add multiplicity validation ui
This commit is contained in:
parent
6f7ed58523
commit
26cbe562ad
|
@ -219,8 +219,7 @@ public class DescriptionPersist {
|
||||||
.must(() -> !this.isNull(item.getProperties()))
|
.must(() -> !this.isNull(item.getProperties()))
|
||||||
.failOn(DescriptionPersist._properties).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionPersist._properties}, LocaleContextHolder.getLocale())),
|
.failOn(DescriptionPersist._properties).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionPersist._properties}, LocaleContextHolder.getLocale())),
|
||||||
this.spec()
|
this.spec()
|
||||||
.iff(() -> item.getStatus() == DescriptionStatus.Finalized)
|
.must(() -> this.isDescriptionTemplateMaxMultiplicityValid(finalDmpBlueprintEntity, item.getDmpId(), item.getDmpDescriptionTemplateId(), this.isValidGuid(item.getId())))
|
||||||
.must(() -> this.isDescriptionTemplateMultiplicityValid(finalDmpBlueprintEntity, item.getDmpId(), item.getDescriptionTemplateId()))
|
|
||||||
.failOn(DescriptionPersist._descriptionTemplateId).failWith(messageSource.getMessage("Validation.InvalidDescriptionTemplateMultiplicity", new Object[]{DescriptionPersist._descriptionTemplateId}, LocaleContextHolder.getLocale()))
|
.failOn(DescriptionPersist._descriptionTemplateId).failWith(messageSource.getMessage("Validation.InvalidDescriptionTemplateMultiplicity", new Object[]{DescriptionPersist._descriptionTemplateId}, LocaleContextHolder.getLocale()))
|
||||||
// this.refSpec()
|
// this.refSpec()
|
||||||
// .iff(() -> !this.isNull(item.getProperties()))
|
// .iff(() -> !this.isNull(item.getProperties()))
|
||||||
|
@ -235,26 +234,28 @@ public class DescriptionPersist {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDescriptionTemplateMultiplicityValid(DmpBlueprintEntity dmpBlueprintEntity, UUID dmpId, UUID descriptionTemplateId){
|
private boolean isDescriptionTemplateMaxMultiplicityValid(DmpBlueprintEntity dmpBlueprintEntity, UUID dmpId, UUID dmpDescriptionTemplateId, Boolean isUpdate){
|
||||||
eu.eudat.commons.types.dmpblueprint.DefinitionEntity definition = this.xmlHandlingService.fromXmlSafe(eu.eudat.commons.types.dmpblueprint.DefinitionEntity.class, dmpBlueprintEntity.getDefinition());
|
eu.eudat.commons.types.dmpblueprint.DefinitionEntity definition = this.xmlHandlingService.fromXmlSafe(eu.eudat.commons.types.dmpblueprint.DefinitionEntity.class, dmpBlueprintEntity.getDefinition());
|
||||||
if (definition == null || this.isListNullOrEmpty(definition.getSections())) return true;
|
if (definition == null || this.isListNullOrEmpty(definition.getSections())) return true;
|
||||||
|
|
||||||
|
DmpDescriptionTemplateEntity dmpDescriptionTemplateEntity = this.queryFactory.query(DmpDescriptionTemplateQuery.class).ids(dmpDescriptionTemplateId).isActive(IsActive.Active).dmpIds(dmpId).first();
|
||||||
|
if (dmpDescriptionTemplateEntity == null) return true;
|
||||||
|
|
||||||
|
List<DescriptionEntity> descriptionEntities = this.queryFactory.query(DescriptionQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).dmpIds(dmpId).dmpDescriptionTemplateIds(dmpDescriptionTemplateId).isActive(IsActive.Active).collect();
|
||||||
|
|
||||||
for (SectionEntity section: definition.getSections()) {
|
for (SectionEntity section: definition.getSections()) {
|
||||||
if (section.getHasTemplates() && !this.isListNullOrEmpty(section.getDescriptionTemplates())){
|
if (dmpDescriptionTemplateEntity.getSectionId().equals(section.getId()) && section.getHasTemplates() && !this.isListNullOrEmpty(section.getDescriptionTemplates())){
|
||||||
int descriptionsCount = 0;
|
int descriptionsCount;
|
||||||
|
if (isUpdate) descriptionsCount = -1;
|
||||||
|
else descriptionsCount = 0;
|
||||||
|
|
||||||
for (eu.eudat.commons.types.dmpblueprint.DescriptionTemplateEntity sectionDescriptionTemplate: section.getDescriptionTemplates()) {
|
for (eu.eudat.commons.types.dmpblueprint.DescriptionTemplateEntity sectionDescriptionTemplate: section.getDescriptionTemplates()) {
|
||||||
if (sectionDescriptionTemplate.getMaxMultiplicity() == null && sectionDescriptionTemplate.getMinMultiplicity() == null ) continue;
|
if (sectionDescriptionTemplate.getDescriptionTemplateGroupId().equals(dmpDescriptionTemplateEntity.getDescriptionTemplateGroupId())){
|
||||||
|
|
||||||
DmpDescriptionTemplateQuery dmpDescriptionTemplateQuery = this.queryFactory.query(DmpDescriptionTemplateQuery.class).isActive(IsActive.Active).dmpIds(dmpId).sectionIds(section.getId());
|
|
||||||
List<DescriptionEntity> descriptionEntities = this.queryFactory.query(DescriptionQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).dmpIds(dmpId).dmpDescriptionTemplateSubQuery(dmpDescriptionTemplateQuery).isActive(IsActive.Active).collect();
|
|
||||||
if (this.isListNullOrEmpty(descriptionEntities)) continue;
|
|
||||||
|
|
||||||
for (DescriptionEntity description: descriptionEntities){
|
for (DescriptionEntity description: descriptionEntities){
|
||||||
if (description.getDescriptionTemplateId().equals(descriptionTemplateId)) descriptionsCount++;
|
if (description.getDmpDescriptionTemplateId().equals(dmpDescriptionTemplateEntity.getId())) descriptionsCount++;
|
||||||
}
|
}
|
||||||
if (sectionDescriptionTemplate.getMinMultiplicity() != null && sectionDescriptionTemplate.getMinMultiplicity() >= descriptionsCount) return false;
|
|
||||||
if (sectionDescriptionTemplate.getMaxMultiplicity() != null && sectionDescriptionTemplate.getMaxMultiplicity() <= descriptionsCount) return false;
|
if (sectionDescriptionTemplate.getMaxMultiplicity() != null && sectionDescriptionTemplate.getMaxMultiplicity() <= descriptionsCount) return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,8 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
|
||||||
private final UserScope userScope;
|
private final UserScope userScope;
|
||||||
private final AuthorizationService authService;
|
private final AuthorizationService authService;
|
||||||
private final QueryUtilsService queryUtilsService;
|
private final QueryUtilsService queryUtilsService;
|
||||||
|
|
||||||
|
private Collection<UUID> dmpDescriptionTemplateIds;
|
||||||
public DescriptionQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService) {
|
public DescriptionQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService) {
|
||||||
this.userScope = userScope;
|
this.userScope = userScope;
|
||||||
this.authService = authService;
|
this.authService = authService;
|
||||||
|
@ -110,7 +112,20 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DescriptionQuery dmpDescriptionTemplateIds(UUID value) {
|
||||||
|
this.dmpDescriptionTemplateIds = List.of(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DescriptionQuery dmpDescriptionTemplateIds(UUID... value) {
|
||||||
|
this.dmpDescriptionTemplateIds = Arrays.asList(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DescriptionQuery dmpDescriptionTemplateIds(Collection<UUID> values) {
|
||||||
|
this.dmpDescriptionTemplateIds = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public DescriptionQuery finalizedAfter(Instant value) {
|
public DescriptionQuery finalizedAfter(Instant value) {
|
||||||
this.finalizedAfter = value;
|
this.finalizedAfter = value;
|
||||||
|
@ -287,6 +302,12 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
|
||||||
QueryContext<DmpEntity, UUID> subQuery = this.applySubQuery(this.dmpQuery, queryContext, UUID.class, dmpEntityRoot -> dmpEntityRoot.get(DmpEntity._id));
|
QueryContext<DmpEntity, UUID> subQuery = this.applySubQuery(this.dmpQuery, queryContext, UUID.class, dmpEntityRoot -> dmpEntityRoot.get(DmpEntity._id));
|
||||||
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._dmpId)).value(subQuery.Query));
|
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._dmpId)).value(subQuery.Query));
|
||||||
}
|
}
|
||||||
|
if (this.dmpDescriptionTemplateIds != null) {
|
||||||
|
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._dmpDescriptionTemplateId));
|
||||||
|
for (UUID item : this.dmpDescriptionTemplateIds)
|
||||||
|
inClause.value(item);
|
||||||
|
predicates.add(inClause);
|
||||||
|
}
|
||||||
if (!predicates.isEmpty()) {
|
if (!predicates.isEmpty()) {
|
||||||
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
|
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
|
||||||
return queryContext.CriteriaBuilder.and(predicatesArray);
|
return queryContext.CriteriaBuilder.and(predicatesArray);
|
||||||
|
|
|
@ -358,7 +358,9 @@ public class PrefillingSourceServiceImpl implements PrefillingSourceService {
|
||||||
eu.eudat.commons.types.descriptiontemplate.DefinitionEntity descriptionTemplateDefinition = this.xmlHandlingService.fromXml(eu.eudat.commons.types.descriptiontemplate.DefinitionEntity.class, descriptionTemplateEntity.getDefinition());
|
eu.eudat.commons.types.descriptiontemplate.DefinitionEntity descriptionTemplateDefinition = this.xmlHandlingService.fromXml(eu.eudat.commons.types.descriptiontemplate.DefinitionEntity.class, descriptionTemplateEntity.getDefinition());
|
||||||
|
|
||||||
Description description = new Description();
|
Description description = new Description();
|
||||||
description.setDescriptionTemplate(this.builderFactory.builder(DescriptionTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(fieldSet, descriptionTemplateEntity));
|
FieldSet descriptionTemplateFields = fieldSet.extractPrefixed(this.conventionService.asPrefix(Description._descriptionTemplate));
|
||||||
|
|
||||||
|
description.setDescriptionTemplate(this.builderFactory.builder(DescriptionTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(descriptionTemplateFields, descriptionTemplateEntity));
|
||||||
return mapPrefilledEntityToDescription(description, descriptionTemplateDefinition, prefillingSourceDefinition, prefillingSourceEntity.getLabel(), externalData.getResults().getFirst());//TODO
|
return mapPrefilledEntityToDescription(description, descriptionTemplateDefinition, prefillingSourceDefinition, prefillingSourceEntity.getLabel(), externalData.getResults().getFirst());//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,8 @@ export class DmpBlueprintService {
|
||||||
lookup.project = {
|
lookup.project = {
|
||||||
fields: [
|
fields: [
|
||||||
nameof<DmpBlueprint>(x => x.id),
|
nameof<DmpBlueprint>(x => x.id),
|
||||||
nameof<DmpBlueprint>(x => x.label)
|
nameof<DmpBlueprint>(x => x.label),
|
||||||
|
nameof<DmpBlueprint>(x => x.version)
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
lookup.order = { items: [nameof<DmpBlueprint>(x => x.label)] };
|
lookup.order = { items: [nameof<DmpBlueprint>(x => x.label)] };
|
||||||
|
|
|
@ -550,6 +550,7 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
|
||||||
finalize() {
|
finalize() {
|
||||||
if (this.checkValidity()) {
|
if (this.checkValidity()) {
|
||||||
this.formGroup.get('status').setValue(DmpBlueprintStatus.Finalized);
|
this.formGroup.get('status').setValue(DmpBlueprintStatus.Finalized);
|
||||||
|
if(this.isNewVersion) this.isNewVersion = false;
|
||||||
this.formSubmit();
|
this.formSubmit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,9 @@ import { FormValidationErrorsDialogComponent } from '@common/forms/form-validati
|
||||||
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||||
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
|
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
|
||||||
import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service';
|
import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service';
|
||||||
|
import { DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||||
|
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
|
||||||
|
import { DmpDescriptionTemplate } from '@app/core/model/dmp/dmp';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-description-editor-component',
|
selector: 'app-description-editor-component',
|
||||||
|
@ -55,24 +58,6 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
||||||
isNew = true;
|
isNew = true;
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
item: Description;
|
item: Description;
|
||||||
// showInactiveDetails = false;
|
|
||||||
// selectedSystemFields: Array<DescriptionSystemFieldType> = [];
|
|
||||||
// DescriptionSectionFieldCategory = DescriptionSectionFieldCategory;
|
|
||||||
// DescriptionSystemFieldType = DescriptionSystemFieldType;
|
|
||||||
// public DescriptionSystemFieldTypeEnum = this.enumUtils.getEnumValues<DescriptionSystemFieldType>(DescriptionSystemFieldType);
|
|
||||||
// DescriptionExtraFieldDataType = DescriptionExtraFieldDataType;
|
|
||||||
// public DescriptionExtraFieldDataTypeEnum = this.enumUtils.getEnumValues<DescriptionExtraFieldDataType>(DescriptionExtraFieldDataType);
|
|
||||||
|
|
||||||
// blueprintsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
|
|
||||||
// filterFn: this.filterDescriptionTempaltes.bind(this),
|
|
||||||
// initialItems: (excludedItems: any[]) => this.filterDescriptionTempaltes('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
|
||||||
// displayFn: (item: DatasetProfileModel) => item.label,
|
|
||||||
// titleFn: (item: DatasetProfileModel) => item.label,
|
|
||||||
// subtitleFn: (item: DatasetProfileModel) => item.description,
|
|
||||||
// popupItemActionIcon: 'visibility'
|
|
||||||
// };
|
|
||||||
|
|
||||||
// hasChanges = false;
|
|
||||||
fieldsetIdWithFocus: string;
|
fieldsetIdWithFocus: string;
|
||||||
|
|
||||||
viewOnly = false;
|
viewOnly = false;
|
||||||
|
@ -211,10 +196,14 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
||||||
},
|
},
|
||||||
panelClass: 'custom-modalbox'
|
panelClass: 'custom-modalbox'
|
||||||
});
|
});
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
dialogRef.afterClosed().subscribe((result: Description) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
result.dmp = this.item.dmp;
|
result.dmp = this.item.dmp;
|
||||||
result.dmpDescriptionTemplate = this.item.dmpDescriptionTemplate;
|
result.dmpDescriptionTemplate = this.item.dmpDescriptionTemplate;
|
||||||
|
|
||||||
|
const sectionId = this.item.dmpDescriptionTemplate.sectionId;
|
||||||
|
result.dmpDescriptionTemplate = this.item.dmp.dmpDescriptionTemplates.find(x => x.sectionId == sectionId && x.descriptionTemplateGroupId == result.descriptionTemplate.groupId);
|
||||||
|
|
||||||
this.prepareForm(result);
|
this.prepareForm(result);
|
||||||
// this.descriptionModel = this.descriptionModel.fromModel(result);
|
// this.descriptionModel = this.descriptionModel.fromModel(result);
|
||||||
// this.descriptionModel.dmp = data;
|
// this.descriptionModel.dmp = data;
|
||||||
|
@ -551,6 +540,13 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
||||||
try {
|
try {
|
||||||
this.editorModel = data ? new DescriptionEditorModel().fromModel(data, data.descriptionTemplate) : new DescriptionEditorModel();
|
this.editorModel = data ? new DescriptionEditorModel().fromModel(data, data.descriptionTemplate) : new DescriptionEditorModel();
|
||||||
this.item = data;
|
this.item = data;
|
||||||
|
if (data && data.dmpDescriptionTemplate?.sectionId && data.dmp?.blueprint?.definition?.sections?.length > 0 && data.dmp?.descriptions?.length > 0){
|
||||||
|
const section = data.dmp?.blueprint?.definition?.sections.find(x => x.id == data.dmpDescriptionTemplate?.sectionId);
|
||||||
|
if(section.hasTemplates) {
|
||||||
|
const notAvailableDescriptionTemplates = this.calculateMultiplicityRejectedDmpDescriptionTemplates(section, data.dmp.descriptions.filter(x => x.isActive == IsActive.Active));
|
||||||
|
this.item.dmp.dmpDescriptionTemplates = data.dmp.dmpDescriptionTemplates.filter(x => !notAvailableDescriptionTemplates.map(y => y.id).includes(x.id) )
|
||||||
|
}
|
||||||
|
}
|
||||||
this.isDeleted = data ? data.isActive === IsActive.Inactive : false;
|
this.isDeleted = data ? data.isActive === IsActive.Inactive : false;
|
||||||
this.buildForm();
|
this.buildForm();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -588,6 +584,26 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calculateMultiplicityRejectedDmpDescriptionTemplates(section: DmpBlueprintDefinitionSection, descriptions: Description[]) : DmpDescriptionTemplate[]{
|
||||||
|
if (section.descriptionTemplates?.length > 0){
|
||||||
|
descriptions = descriptions?.filter(x => x?.dmpDescriptionTemplate?.sectionId === section.id) || [];
|
||||||
|
|
||||||
|
let rejectedDmpDescriptionTemplates: DmpDescriptionTemplate[] = [];
|
||||||
|
section.descriptionTemplates.forEach(sectionDescriptionTemplate => {
|
||||||
|
if (sectionDescriptionTemplate.maxMultiplicity != null){
|
||||||
|
const commonDescriptions = descriptions.filter(x => x.dmpDescriptionTemplate.descriptionTemplateGroupId == sectionDescriptionTemplate.descriptionTemplateGroupId);
|
||||||
|
|
||||||
|
if (commonDescriptions && commonDescriptions.length >= sectionDescriptionTemplate.maxMultiplicity) {
|
||||||
|
rejectedDmpDescriptionTemplates = commonDescriptions.map(x => x.dmpDescriptionTemplate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return rejectedDmpDescriptionTemplates;
|
||||||
|
} else{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
refreshData(): void {
|
refreshData(): void {
|
||||||
this.getItem(this.editorModel.id, (data: Description) => this.prepareForm(data));
|
this.getItem(this.editorModel.id, (data: Description) => this.prepareForm(data));
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
|
||||||
(prefix ? prefix + '.' : '') + [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('.'),
|
(prefix ? prefix + '.' : '') + [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('.'),
|
||||||
// (prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.label)].join('.'),
|
// (prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.label)].join('.'),
|
||||||
// (prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.minMultiplicity)].join('.'),
|
// (prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.minMultiplicity)].join('.'),
|
||||||
// (prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
|
||||||
|
|
||||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.id)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.id)].join('.'),
|
||||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
||||||
|
@ -165,6 +165,13 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
|
||||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.currentDescriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.currentDescriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
|
||||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.currentDescriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.currentDescriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
|
||||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.currentDescriptionTemplate), nameof<DescriptionTemplate>(x => x.version)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.currentDescriptionTemplate), nameof<DescriptionTemplate>(x => x.version)].join('.'),
|
||||||
|
|
||||||
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'),
|
||||||
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.isActive)].join('.'),
|
||||||
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.id)].join('.'),
|
||||||
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
|
||||||
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
||||||
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@ import { TranslateService } from "@ngx-translate/core";
|
||||||
import { UUID } from "crypto";
|
import { UUID } from "crypto";
|
||||||
import { Observable } from "rxjs";
|
import { Observable } from "rxjs";
|
||||||
import { map, takeUntil } from "rxjs/operators";
|
import { map, takeUntil } from "rxjs/operators";
|
||||||
|
import { DescriptionEditorResolver } from "../description-editor.resolver";
|
||||||
|
import { nameof } from "ts-simple-nameof";
|
||||||
|
import { Description } from "@app/core/model/description/description";
|
||||||
|
import { IsActive } from "@app/core/common/enum/is-active.enum";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'prefill-description-component',
|
selector: 'prefill-description-component',
|
||||||
|
@ -47,7 +51,7 @@ export class PrefillDescriptionDialogComponent extends BaseComponent implements
|
||||||
|
|
||||||
this.dmp = data.dmp;
|
this.dmp = data.dmp;
|
||||||
this.dmpSectionId = data.dmpSectionId;
|
this.dmpSectionId = data.dmpSectionId;
|
||||||
this.availableDescriptionTemplates = this.dmp.dmpDescriptionTemplates.filter(x => x.sectionId == this.dmpSectionId).map(x => x.currentDescriptionTemplate);
|
this.availableDescriptionTemplates = this.dmp.dmpDescriptionTemplates.filter(x => x.sectionId == this.dmpSectionId && x.isActive == IsActive.Active).map(x => x.currentDescriptionTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
@ -212,7 +216,7 @@ export class PrefillDescriptionDialogComponent extends BaseComponent implements
|
||||||
// }
|
// }
|
||||||
const formData = this.formService.getValue(this.prefillForm.value) as DescriptionProfilingRequest;
|
const formData = this.formService.getValue(this.prefillForm.value) as DescriptionProfilingRequest;
|
||||||
|
|
||||||
this.prefillingSourceService.generate(formData, DescriptionTemplateEditorResolver.lookupFields())
|
this.prefillingSourceService.generate(formData, DescriptionEditorResolver.descriptionTemplateLookupFields(nameof<Description>(x => x.descriptionTemplate)))
|
||||||
.pipe(takeUntil(this._destroyed)).subscribe(description => {
|
.pipe(takeUntil(this._destroyed)).subscribe(description => {
|
||||||
if (description) {
|
if (description) {
|
||||||
this.closeDialog(description);
|
this.closeDialog(description);
|
||||||
|
|
|
@ -96,11 +96,16 @@
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<ul *ngIf="item.id && section.hasTemplates && canEditSection(section.id) && !formGroup.disabled" class="add-description-option">
|
<ul *ngIf="item.id && section.hasTemplates && canEditSection(section.id) && !formGroup.disabled" class="add-description-option">
|
||||||
<li>
|
<li *ngIf="canAddDescription(section)">
|
||||||
<a class="add-description-action" [routerLink]="['/descriptions/edit/' + item.id + '/' + section.id]">
|
<a class="add-description-action" [routerLink]="['/descriptions/edit/' + item.id + '/' + section.id]">
|
||||||
<mat-icon>add</mat-icon>{{'DMP-EDITOR.ACTIONS.ADD-DESCRIPTION-IN-SECTION' | translate}}
|
<mat-icon>add</mat-icon>{{'DMP-EDITOR.ACTIONS.ADD-DESCRIPTION-IN-SECTION' | translate}}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li *ngIf="!canAddDescription(section)">
|
||||||
|
<a [ngClass]="{'drag-handle-disabled': true}" class="add-description-action">
|
||||||
|
<mat-icon>add</mat-icon>{{'DMP-EDITOR.ACTIONS.ADD-DESCRIPTION-IN-SECTION' | translate}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||||
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
|
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
|
||||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||||
import { DescriptionSectionPermissionResolver } from '@app/core/model/description/description';
|
import { DescriptionSectionPermissionResolver } from '@app/core/model/description/description';
|
||||||
import { DmpBlueprint } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
import { DmpBlueprint, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||||
import { Dmp, DmpPersist } from '@app/core/model/dmp/dmp';
|
import { Dmp, DmpPersist } from '@app/core/model/dmp/dmp';
|
||||||
import { LanguageInfo } from '@app/core/model/language-info';
|
import { LanguageInfo } from '@app/core/model/language-info';
|
||||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||||
|
@ -88,6 +88,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
||||||
filterFn: (searchQuery: string, data?: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(searchQuery, 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])),
|
getSelectedItem: (selectedItem: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
|
||||||
displayFn: (item: DmpBlueprint) => item.label,
|
displayFn: (item: DmpBlueprint) => item.label,
|
||||||
|
subtitleFn: (item: DmpBlueprint) => this.language.instant('DMP-EDITOR.FIELDS.DMP-BLUEPRINT-VERSION') + ' '+ item.version,
|
||||||
titleFn: (item: DmpBlueprint) => item.label,
|
titleFn: (item: DmpBlueprint) => item.label,
|
||||||
valueAssign: (item: DmpBlueprint) => item.id,
|
valueAssign: (item: DmpBlueprint) => item.id,
|
||||||
};
|
};
|
||||||
|
@ -446,6 +447,32 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canAddDescription(section: DmpBlueprintDefinitionSection ): boolean{
|
||||||
|
if(section.hasTemplates){
|
||||||
|
if (section.descriptionTemplates?.length > 0){
|
||||||
|
const descriptions = this.descriptionsInSection(section.id)
|
||||||
|
|
||||||
|
let multiplicityValidResults :boolean[] = [];
|
||||||
|
section.descriptionTemplates.forEach(sectionDescriptionTemplate => {
|
||||||
|
if (sectionDescriptionTemplate.maxMultiplicity != null){
|
||||||
|
const count = descriptions.filter(x => x.dmpDescriptionTemplate.descriptionTemplateGroupId == sectionDescriptionTemplate.descriptionTemplateGroupId).length || 0;
|
||||||
|
if (count >= sectionDescriptionTemplate.maxMultiplicity) multiplicityValidResults.push(false);
|
||||||
|
else multiplicityValidResults.push(true);
|
||||||
|
}else{
|
||||||
|
multiplicityValidResults.push(true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if(multiplicityValidResults.includes(true)) return true
|
||||||
|
else return false;
|
||||||
|
}else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Description Template
|
// Description Template
|
||||||
|
|
|
@ -61,6 +61,7 @@ export class DmpEditorResolver extends BaseEditorResolver {
|
||||||
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.isActive)].join('.'),
|
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.isActive)].join('.'),
|
||||||
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.id)].join('.'),
|
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.id)].join('.'),
|
||||||
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
||||||
|
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
|
||||||
|
|
||||||
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
|
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
|
||||||
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
|
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
|
||||||
|
@ -104,6 +105,8 @@ export class DmpEditorResolver extends BaseEditorResolver {
|
||||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.ordinal)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.ordinal)].join('.'),
|
||||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
|
||||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
|
||||||
|
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.minMultiplicity)].join('.'),
|
||||||
|
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
|
||||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.id)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.id)].join('.'),
|
||||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.category)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.category)].join('.'),
|
||||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.label)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.label)].join('.'),
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 title-form">
|
<div class="col-12 title-form">
|
||||||
<mat-form-field class="w-100">
|
<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]="dmpBlueprintService.singleAutocompleteConfiguration">
|
<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>
|
</app-single-auto-complete>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,10 +6,13 @@ import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||||
import { BaseComponent } from '@common/base/base.component';
|
import { BaseComponent } from '@common/base/base.component';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { map, takeUntil } from 'rxjs/operators';
|
||||||
import { DmpNewVersionDialogEditorModel } from './dmp-new-version-dialog.editor.model';
|
import { DmpNewVersionDialogEditorModel } from './dmp-new-version-dialog.editor.model';
|
||||||
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
|
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
|
||||||
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
|
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 { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-dmp-new-version-dialog',
|
selector: 'app-dmp-new-version-dialog',
|
||||||
|
@ -22,6 +25,16 @@ export class NewVersionDmpDialogComponent extends BaseComponent {
|
||||||
editorModel: DmpNewVersionDialogEditorModel;
|
editorModel: DmpNewVersionDialogEditorModel;
|
||||||
formGroup: UntypedFormGroup;
|
formGroup: UntypedFormGroup;
|
||||||
|
|
||||||
|
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])),
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<NewVersionDmpDialogComponent>,
|
public dialogRef: MatDialogRef<NewVersionDmpDialogComponent>,
|
||||||
private dmpService: DmpService,
|
private dmpService: DmpService,
|
||||||
|
|
|
@ -1304,7 +1304,8 @@
|
||||||
"EMAIL": "Email",
|
"EMAIL": "Email",
|
||||||
"USER": "User",
|
"USER": "User",
|
||||||
"USER-ROLE": "Role",
|
"USER-ROLE": "Role",
|
||||||
"SECTION": "Specific DMP Section"
|
"SECTION": "Specific DMP Section",
|
||||||
|
"DMP-BLUEPRINT-VERSION": "Version"
|
||||||
},
|
},
|
||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"DISCARD": "Discard",
|
"DISCARD": "Discard",
|
||||||
|
|
Loading…
Reference in New Issue