update new version logic and remove user id from dmp contacts

This commit is contained in:
amentis 2024-05-28 18:55:35 +03:00
parent c03594f74a
commit d7719d4299
27 changed files with 395 additions and 267 deletions

View File

@ -1,24 +1,14 @@
package org.opencdmp.commons.types.dmp;
import java.util.UUID;
public class DmpContactEntity {
private UUID userId;
private String firstName;
private String lastName;
private String email;
public UUID getUserId() {
return this.userId;
}
public void setUserId(UUID userId) {
this.userId = userId;
}
public String getFirstName() {
return this.firstName;

View File

@ -4,14 +4,10 @@ import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlElement;
import java.util.UUID;
@XmlAccessorType(XmlAccessType.FIELD)
public class DmpContactImportExport {
@XmlElement(name = "userId")
private UUID userId;
@XmlElement(name = "name")
private String name;
@ -24,14 +20,6 @@ public class DmpContactImportExport {
@XmlElement(name = "email")
private String email;
public UUID getUserId() {
return this.userId;
}
public void setUserId(UUID userId) {
this.userId = userId;
}
public String getFirstName() {
return this.firstName;
}

View File

@ -5,16 +5,11 @@ import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.logging.LoggerService;
import org.opencdmp.authorization.AuthorizationFlags;
import org.opencdmp.commonmodels.models.UserModel;
import org.opencdmp.commonmodels.models.dmp.DmpContactModel;
import org.opencdmp.commons.enums.IsActive;
import org.opencdmp.commons.types.dmp.DmpContactEntity;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.data.UserEntity;
import org.opencdmp.model.builder.commonmodels.BaseCommonModelBuilder;
import org.opencdmp.model.builder.commonmodels.CommonModelBuilderItemResponse;
import org.opencdmp.model.builder.commonmodels.UserCommonModelBuilder;
import org.opencdmp.query.UserQuery;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
@ -22,7 +17,6 @@ import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@ -51,29 +45,16 @@ public class DmpContactCommonModelBuilder extends BaseCommonModelBuilder<DmpCont
this.logger.debug("building for {}", Optional.ofNullable(data).map(List::size).orElse(0));
if (data == null || data.isEmpty()) return new ArrayList<>();
Map<UUID, UserModel> userItemsMap = this.collectUsers(data);
List<CommonModelBuilderItemResponse<DmpContactModel, DmpContactEntity>> models = new ArrayList<>();
for (DmpContactEntity d : data) {
DmpContactModel m = new DmpContactModel();
m.setEmail(d.getEmail());
m.setFirstName(d.getFirstName());
m.setLastName(d.getLastName());
if (userItemsMap != null && d.getUserId() != null && userItemsMap.containsKey(d.getUserId())) m.setUser(userItemsMap.get(d.getUserId()));
models.add(new CommonModelBuilderItemResponse<>(m, d));
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
private Map<UUID, UserModel> collectUsers(List<DmpContactEntity> data) throws MyApplicationException {
if (data.isEmpty())
return null;
this.logger.debug("checking related - {}", UserModel.class.getSimpleName());
Map<UUID, UserModel> itemMap;
UserQuery q = this.queryFactory.query(UserQuery.class).disableTracking().isActive(IsActive.Active).authorize(this.authorize).ids(data.stream().filter(x-> x.getUserId() != null).map(DmpContactEntity::getUserId).distinct().collect(Collectors.toList()));
itemMap = this.builderFactory.builder(UserCommonModelBuilder.class).disableContacts(true).authorize(this.authorize).asForeignKey(q, UserEntity::getId);
return itemMap;
}
}

View File

@ -3,19 +3,14 @@ package org.opencdmp.model.builder.dmp;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.fieldset.BaseFieldSet;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.opencdmp.authorization.AuthorizationFlags;
import org.opencdmp.commons.types.dmp.DmpContactEntity;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.model.DmpAssociatedUser;
import org.opencdmp.model.builder.BaseBuilder;
import org.opencdmp.model.builder.DmpAssociatedUserBuilder;
import org.opencdmp.model.dmp.DmpContact;
import org.opencdmp.model.user.User;
import org.opencdmp.query.UserQuery;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
@ -23,7 +18,6 @@ import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
@Component("dmpcontactbuilder")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@ -55,13 +49,10 @@ public class DmpContactBuilder extends BaseBuilder<DmpContact, DmpContactEntity>
return new ArrayList<>();
//Not Bulk Build because is XML no interaction with db
FieldSet userFields = fields.extractPrefixed(this.asPrefix(DmpContact._user));
Map<UUID, DmpAssociatedUser> userItemsMap = this.collectUsers(userFields, data);
List<DmpContact> models = new ArrayList<>();
for (DmpContactEntity d : data) {
DmpContact m = new DmpContact();
if (!userFields.isEmpty() && userItemsMap != null && userItemsMap.containsKey(d.getUserId())) m.setUser(userItemsMap.get(d.getUserId()));
if (fields.hasField(this.asIndexer(DmpContact._email))) m.setEmail(d.getEmail());
if (fields.hasField(this.asIndexer(DmpContact._firstName))) m.setFirstName(d.getFirstName());
if (fields.hasField(this.asIndexer(DmpContact._lastName))) m.setLastName(d.getLastName());
@ -71,33 +62,4 @@ public class DmpContactBuilder extends BaseBuilder<DmpContact, DmpContactEntity>
return models;
}
private Map<UUID, DmpAssociatedUser> collectUsers(FieldSet fields, List<DmpContactEntity> data) throws MyApplicationException {
if (fields.isEmpty() || data.isEmpty())
return null;
this.logger.debug("checking related - {}", User.class.getSimpleName());
Map<UUID, DmpAssociatedUser> itemMap;
if (!fields.hasOtherField(this.asIndexer(DmpAssociatedUser._id))) {
itemMap = this.asEmpty(
data.stream().filter(x-> x.getUserId() != null).map(DmpContactEntity::getUserId).distinct().collect(Collectors.toList()),
x -> {
DmpAssociatedUser item = new DmpAssociatedUser();
item.setId(x);
return item;
},
DmpAssociatedUser::getId);
} else {
FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(User._id);
UserQuery q = this.queryFactory.query(UserQuery.class).authorize(this.authorize).disableTracking().ids(data.stream().filter(x-> x.getUserId() != null).map(DmpContactEntity::getUserId).distinct().collect(Collectors.toList()));
itemMap = this.builderFactory.builder(DmpAssociatedUserBuilder.class).authorize(this.authorize).asForeignKey(q, clone, DmpAssociatedUser::getId);
}
if (!fields.hasField(User._id)) {
itemMap.forEach((id, item) -> {
if (item != null)
item.setId(null);
});
}
return itemMap;
}
}

View File

@ -3,8 +3,6 @@ package org.opencdmp.model.censorship.dmp;
import org.opencdmp.authorization.Permission;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.model.censorship.BaseCensor;
import org.opencdmp.model.censorship.UserCensor;
import org.opencdmp.model.dmp.DmpContact;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.data.censor.CensorFactory;
import gr.cite.tools.fieldset.FieldSet;
@ -39,8 +37,6 @@ public class DmpContactCensor extends BaseCensor {
return;
this.authService.authorizeForce(Permission.BrowseDmp, Permission.DeferredAffiliation);
FieldSet userFields = fields.extractPrefixed(this.asIndexerPrefix(DmpContact._user));
this.censorFactory.censor(UserCensor.class).censor(userFields, userId);
}
}

View File

@ -1,11 +1,8 @@
package org.opencdmp.model.dmp;
import org.opencdmp.model.DmpAssociatedUser;
public class DmpContact {
private DmpAssociatedUser user;
public static final String _user = "user";
private String firstName;
public static final String _firstName = "firstName";
@ -39,11 +36,4 @@ public class DmpContact {
this.email = email;
}
public DmpAssociatedUser getUser() {
return user;
}
public void setUser(DmpAssociatedUser user) {
this.user = user;
}
}

View File

@ -0,0 +1,73 @@
package org.opencdmp.model.persist;
import gr.cite.tools.validation.specification.Specification;
import org.opencdmp.commons.validation.BaseValidator;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.errorcode.ErrorThesaurusProperties;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Scope;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
public class NewVersionDmpDescriptionPersist {
private UUID descriptionId;
public static final String _descriptionId = "descriptionId";
private UUID blueprintSectionId;
public static final String _blueprintSectionId = "blueprintSectionId";
public UUID getDescriptionId() {
return descriptionId;
}
public void setDescriptionId(UUID descriptionId) {
this.descriptionId = descriptionId;
}
public UUID getBlueprintSectionId() {
return blueprintSectionId;
}
public void setBlueprintSectionId(UUID blueprintSectionId) {
this.blueprintSectionId = blueprintSectionId;
}
@Component(NewVersionDmpDescriptionPersist.NewVersionDmpDescriptionPersistValidator.ValidatorName)
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public static class NewVersionDmpDescriptionPersistValidator extends BaseValidator<NewVersionDmpDescriptionPersist> {
public static final String ValidatorName = "NewVersionDmpDescriptionPersistValidator";
private final MessageSource messageSource;
protected NewVersionDmpDescriptionPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) {
super(conventionService, errors);
this.messageSource = messageSource;
}
@Override
protected Class<NewVersionDmpDescriptionPersist> modelClass() {
return NewVersionDmpDescriptionPersist.class;
}
@Override
protected List<Specification> specifications(NewVersionDmpDescriptionPersist item) {
return Arrays.asList(
this.spec()
.must(() -> this.isValidGuid(item.getDescriptionId()))
.failOn(NewVersionDmpDescriptionPersist._descriptionId).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpDescriptionPersist._descriptionId}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> this.isValidGuid(item.getBlueprintSectionId()))
.failOn(NewVersionDmpDescriptionPersist._blueprintSectionId).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpDescriptionPersist._blueprintSectionId}, LocaleContextHolder.getLocale()))
);
}
}
}

View File

@ -1,5 +1,6 @@
package org.opencdmp.model.persist;
import gr.cite.tools.validation.ValidatorFactory;
import gr.cite.tools.validation.specification.Specification;
import org.opencdmp.commons.validation.BaseValidator;
import org.opencdmp.convention.ConventionService;
@ -11,7 +12,6 @@ import org.springframework.context.annotation.Scope;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
@ -33,7 +33,7 @@ public class NewVersionDmpPersist {
public static final String _blueprintId = "blueprintId";
private List<UUID> descriptions = new ArrayList<>();
private List<NewVersionDmpDescriptionPersist> descriptions;
public static final String _descriptions = "descriptions";
@ -73,11 +73,11 @@ public class NewVersionDmpPersist {
this.blueprintId = blueprintId;
}
public List<UUID> getDescriptions() {
return this.descriptions;
public List<NewVersionDmpDescriptionPersist> getDescriptions() {
return descriptions;
}
public void setDescriptions(List<UUID> descriptions) {
public void setDescriptions(List<NewVersionDmpDescriptionPersist> descriptions) {
this.descriptions = descriptions;
}
@ -96,10 +96,12 @@ public class NewVersionDmpPersist {
public static final String ValidatorName = "NewVersionDmpPersistValidator";
private final MessageSource messageSource;
private final ValidatorFactory validatorFactory;
protected NewVersionDmpPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) {
protected NewVersionDmpPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) {
super(conventionService, errors);
this.messageSource = messageSource;
this.validatorFactory = validatorFactory;
}
@Override
@ -127,9 +129,11 @@ public class NewVersionDmpPersist {
this.spec()
.must(() -> this.isValidGuid(item.getBlueprintId()))
.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(this.messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpPersist._descriptions}, LocaleContextHolder.getLocale()))
this.navSpec()
.iff(() -> !this.isListNullOrEmpty(item.getDescriptions()))
.on(NewVersionDmpPersist._descriptions)
.over(item.getDescriptions())
.using((itm) -> this.validatorFactory.validator(NewVersionDmpDescriptionPersist.NewVersionDmpDescriptionPersistValidator.class))
);
}
}

View File

@ -12,13 +12,9 @@ import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
public class DmpContactPersist {
private UUID userId;
public static final String _userId = "userId";
private String firstName;
public static final String _firstName = "firstName";
@ -28,14 +24,6 @@ public class DmpContactPersist {
private String email;
public static final String _email = "email";
public UUID getUserId() {
return userId;
}
public void setUserId(UUID userId) {
this.userId = userId;
}
public String getFirstName() {
return firstName;
}
@ -81,19 +69,12 @@ public class DmpContactPersist {
protected List<Specification> specifications(DmpContactPersist item) {
return Arrays.asList(
this.spec()
.iff(() -> this.isEmpty(item.getEmail()) && this.isEmpty(item.getFirstName()) && this.isEmpty(item.getLastName()))
.must(() -> !this.isNull(item.getUserId()))
.failOn(DmpContactPersist._userId).failWith(messageSource.getMessage("Validation_Required", new Object[]{"user"}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> this.isNull(item.getUserId()))
.must(() -> !this.isEmpty(item.getEmail()))
.failOn(DmpContactPersist._email).failWith(messageSource.getMessage("Validation_Required", new Object[]{DmpContactPersist._email}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> this.isNull(item.getUserId()))
.must(() -> !this.isEmpty(item.getFirstName()))
.failOn(DmpContactPersist._firstName).failWith(messageSource.getMessage("Validation_Required", new Object[]{DmpContactPersist._firstName}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> this.isNull(item.getUserId()))
.must(() -> !this.isEmpty(item.getLastName()))
.failOn(DmpContactPersist._lastName).failWith(messageSource.getMessage("Validation_Required", new Object[]{DmpContactPersist._lastName}, LocaleContextHolder.getLocale()))
);

View File

@ -1280,6 +1280,8 @@ public class DescriptionServiceImpl implements DescriptionService {
if (descriptionXml == null) throw new MyNotFoundException("Description xml not found");
if (this.conventionService.isListNullOrEmpty(dmpDescriptionTemplates)) throw new MyApplicationException("Error creating description without dmp description template");
logger.debug(new MapLogEntry("import description").And("dmpId", dmpId).And("fields", fields));
DescriptionPersist persist = new DescriptionPersist();

View File

@ -70,8 +70,11 @@ import org.opencdmp.model.DmpUser;
import org.opencdmp.model.DmpValidationResult;
import org.opencdmp.model.UserContactInfo;
import org.opencdmp.model.builder.DmpUserBuilder;
import org.opencdmp.model.builder.description.DescriptionBuilder;
import org.opencdmp.model.builder.dmp.DmpBuilder;
import org.opencdmp.model.deleter.*;
import org.opencdmp.model.description.Description;
import org.opencdmp.model.descriptiontemplate.DescriptionTemplate;
import org.opencdmp.model.dmp.Dmp;
import org.opencdmp.model.dmpblueprint.DmpBlueprint;
import org.opencdmp.model.dmpreference.DmpReferenceData;
@ -481,8 +484,35 @@ public class DmpServiceImpl implements DmpService {
this.entityManager.flush();
for (UUID descriptionId : model.getDescriptions()) {
this.cloneDescription(newDmp.getId(), dmpDescriptionTemplateRemap, descriptionId);
if (model.getDescriptions() != null){
List<DmpDescriptionTemplateEntity> dmpDescriptionTemplateEntities = this.queryFactory.query(DmpDescriptionTemplateQuery.class).disableTracking().dmpIds(newDmp.getId()).isActive(IsActive.Active).collect();
List<DescriptionEntity> descriptionEntities = this.queryFactory.query(DescriptionQuery.class).disableTracking().ids(model.getDescriptions().stream().map(NewVersionDmpDescriptionPersist::getDescriptionId).distinct().collect(Collectors.toList())).isActive(IsActive.Active).collect();
FieldSet fieldSet = new BaseFieldSet(Description._id, BaseFieldSet.asIndexer(Description._descriptionTemplate, DescriptionTemplate._groupId));
List<Description> models = this.builderFactory.builder(DescriptionBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(fieldSet, descriptionEntities);
if (!this.conventionService.isListNullOrEmpty(dmpDescriptionTemplateEntities) && !this.conventionService.isListNullOrEmpty(models)){
for (NewVersionDmpDescriptionPersist newVersionDmpDescriptionPersist : model.getDescriptions()) {
Description description = models.stream().filter(x -> x.getId().equals(newVersionDmpDescriptionPersist.getDescriptionId())).findFirst().orElse(null);
if (description != null){
DmpDescriptionTemplateEntity existingDmpDescriptionTemplateEntity = dmpDescriptionTemplateEntities.stream().filter(x -> x.getSectionId().equals(newVersionDmpDescriptionPersist.getBlueprintSectionId()) && x.getDescriptionTemplateGroupId().equals(description.getDescriptionTemplate().getGroupId())).findFirst().orElse(null);
if (existingDmpDescriptionTemplateEntity == null){
DmpDescriptionTemplateEntity newTemplate = new DmpDescriptionTemplateEntity();
newTemplate.setId(UUID.randomUUID());
newTemplate.setDmpId(newDmp.getId());
newTemplate.setDescriptionTemplateGroupId(description.getDescriptionTemplate().getGroupId());
newTemplate.setSectionId(newVersionDmpDescriptionPersist.getBlueprintSectionId());
newTemplate.setCreatedAt(Instant.now());
newTemplate.setUpdatedAt(Instant.now());
newTemplate.setIsActive(IsActive.Active);
this.entityManager.persist(newTemplate);
this.entityManager.flush();
this.cloneDescription(newDmp.getId(), dmpDescriptionTemplateRemap, newVersionDmpDescriptionPersist.getDescriptionId(), newTemplate.getId());
} else{
this.cloneDescription(newDmp.getId(), dmpDescriptionTemplateRemap, newVersionDmpDescriptionPersist.getDescriptionId(), null);
}
}
}
}
}
this.entityManager.flush();
@ -500,7 +530,7 @@ public class DmpServiceImpl implements DmpService {
return this.builderFactory.builder(DmpBuilder.class).build(BaseFieldSet.build(fields, Dmp._id), newDmp);
}
public void cloneDescription(UUID dmpId, Map<UUID, UUID> dmpDescriptionTemplateRemap, UUID descriptionId) throws InvalidApplicationException, IOException {
public void cloneDescription(UUID dmpId, Map<UUID, UUID> dmpDescriptionTemplateRemap, UUID descriptionId, UUID newDmpDescriptionTemplateId) throws InvalidApplicationException, IOException {
logger.debug("cloning description: {} with description: {}", descriptionId, dmpId);
this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.descriptionAffiliation(descriptionId)), Permission.CloneDescription);
@ -514,7 +544,8 @@ public class DmpServiceImpl implements DmpService {
newDescription.setStatus(DescriptionStatus.Draft);
newDescription.setProperties(existing.getProperties());
newDescription.setDmpId(dmpId);
newDescription.setDmpDescriptionTemplateId(dmpDescriptionTemplateRemap.get(existing.getDmpDescriptionTemplateId()));
if (newDmpDescriptionTemplateId == null) newDescription.setDmpDescriptionTemplateId(dmpDescriptionTemplateRemap.get(existing.getDmpDescriptionTemplateId()));
else newDescription.setDmpDescriptionTemplateId(newDmpDescriptionTemplateId);
newDescription.setDescriptionTemplateId(existing.getDescriptionTemplateId());
newDescription.setCreatedById(this.userScope.getUserId());
newDescription.setCreatedAt(Instant.now());
@ -695,7 +726,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.cloneDescription(newDmp.getId(), dmpDescriptionTemplateRemap, description);
this.cloneDescription(newDmp.getId(), dmpDescriptionTemplateRemap, description, null);
}
}
return this.builderFactory.builder(DmpBuilder.class).build(fields, resultingDmpEntity);
@ -862,7 +893,6 @@ public class DmpServiceImpl implements DmpService {
data.setEmail(persist.getEmail());
data.setLastName(persist.getLastName());
data.setFirstName(persist.getFirstName());
data.setUserId(persist.getUserId());
return data;
}
@ -1282,7 +1312,6 @@ public class DmpServiceImpl implements DmpService {
persist.setEmail(data.getEmail());
persist.setLastName(data.getLastName());
persist.setFirstName(data.getFirstName());
persist.setUserId(data.getUserId());
return persist;
}
@ -1528,10 +1557,8 @@ public class DmpServiceImpl implements DmpService {
if (propertiesEntity != null && !this.conventionService.isListNullOrEmpty(propertiesEntity.getContacts())) {
List<DmpContactImportExport> dmpContactImportExports = new LinkedList<>();
List<UserEntity> users = this.queryFactory.query(UserQuery.class).disableTracking().ids(propertiesEntity.getContacts().stream().map(DmpContactEntity::getUserId).filter(Objects::nonNull).distinct().toList()).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).isActive(IsActive.Active).collect();
Map<UUID, UserEntity> usersMap = users == null ? new HashMap<>() : users.stream().collect(Collectors.toMap(UserEntity::getId, x-> x));
for (DmpContactEntity contactEntity : propertiesEntity.getContacts()) {
dmpContactImportExports.add(this.dmpContactToExport(contactEntity, usersMap));
dmpContactImportExports.add(this.dmpContactToExport(contactEntity));
}
xml.setContacts(dmpContactImportExports);
}
@ -1668,15 +1695,10 @@ public class DmpServiceImpl implements DmpService {
return xml;
}
private DmpContactImportExport dmpContactToExport(DmpContactEntity entity, Map<UUID, UserEntity> usersMap) {
private DmpContactImportExport dmpContactToExport(DmpContactEntity entity) {
DmpContactImportExport xml = new DmpContactImportExport();
if (entity == null) return xml;
UserEntity userEntity = entity.getUserId() == null ? null : usersMap.getOrDefault(entity.getUserId(), null);
if (userEntity != null){
xml.setName(userEntity.getName());
}
xml.setUserId(entity.getUserId());
xml.setEmail(entity.getEmail());
xml.setFirstName(entity.getFirstName());
xml.setLastName(entity.getLastName());
@ -1756,10 +1778,8 @@ public class DmpServiceImpl implements DmpService {
List<DmpContactPersist> contacts = new ArrayList<>();
if (!this.conventionService.isListNullOrEmpty(importXml.getContacts())) {
List<UserEntity> users = this.queryFactory.query(UserQuery.class).disableTracking().ids(importXml.getContacts().stream().map(DmpContactImportExport::getUserId).filter(Objects::nonNull).distinct().toList()).isActive(IsActive.Active).collect();
List<UUID> usersIds = users == null ? new ArrayList<>() : users.stream().map(x -> x.getId()).collect(Collectors.toList());
for (DmpContactImportExport contact : importXml.getContacts()) {
contacts.add(this.xmlDmpContactToPersist(contact, usersIds));
contacts.add(this.xmlDmpContactToPersist(contact));
}
}
@ -1877,19 +1897,15 @@ public class DmpServiceImpl implements DmpService {
return null;
}
private DmpContactPersist xmlDmpContactToPersist(DmpContactImportExport importXml, List<UUID> userIds) {
private DmpContactPersist xmlDmpContactToPersist(DmpContactImportExport importXml) {
if (importXml == null)
return null;
DmpContactPersist persist = new DmpContactPersist();
if (importXml.getUserId() != null && !userIds.isEmpty() && userIds.contains(importXml.getUserId())){
persist.setUserId(importXml.getUserId());
} else {
persist.setEmail(importXml.getEmail());
persist.setFirstName(importXml.getEmail());
persist.setLastName(importXml.getLastName());
}
return persist;
}
@ -1969,10 +1985,8 @@ public class DmpServiceImpl implements DmpService {
List<DmpContactPersist> contacts = new ArrayList<>();
if (model.getProperties() != null && !this.conventionService.isListNullOrEmpty(model.getProperties().getContacts())) {
List<UserEntity> users = this.queryFactory.query(UserQuery.class).disableTracking().ids(model.getProperties().getContacts().stream().map(x -> x.getUser()).collect(Collectors.toList()).stream().map(UserModel::getId).filter(Objects::nonNull).distinct().toList()).isActive(IsActive.Active).collect();
List<UUID> usersIds = users == null ? new ArrayList<>() : users.stream().map(x -> x.getId()).collect(Collectors.toList());
for (DmpContactModel contact : model.getProperties().getContacts()) {
contacts.add(this.commonDmpContactToPersist(contact, usersIds));
contacts.add(this.commonDmpContactToPersist(contact));
}
}
@ -2106,19 +2120,15 @@ public class DmpServiceImpl implements DmpService {
return null;
}
private DmpContactPersist commonDmpContactToPersist(DmpContactModel model, List<UUID> userIds) {
private DmpContactPersist commonDmpContactToPersist(DmpContactModel model) {
if (model == null)
return null;
DmpContactPersist persist = new DmpContactPersist();
if (model.getUser() != null && model.getUser().getId() != null && !userIds.isEmpty() && userIds.contains(model.getUser().getId())){
persist.setUserId(model.getUser().getId());
} else {
persist.setEmail(model.getEmail());
persist.setFirstName(model.getEmail());
persist.setLastName(model.getLastName());
}
return persist;
}

View File

@ -1,4 +0,0 @@
export enum DmpContactType {
Internal = 0,
External = 1
}

View File

@ -52,7 +52,6 @@ export interface DmpBlueprintValue {
}
export interface DmpContact {
user?: DmpAssociatedUser;
firstName: string;
lastName: string;
email: string;
@ -104,7 +103,6 @@ export interface DmpBlueprintValuePersist {
}
export interface DmpContactPersist {
userId: Guid;
firstName: string;
lastName: string;
email: string;
@ -136,10 +134,15 @@ export interface NewVersionDmpPersist {
label: string;
description: String;
blueprintId: Guid;
descriptions: Guid[];
descriptions: NewVersionDmpDescriptionPersist[];
hash?: string;
}
export interface NewVersionDmpDescriptionPersist {
descriptionId: Guid;
blueprintSectionId: Guid;
}
export interface DmpUserPersist {
user: Guid;
role: DmpUserRole;

View File

@ -8,7 +8,6 @@ import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description
import { DmpAccessType } from '@app/core/common/enum/dmp-access-type';
import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
import { DmpContactType } from '@app/core/common/enum/dmp-contact-type';
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
@ -252,13 +251,6 @@ export class EnumUtils {
}
}
public toDmpContactTypeString(value: DmpContactType): string {
switch (value) {
case DmpContactType.Internal: return this.language.instant('TYPES.DMP-CONTACT-TYPE.INTERNAL');
case DmpContactType.External: return this.language.instant('TYPES.DMP-CONTACT-TYPE.EXTERNAL');
}
}
public toDmpUserTypeString(value: DmpUserType): string {
switch (value) {
case DmpUserType.Internal: return this.language.instant('TYPES.DMP-USER-TYPE.INTERNAL');

View File

@ -6,7 +6,7 @@ import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order
import { RecentActivityItem } from '@app/core/model/dashboard/recent-activity-item';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description } from '@app/core/model/description/description';
import { Dmp, DmpUser } from "@app/core/model/dmp/dmp";
import { Dmp, DmpDescriptionTemplate, DmpUser } from "@app/core/model/dmp/dmp";
import { DmpReference } from '@app/core/model/dmp/dmp-reference';
import { Reference } from '@app/core/model/reference/reference';
import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-lookup.lookup';
@ -22,7 +22,7 @@ import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
@Component({
@ -160,6 +160,7 @@ export class DraftsComponent extends BaseComponent implements OnInit {
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
@ -169,6 +170,10 @@ export class DraftsComponent extends BaseComponent implements OnInit {
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.label)].join('.'),

View File

@ -10,8 +10,8 @@ import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order
import { RecentActivityItem } from '@app/core/model/dashboard/recent-activity-item';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description } from '@app/core/model/description/description';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpUser } from '@app/core/model/dmp/dmp';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpDescriptionTemplate, 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';
@ -267,6 +267,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
@ -276,6 +277,10 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
];
}

View File

@ -8,9 +8,10 @@ import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { RecentActivityItem } from '@app/core/model/dashboard/recent-activity-item';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description } from '@app/core/model/description/description';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpUser } from '@app/core/model/dmp/dmp';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpDescriptionTemplate, 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';
@ -164,6 +165,7 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
@ -173,6 +175,10 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
]
};

View File

@ -194,24 +194,8 @@
<span *ngIf="!isContactSelected(contactIndex)" style="font-size: 18px; box-sizing: border-box; display: inline-block; padding: 0.15rem 0.435rem 0.3rem 0.435rem;">{{contactIndex + 1}}</span>
<mat-icon *ngIf="isContactSelected(contactIndex)" [ngClass]="{'drag-handle-disabled': formGroup.disabled || !canEdit}" cdkDragHandle class="drag-handle">drag_indicator</mat-icon>
</div>
<div class="col-12 col-xl-auto">
<mat-button-toggle-group name="fontStyle" aria-label="Font Style" [formControl]="contact.get('contactType')">
<div *ngFor="let contactType of dmpContactTypeEnumValues">
<mat-button-toggle class="lang-button" [value]="contactType">{{enumUtils.toDmpContactTypeString(contactType)}}</mat-button-toggle>
</div>
</mat-button-toggle-group>
</div>
<div class="col pt-3">
<div class="row">
<div class="col d-flex" *ngIf="contact.get('contactType').value == dmpContactTypeEnum.Internal">
<mat-form-field class="w-100">
<mat-label>{{'DMP-EDITOR.FIELDS.USER' | translate}}</mat-label>
<app-single-auto-complete [formControl]="contact.get('userId')" [configuration]="userService.singleAutoCompleteDmpAssociatedUserConfiguration"></app-single-auto-complete>
<mat-error *ngIf="contact.get('userId').hasError('backendError')">{{contact.get('userId').getError('backendError').message}}</mat-error>
<mat-error *ngIf="contact.get('userId').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<ng-container *ngIf="contact.get('contactType').value == dmpContactTypeEnum.External">
<div class="col">
<mat-form-field class="w-100">
<mat-label>{{'DMP-EDITOR.FIELDS.FIRST-NAME' | translate}}</mat-label>
@ -236,7 +220,6 @@
<mat-error *ngIf="contact.get('email').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</ng-container>
</div>
</div>
<div *ngIf="canSave || isNew" class="col-12 col-xl-auto">

View File

@ -10,7 +10,6 @@ import { DmpBlueprintFieldCategory } from '@app/core/common/enum/dmp-blueprint-f
import { DmpBlueprintExtraFieldDataType } from '@app/core/common/enum/dmp-blueprint-field-type';
import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
import { DmpContactType } from '@app/core/common/enum/dmp-contact-type';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
import { DmpUserType } from '@app/core/common/enum/dmp-user-type';
@ -75,8 +74,6 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
dmpBlueprintExtraFieldDataTypeEnum = DmpBlueprintExtraFieldDataType;
dmpAccessTypeEnum = DmpAccessType;
dmpAccessTypeEnumValues = this.enumUtils.getEnumValues<DmpAccessType>(DmpAccessType);
dmpContactTypeEnum = DmpContactType;
dmpContactTypeEnumValues = this.enumUtils.getEnumValues<DmpContactType>(DmpContactType);
dmpUserTypeEnum = DmpUserType;
dmpUserTypeEnumValues = this.enumUtils.getEnumValues<DmpUserType>(DmpUserType);
dmpUserRoleEnumValues = this.enumUtils.getEnumValues<DmpUserRole>(DmpUserRole);

View File

@ -2,7 +2,6 @@ import { FormArray, FormControl, UntypedFormBuilder, UntypedFormGroup, Validator
import { DmpAccessType } from "@app/core/common/enum/dmp-access-type";
import { DmpBlueprintFieldCategory } from "@app/core/common/enum/dmp-blueprint-field-category";
import { DmpBlueprintSystemFieldType } from "@app/core/common/enum/dmp-blueprint-system-field-type";
import { DmpContactType } from "@app/core/common/enum/dmp-contact-type";
import { DmpStatus } from "@app/core/common/enum/dmp-status";
import { DmpUserRole } from "@app/core/common/enum/dmp-user-role";
import { DmpUserType } from "@app/core/common/enum/dmp-user-type";
@ -450,11 +449,9 @@ export class DmpBlueprintValueEditorModel implements DmpBlueprintValuePersist {
}
export class DmpContactEditorModel implements DmpContactPersist {
userId: Guid;
firstName: string;
lastName: string;
email: string;
contactType: DmpContactType = DmpContactType.Internal;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
@ -463,11 +460,9 @@ export class DmpContactEditorModel implements DmpContactPersist {
) { }
fromModel(item: DmpContact): DmpContactEditorModel {
if (item?.user?.id) this.userId = item.user.id;
this.firstName = item.firstName;
this.lastName = item.lastName;
this.email = item.email;
this.contactType = (item == null || this.userId != null) ? DmpContactType.Internal : DmpContactType.External;
return this;
}
@ -486,11 +481,9 @@ export class DmpContactEditorModel implements DmpContactPersist {
}
return this.formBuilder.group({
userId: [{ value: this.userId, disabled: disabled }, context.getValidation('userId').validators],
firstName: [{ value: this.firstName, disabled: disabled }, context.getValidation('firstName').validators],
lastName: [{ value: this.lastName, disabled: disabled }, context.getValidation('lastName').validators],
email: [{ value: this.email, disabled: disabled }, context.getValidation('email').validators],
contactType: [{ value: this.contactType, disabled: disabled }, context.getValidation('contactType').validators],
});
}
@ -502,11 +495,9 @@ export class DmpContactEditorModel implements DmpContactPersist {
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'userId', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}userId`)] });
baseValidationArray.push({ key: 'firstName', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}firstName`)] });
baseValidationArray.push({ key: 'lastName', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}lastName`)] });
baseValidationArray.push({ key: 'email', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}email`)] });
baseValidationArray.push({ key: 'contactType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}contactType`)] });
baseValidationArray.push({ key: 'firstName', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}firstName`)] });
baseValidationArray.push({ key: 'lastName', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}lastName`)] });
baseValidationArray.push({ key: 'email', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}email`)] });
baseContext.validation = baseValidationArray;
return baseContext;
@ -524,7 +515,7 @@ export class DmpContactEditorModel implements DmpContactPersist {
validationErrorModel
});
['userId', 'firstName', 'lastName', 'email'].forEach(keyField => {
['firstName', 'lastName', 'email'].forEach(keyField => {
const control = formGroup?.get(keyField);
control?.clearValidators();
control?.addValidators(context.getValidation(keyField).validators);

View File

@ -8,7 +8,6 @@ import { DmpReference, DmpReferenceData } from '@app/core/model/dmp/dmp-referenc
import { ExternalFetcherBaseSourceConfiguration } from '@app/core/model/external-fetcher/external-fetcher';
import { ReferenceType, ReferenceTypeDefinition } from '@app/core/model/reference-type/reference-type';
import { Reference } from '@app/core/model/reference/reference';
import { DmpAssociatedUser, User } from '@app/core/model/user/user';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
import { BaseEditorResolver } from '@common/base/base-editor.resolver';
@ -49,7 +48,6 @@ export class DmpEditorResolver extends BaseEditorResolver {
[nameof<Dmp>(x => x.properties), nameof<DmpProperties>(x => x.dmpBlueprintValues), nameof<DmpBlueprintValue>(x => x.fieldValue)].join('.'),
[nameof<Dmp>(x => x.properties), nameof<DmpProperties>(x => x.dmpBlueprintValues), nameof<DmpBlueprintValue>(x => x.dateValue)].join('.'),
[nameof<Dmp>(x => x.properties), nameof<DmpProperties>(x => x.dmpBlueprintValues), nameof<DmpBlueprintValue>(x => x.numberValue)].join('.'),
[nameof<Dmp>(x => x.properties), nameof<DmpProperties>(x => x.contacts), nameof<DmpContact>(x => x.user), nameof<DmpAssociatedUser>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.properties), nameof<DmpProperties>(x => x.contacts), nameof<DmpContact>(x => x.firstName)].join('.'),
[nameof<Dmp>(x => x.properties), nameof<DmpProperties>(x => x.contacts), nameof<DmpContact>(x => x.lastName)].join('.'),
[nameof<Dmp>(x => x.properties), nameof<DmpProperties>(x => x.contacts), nameof<DmpContact>(x => x.email)].join('.'),

View File

@ -17,8 +17,8 @@ import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service'
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { Description } from '@app/core/model/description/description';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpUser } from '@app/core/model/dmp/dmp';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpDescriptionTemplate, DmpUser } from '@app/core/model/dmp/dmp';
import { DmpLookup } from '@app/core/query/dmp.lookup';
import { BaseComponent } from '@common/base/base.component';
import { Guid } from '@common/types/guid';
@ -35,6 +35,7 @@ import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { SortDirection } from '@common/modules/hybrid-listing/hybrid-listing.component';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
@Component({
selector: 'app-dmp-listing-component',
@ -223,6 +224,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.label)].join('.'),
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.status)].join('.'),
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.isActive)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),
@ -230,6 +232,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
// [nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
// [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
@ -246,6 +249,11 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.isActive)].join('.'),
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
// [nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.reference)].join('.'),
]
};

View File

@ -34,7 +34,7 @@
</div>
<div class="col-12 title-form">
<mat-form-field class="w-100">
<app-single-auto-complete [required]="false" [formControl]="formGroup.get('blueprintId')" placeholder="{{'DMP-NEW-VERSION-DIALOG.FIELDS.BLUEPRINT-PLACEHOLDER' | translate}}" [configuration]="singleAutocompleteBlueprintConfiguration">
<app-single-auto-complete [required]="false" [formControl]="formGroup.get('blueprintId')" placeholder="{{'DMP-NEW-VERSION-DIALOG.FIELDS.BLUEPRINT-PLACEHOLDER' | translate}}" [configuration]="singleAutocompleteBlueprintConfiguration" (optionSelected)="selectedBlueprintChanged($event)">
</app-single-auto-complete>
</mat-form-field>
</div>
@ -48,12 +48,19 @@
</div>
<div class="col-12" *ngIf="hasDescriptions()">
<mat-card class="mat-card">
<mat-card-header>
<!-- <mat-card-header>
<mat-checkbox [checked]="allDescriptionsCompleted" [indeterminate]="someDescriptionsCompleted" (change)="toggleAllDescriptions($event.checked)">{{ 'DMP-NEW-VERSION-DIALOG.ACTIONS.TOGGLE-DESCRIPTIONS' | translate }}</mat-checkbox>
</mat-card-header>
<mat-selection-list #selectedItems [formControl]="formGroup.get('descriptions')">
<mat-list-option *ngFor="let description of dmp.descriptions;" [value]="description.id">
</mat-card-header> -->
<mat-selection-list #selectedItems (selectionChange)="descriptionSelectionChanged($event)">
<mat-list-option *ngFor="let description of dmp.descriptions;" [value]="description.id" [selected]="isDefaultSelected(formGroup.get('descriptions'), description.id)">
<span class="text-truncate" [matTooltip]="description.label">{{description.label}}</span>
<div>
<mat-select [formControl]="getDescriptionSectionFormControl(formGroup.get('descriptions'), description.id)" placeholder="{{'DMP-NEW-VERSION-DIALOG.FIELDS.SELECT-BLUEPRINT-SECTION'| translate}}">
<mat-option *ngFor="let section of selectedBlueprintSections" [value]="section.id">
{{ section.label }}
</mat-option>
</mat-select>
</div>
</mat-list-option>
</mat-selection-list>
</mat-card>

View File

@ -1,7 +1,7 @@
import { Component, Inject } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { FormArray, UntypedFormGroup } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Dmp, NewVersionDmpPersist } from '@app/core/model/dmp/dmp';
import { Dmp, NewVersionDmpDescriptionPersist, NewVersionDmpPersist } from '@app/core/model/dmp/dmp';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { BaseComponent } from '@common/base/base.component';
@ -11,8 +11,16 @@ import { DmpNewVersionDialogEditorModel } from './dmp-new-version-dialog.editor.
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { DmpBlueprint } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status';
import { DmpBlueprintLookup } from '@app/core/query/dmp-blueprint.lookup';
import { IsActive } from '@notification-service/core/enum/is-active.enum';
import { nameof } from 'ts-simple-nameof';
import { DmpBlueprintVersionStatus } from '@app/core/common/enum/dmp-blueprint-version-status';
import { FilterService } from '@common/modules/text-filter/filter-service';
import { Guid } from '@common/types/guid';
import { FormService } from '@common/forms/form-service';
import { MatSelectionListChange } from '@angular/material/list';
@Component({
selector: 'app-dmp-new-version-dialog',
@ -24,27 +32,55 @@ export class NewVersionDmpDialogComponent extends BaseComponent {
dmp: Dmp;
editorModel: DmpNewVersionDialogEditorModel;
formGroup: UntypedFormGroup;
selectedBlueprintSections: DmpBlueprintDefinitionSection[];
singleAutocompleteBlueprintConfiguration: SingleAutoCompleteConfiguration = {
initialItems: (data?: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(null, null, null, [DmpBlueprintStatus.Finalized])).pipe(map(x => x.items)),
filterFn: (searchQuery: string, data?: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(searchQuery, null, null, [DmpBlueprintStatus.Finalized])).pipe(map(x => x.items)),
getSelectedItem: (selectedItem: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
initialItems: (data?: any) => this.dmpBlueprintService.query(this.buildAutocompleteLookup(null, null, null, [DmpBlueprintStatus.Finalized])).pipe(map(x => x.items)),
filterFn: (searchQuery: string, data?: any) => this.dmpBlueprintService.query(this.buildAutocompleteLookup(searchQuery, null, null, [DmpBlueprintStatus.Finalized])).pipe(map(x => x.items)),
getSelectedItem: (selectedItem: any) => this.dmpBlueprintService.query(this.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
displayFn: (item: DmpBlueprint) => item.label,
subtitleFn: (item: DmpBlueprint) => this.language.instant('DMP-EDITOR.FIELDS.DMP-BLUEPRINT-VERSION') + ' '+ item.version,
titleFn: (item: DmpBlueprint) => item.label,
valueAssign: (item: DmpBlueprint) => item.id,
};
public buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[], statuses?: DmpBlueprintStatus[]): DmpBlueprintLookup {
const lookup: DmpBlueprintLookup = new DmpBlueprintLookup();
lookup.page = { size: 100, offset: 0 };
if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; }
if (ids && ids.length > 0) { lookup.ids = ids; }
lookup.isActive = [IsActive.Active];
lookup.statuses = statuses;
lookup.project = {
fields: [
nameof<DmpBlueprint>(x => x.id),
nameof<DmpBlueprint>(x => x.label),
nameof<DmpBlueprint>(x => x.version),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
]
};
lookup.order = { items: [nameof<DmpBlueprint>(x => x.label)] };
lookup.versionStatuses = [DmpBlueprintVersionStatus.Previous, DmpBlueprintVersionStatus.Current];
if (like) { lookup.like = this.filterService.transformLike(like); }
return lookup;
}
constructor(
public dialogRef: MatDialogRef<NewVersionDmpDialogComponent>,
private dmpService: DmpService,
public dmpBlueprintService: DmpBlueprintService,
private uiNotificationService: UiNotificationService,
private language: TranslateService,
private filterService: FilterService,
private formService: FormService,
@Inject(MAT_DIALOG_DATA) public data: any
) {
super();
this.dmp = data.dmp;
this.dmp.dmpDescriptionTemplates = this.dmp.dmpDescriptionTemplates?.filter(x => x.isActive === IsActive.Active);
}
get allDescriptionsNo(): number{
@ -65,10 +101,48 @@ export class NewVersionDmpDialogComponent extends BaseComponent {
ngOnInit() {
this.editorModel = new DmpNewVersionDialogEditorModel().fromModel(this.data.dmp);
this.selectedBlueprintSections = this.dmp.blueprint?.definition?.sections?.filter(x => x.hasTemplates) || null;
this.editorModel = new DmpNewVersionDialogEditorModel().fromModel(this.dmp, this.dmp.blueprint);
this.formGroup = this.editorModel.buildForm();
}
selectedBlueprintChanged(item: DmpBlueprint): void{
this.selectedBlueprintSections = item.definition?.sections?.filter(x => x.hasTemplates) || null;
if(this.selectedBlueprintSections && this.hasDescriptions()) {
this.formGroup = this.editorModel.fromModel(this.dmp, item).buildForm();
}
}
descriptionSelectionChanged(event: MatSelectionListChange) {
const descriptionsFormArray = this.formGroup.get('descriptions') as FormArray;
const descriptionIds = (this.formGroup.get('descriptions').value as NewVersionDmpDescriptionPersist[]).filter(y => y.blueprintSectionId != undefined).map( x => x.descriptionId);
if (event.source._value.length > 0 && descriptionIds.length > 0){
if (event.source._value.length < descriptionIds.length){
const mustDeleteDescription = descriptionIds.filter( id => event.source._value.indexOf(id.toString()) < 0) || []
if (mustDeleteDescription.length > 0){
mustDeleteDescription.forEach(x => this.removeSelectedDescription(descriptionsFormArray, x));
}
}
} else {
if (descriptionIds?.length > 0){
descriptionIds.forEach(x => this.removeSelectedDescription(descriptionsFormArray, x))
}
}
}
removeSelectedDescription(descriptionFormArray: FormArray, descriptionId: Guid){
this.getDescriptionSectionFormControl(descriptionFormArray, descriptionId).patchValue(null);
}
getDescriptionSectionFormControl(descriptionFormArray: FormArray, descriptionId: Guid) {
const index = descriptionFormArray.controls.findIndex(x => x.get('descriptionId')?.value == descriptionId);
return descriptionFormArray.at(index).get('blueprintSectionId');
}
isDefaultSelected(descriptionFormArray: FormArray, descriptionId: Guid): boolean{
return this.getDescriptionSectionFormControl(descriptionFormArray, descriptionId).value != null;
}
hasDescriptions() {
return this.dmp.descriptions?.length > 0;
}
@ -83,8 +157,11 @@ export class NewVersionDmpDialogComponent extends BaseComponent {
confirm() {
if (!this.formGroup.valid) { return; }
const value: NewVersionDmpPersist = this.formGroup.value;
this.dmpService.newVersion(value, DmpEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
const formData = this.formService.getValue(this.formGroup.value) as NewVersionDmpPersist;
if (formData.descriptions.length > 0){
formData.descriptions = formData.descriptions.filter(x => x.blueprintSectionId != null)
}
this.dmpService.newVersion(formData, DmpEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
dmp => this.dialogRef.close(dmp),
error => this.onCallbackError(error)
);

View File

@ -1,5 +1,6 @@
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
import { Dmp, NewVersionDmpPersist } from "@app/core/model/dmp/dmp";
import { DmpBlueprint } from "@app/core/model/dmp-blueprint/dmp-blueprint";
import { Dmp, NewVersionDmpDescriptionPersist, NewVersionDmpPersist } from "@app/core/model/dmp/dmp";
import { BackendErrorValidator } from '@common/forms/validation/custom-validator';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { Validation, ValidationContext } from '@common/forms/validation/validation-context';
@ -10,7 +11,7 @@ export class DmpNewVersionDialogEditorModel implements NewVersionDmpPersist {
label: string;
description: String;
blueprintId: Guid;
descriptions: Guid[] = [];
descriptions: NewVersionDmpDescriptionEditorModel[] = [];
hash?: string;
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
@ -18,14 +19,35 @@ export class DmpNewVersionDialogEditorModel implements NewVersionDmpPersist {
constructor() { }
public fromModel(item: Dmp): DmpNewVersionDialogEditorModel {
public fromModel(item: Dmp, blueprint: DmpBlueprint): DmpNewVersionDialogEditorModel {
if (item) {
this.id = item.id;
this.label = item.label;
this.description = item.description;
this.descriptions = item.descriptions?.map(d=> d.id);
this.blueprintId = item.blueprint.id;
this.label = this.label != undefined ? this.label : item.label;
this.description = this.description != undefined ? this.description : item.description;
this.blueprintId = blueprint?.id != undefined ? blueprint.id : item.blueprint.id;
this.hash= item.hash;
if (item.descriptions?.length > 0) {
// initialize because blueprint changed
this.descriptions = [];
if (item.dmpDescriptionTemplates?.length > 0 && blueprint.id === item.blueprint.id) {
item.descriptions.forEach(description => {
const matchingSection = item.dmpDescriptionTemplates.find(dmpDescriptionTemplate => dmpDescriptionTemplate.descriptionTemplateGroupId === description.descriptionTemplate.groupId);
this.descriptions.push(new NewVersionDmpDescriptionEditorModel(this.validationErrorModel).fromModel(description.id, matchingSection != null ? matchingSection.sectionId : null));
})
} else{
const selectedBlueprintSections = blueprint.definition?.sections?.filter(x => x.hasTemplates) || null;
if (selectedBlueprintSections != null){
item.descriptions.forEach(description => {
const matchingSection = selectedBlueprintSections.find(blueprintSection => blueprintSection.descriptionTemplates.map(y => y.descriptionTemplateGroupId).includes(description.descriptionTemplate.groupId));
this.descriptions.push(new NewVersionDmpDescriptionEditorModel(this.validationErrorModel).fromModel(description.id, matchingSection != null ? matchingSection.id : null));
})
}
}
}
}
return this;
}
@ -37,8 +59,15 @@ export class DmpNewVersionDialogEditorModel implements NewVersionDmpPersist {
id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators],
label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators],
description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators],
descriptions: this.formBuilder.array(
(this.descriptions ?? []).map(
(item, index) => item.buildForm({
rootPath: `descriptions[${index}].`,
disabled: disabled
})
), context.getValidation('descriptions').validators
),
blueprintId: [{ value: this.blueprintId, disabled: disabled }, context.getValidation('blueprintId').validators],
descriptions: [{ value: this.descriptions, disabled: disabled }, context.getValidation('descriptions').validators],
hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators]
});
}
@ -57,3 +86,55 @@ export class DmpNewVersionDialogEditorModel implements NewVersionDmpPersist {
return baseContext;
}
}
export class NewVersionDmpDescriptionEditorModel implements NewVersionDmpDescriptionPersist {
descriptionId: Guid;
blueprintSectionId: Guid;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { }
fromModel(descriptionId: Guid, blueprintSectionId: Guid): NewVersionDmpDescriptionEditorModel {
this.descriptionId = descriptionId;
this.blueprintSectionId = blueprintSectionId;
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = NewVersionDmpDescriptionEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
return this.formBuilder.group({
descriptionId: [{ value: this.descriptionId, disabled: disabled }, context.getValidation('descriptionId').validators],
blueprintSectionId: [{ value: this.blueprintSectionId, disabled: disabled }, context.getValidation('blueprintSectionId').validators],
});
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'descriptionId', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}descriptionId`)] });
baseValidationArray.push({ key: 'blueprintSectionId', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}blueprintSectionId`)] });
baseContext.validation = baseValidationArray;
return baseContext;
}
}

View File

@ -16,7 +16,7 @@ import { DmpAccessType } from '@app/core/common/enum/dmp-access-type';
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
import { DepositConfiguration } from '@app/core/model/deposit/deposit-configuration';
import { Description } from '@app/core/model/description/description';
import { Dmp, DmpUser, DmpUserRemovePersist } from '@app/core/model/dmp/dmp';
import { Dmp, DmpDescriptionTemplate, DmpUser, DmpUserRemovePersist } from '@app/core/model/dmp/dmp';
import { DmpReference } from '@app/core/model/dmp/dmp-reference';
import { EntityDoi } from '@app/core/model/entity-doi/entity-doi';
import { Reference } from '@app/core/model/reference/reference';
@ -38,7 +38,7 @@ import { takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { DmpInvitationDialogComponent } from '../invitation/dialog/dmp-invitation-dialog.component';
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { CloneDmpDialogComponent } from '../clone-dialog/dmp-clone-dialog.component';
import { NewVersionDmpDialogComponent } from '../new-version-dialog/dmp-new-version-dialog.component';
import { AppPermission } from '@app/core/common/enum/permission.enum';
@ -50,6 +50,7 @@ import { FileTransformerEntityType } from '@app/core/common/enum/file-transforme
import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status';
import { DmpDeleteDialogComponent } from '../dmp-delete-dialog/dmp-delete-dialog.component';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
@Component({
selector: 'app-dmp-overview',
@ -794,12 +795,17 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.source)].join('.'),
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.reference)].join('.'),
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.isActive)].join('.'),
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
[nameof<Dmp>(x => x.otherDmpVersions), nameof<Dmp>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.otherDmpVersions), nameof<Dmp>(x => x.groupId)].join('.'),

View File

@ -1947,10 +1947,6 @@
"REUSED": "Reused dataset",
"OTHER": "Other"
},
"DMP-CONTACT-TYPE": {
"INTERNAL": "Internal",
"EXTERNAL": "External"
},
"DMP-USER-TYPE": {
"INTERNAL": "Internal",
"EXTERNAL": "External"