description template fixes
This commit is contained in:
parent
ab993c43af
commit
4de68e34b2
|
@ -1,12 +1,19 @@
|
|||
package eu.eudat.model.persist;
|
||||
|
||||
import eu.eudat.authorization.AuthorizationFlags;
|
||||
import eu.eudat.commons.XmlHandlingService;
|
||||
import eu.eudat.commons.enums.DmpAccessType;
|
||||
import eu.eudat.commons.enums.DmpStatus;
|
||||
import eu.eudat.commons.enums.IsActive;
|
||||
import eu.eudat.commons.types.dmpblueprint.SectionEntity;
|
||||
import eu.eudat.commons.validation.BaseValidator;
|
||||
import eu.eudat.data.*;
|
||||
import eu.eudat.query.DescriptionQuery;
|
||||
import eu.eudat.query.DmpDescriptionTemplateQuery;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
import gr.cite.tools.validation.ValidatorFactory;
|
||||
import gr.cite.tools.validation.specification.Specification;
|
||||
import eu.eudat.convention.ConventionService;
|
||||
import eu.eudat.data.DmpEntity;
|
||||
import eu.eudat.errorcode.ErrorThesaurusProperties;
|
||||
import eu.eudat.model.persist.dmpproperties.DmpPropertiesPersist;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
|
@ -15,6 +22,7 @@ import org.springframework.context.annotation.Scope;
|
|||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
@ -160,11 +168,17 @@ public class DmpPersist {
|
|||
private final MessageSource messageSource;
|
||||
|
||||
private final ValidatorFactory validatorFactory;
|
||||
private final TenantEntityManager entityManager;
|
||||
private final XmlHandlingService xmlHandlingService;
|
||||
private final QueryFactory queryFactory;
|
||||
|
||||
protected DmpPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) {
|
||||
protected DmpPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory, TenantEntityManager entityManager, XmlHandlingService xmlHandlingService, QueryFactory queryFactory) {
|
||||
super(conventionService, errors);
|
||||
this.messageSource = messageSource;
|
||||
this.validatorFactory = validatorFactory;
|
||||
this.entityManager = entityManager;
|
||||
this.xmlHandlingService = xmlHandlingService;
|
||||
this.queryFactory = queryFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -174,6 +188,16 @@ public class DmpPersist {
|
|||
|
||||
@Override
|
||||
protected List<Specification> specifications(DmpPersist item) {
|
||||
DmpEntity dmpEntity = null;
|
||||
DmpBlueprintEntity dmpBlueprintEntity = null;
|
||||
try {
|
||||
dmpEntity = this.isValidGuid(item.getId()) ? this.entityManager.find(DmpEntity.class, item.getId()) : null;
|
||||
if(dmpEntity != null) dmpBlueprintEntity = this.isValidGuid(item.getBlueprint()) ? this.entityManager.find(DmpBlueprintEntity.class, dmpEntity.getBlueprintId()) : null;
|
||||
|
||||
} catch (InvalidApplicationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
DmpBlueprintEntity finalDmpBlueprintEntity = dmpBlueprintEntity;
|
||||
return Arrays.asList(
|
||||
this.spec()
|
||||
.iff(() -> this.isValidGuid(item.getId()))
|
||||
|
@ -202,6 +226,10 @@ public class DmpPersist {
|
|||
.iff(() -> item.getStatus() == DmpStatus.Finalized)
|
||||
.must(() -> !this.isNull(item.getProperties()))
|
||||
.failOn(DmpPersist._properties).failWith(messageSource.getMessage("Validation_Required", new Object[]{DmpPersist._properties}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.iff(() -> item.getStatus() == DmpStatus.Finalized)
|
||||
.must(() -> this.isDescriptionTemplateMultiplicityValid(finalDmpBlueprintEntity, item.getId()))
|
||||
.failOn(DmpPersist._descriptionTemplates).failWith(messageSource.getMessage("Validation.InvalidDescriptionTemplateMultiplicity", new Object[]{DmpPersist._descriptionTemplates}, LocaleContextHolder.getLocale())),
|
||||
this.refSpec()
|
||||
.iff(() -> !this.isNull(item.getProperties()))
|
||||
.on(DmpPersist._properties)
|
||||
|
@ -231,6 +259,42 @@ public class DmpPersist {
|
|||
.using((itm) -> this.validatorFactory.validator(DmpUserPersist.DmpUserPersistValidator.class))
|
||||
);
|
||||
}
|
||||
|
||||
private boolean isDescriptionTemplateMultiplicityValid(DmpBlueprintEntity dmpBlueprintEntity, UUID dmpId){
|
||||
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;
|
||||
|
||||
List<DmpDescriptionTemplateEntity> dmpDescriptionTemplateEntities = this.queryFactory.query(DmpDescriptionTemplateQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).isActive(IsActive.Active).dmpIds(dmpId).collect();
|
||||
List<DescriptionEntity> descriptionEntities = this.queryFactory.query(DescriptionQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).dmpIds(dmpId).isActive(IsActive.Active).collect();
|
||||
|
||||
for (SectionEntity section: definition.getSections()) {
|
||||
if (section.getHasTemplates() && !this.isListNullOrEmpty(section.getDescriptionTemplates())){
|
||||
|
||||
for (eu.eudat.commons.types.dmpblueprint.DescriptionTemplateEntity sectionDescriptionTemplate: section.getDescriptionTemplates()) {
|
||||
if (sectionDescriptionTemplate.getMaxMultiplicity() == null && sectionDescriptionTemplate.getMinMultiplicity() == null ) continue;
|
||||
|
||||
int descriptionsCount = 0;
|
||||
for (DmpDescriptionTemplateEntity dmpDescriptionTemplate: dmpDescriptionTemplateEntities) {
|
||||
|
||||
if(dmpDescriptionTemplate.getSectionId().equals(section.getId())) {
|
||||
for (DescriptionEntity description: descriptionEntities){
|
||||
if (sectionDescriptionTemplate.getDescriptionTemplateGroupId().equals(dmpDescriptionTemplate.getDescriptionTemplateGroupId())) {
|
||||
if (description.getDmpDescriptionTemplateId().equals(dmpDescriptionTemplate.getId()) && dmpDescriptionTemplate.getSectionId().equals(section.getId()))
|
||||
descriptionsCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sectionDescriptionTemplate.getMinMultiplicity() != null && sectionDescriptionTemplate.getMinMultiplicity() > descriptionsCount) return false;
|
||||
if (sectionDescriptionTemplate.getMaxMultiplicity() != null && sectionDescriptionTemplate.getMaxMultiplicity() < descriptionsCount) return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -514,8 +514,8 @@ public class DmpBlueprintServiceImpl implements DmpBlueprintService {
|
|||
DescriptionTemplateImportExport xml = new DescriptionTemplateImportExport();
|
||||
xml.setDescriptionTemplateGroupId(entity.getDescriptionTemplateGroupId());
|
||||
xml.setLabel(entity.getLabel());
|
||||
xml.setMinMultiplicity(entity.getMinMultiplicity());
|
||||
xml.setMaxMultiplicity(entity.getMaxMultiplicity());
|
||||
if (entity.getMinMultiplicity() != null ) xml.setMinMultiplicity(entity.getMinMultiplicity());
|
||||
if (entity.getMaxMultiplicity() != null ) xml.setMaxMultiplicity(entity.getMaxMultiplicity());
|
||||
return xml;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,15 +37,17 @@ export class FinalPreviewComponent implements OnInit {
|
|||
|
||||
private generatePreviewForm() {
|
||||
|
||||
this.descriptionTemplate = this.buildDescriptionTemplate(this.descriptionTemplatePersist);
|
||||
if(this.descriptionTemplatePersist){
|
||||
this.descriptionTemplate = this.buildDescriptionTemplate(this.descriptionTemplatePersist);
|
||||
|
||||
const mockDescription: Description = {
|
||||
descriptionTemplate: this.descriptionTemplate
|
||||
const mockDescription: Description = {
|
||||
descriptionTemplate: this.descriptionTemplate
|
||||
}
|
||||
const descriptionEditorModel = new DescriptionEditorModel().fromModel(mockDescription, mockDescription.descriptionTemplate);
|
||||
this.previewPropertiesFormGroup = descriptionEditorModel.properties.buildForm() as UntypedFormGroup;
|
||||
|
||||
this.visibilityRulesService.setContext(this.descriptionTemplate.definition, this.previewPropertiesFormGroup);
|
||||
}
|
||||
const descriptionEditorModel = new DescriptionEditorModel().fromModel(mockDescription, mockDescription.descriptionTemplate);
|
||||
this.previewPropertiesFormGroup = descriptionEditorModel.properties.buildForm() as UntypedFormGroup;
|
||||
|
||||
this.visibilityRulesService.setContext(this.descriptionTemplate.definition, this.previewPropertiesFormGroup);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@
|
|||
[datasetProfileId]="datasetProfileId"
|
||||
[validationErrorModel]="editorModel.validationErrorModel"
|
||||
[validationRootPath]="selectedTocEntry.validationRootPath"
|
||||
(addNewFieldSet)="addNewEntry({childType: tocEntryEnumValues.FieldSet,parent: {formGroup: $event}})" (removeFieldSet)="onRemoveEntry(_findTocEntryById($event, toCEntries))" (cloneFieldSet)="cloneFieldSet($event)" (selectedEntryId)="displayItem(_findTocEntryById($event, toCEntries))" (dataNeedsRefresh)="onDataNeedsRefresh()"
|
||||
(addNewFieldSet)="addNewEntry({childType: tocEntryEnumValues.FieldSet,parent: {formGroup: $event}})" (removeFieldSet)="onRemoveEntry(_findTocEntryById($event, toCEntries))" (cloneFieldSet)="cloneFieldSet($event, selectedTocEntry.validationRootPath)" (selectedEntryId)="displayItem(_findTocEntryById($event, toCEntries))" (dataNeedsRefresh)="onDataNeedsRefresh()"
|
||||
>
|
||||
|
||||
</app-description-template-editor-section-fieldset-component>
|
||||
|
@ -305,7 +305,7 @@
|
|||
<div>
|
||||
<button mat-raised-button class="template_action_btn mr-3" (click)="cancel()">{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.CLOSE' | translate}}</button>
|
||||
<!-- <button *ngIf="!formGroup.disabled && formGroup.get('status').value!=1" [disabled]="!formGroup.valid" mat-raised-button class="template_action_btn save-btn" type="button"> -->
|
||||
<button *ngIf="!formGroup.disabled && formGroup.get('status').value!=finalized" mat-raised-button class="template_action_btn save-btn" type="button">
|
||||
<button [disabled]="!formGroup.valid" *ngIf="!formGroup.disabled && formGroup.get('status').value!=finalized" mat-raised-button class="template_action_btn save-btn" type="button">
|
||||
<span class="d-flex flex-row row">
|
||||
<span (click)="save(); formSubmit()" class="col">{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.SAVE' | translate}}</span>
|
||||
<mat-divider [vertical]="true"></mat-divider>
|
||||
|
@ -315,8 +315,8 @@
|
|||
</span>
|
||||
</button>
|
||||
<mat-menu #menuSave="matMenu">
|
||||
<button [disabled]="!formGroup.valid" mat-menu-item (click)="onSubmit(true)" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.SAVE-AND-CLOSE' | translate }}</button>
|
||||
<button [disabled]="!formGroup.valid" mat-menu-item (click)="onSubmit()" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.SAVE-AND-CONTINUE' | translate }}</button>
|
||||
<button [disabled]="!formGroup.valid" mat-menu-item (click)="saveWithClose(true)" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.SAVE-AND-CLOSE' | translate }}</button>
|
||||
<button [disabled]="!formGroup.valid" mat-menu-item (click)="saveWithClose(false)" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.SAVE-AND-CONTINUE' | translate }}</button>
|
||||
</mat-menu>
|
||||
|
||||
<!-- <button *ngIf="formGroup.disabled || formGroup.get('status').value==1" [@finalize_btn] mat-raised-button class="template_action_btn save-btn" [disabled]="!formGroup.valid" (click)="updateAndFinalize()">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
import { Component, OnInit, QueryList, ViewChild } from '@angular/core';
|
||||
import { FormArray, FormControl, UntypedFormArray, UntypedFormGroup } from '@angular/forms';
|
||||
import { FormArray, FormControl, FormGroup, UntypedFormArray, UntypedFormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
|
@ -71,6 +71,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
|||
selectedTocEntry: ToCEntry;
|
||||
colorizeInvalid: boolean = false;
|
||||
tocEntryEnumValues = ToCEntryType;
|
||||
close = false;
|
||||
|
||||
usersMap: Map<Guid, User> = new Map<Guid, User>();
|
||||
userFormControl = new FormControl();
|
||||
|
@ -199,7 +200,9 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
|||
refreshOnNavigateToData(id?: Guid): void {
|
||||
this.formGroup.markAsPristine();
|
||||
let route = [];
|
||||
|
||||
if(close){
|
||||
this.router.navigate(['/description-templates']);
|
||||
}
|
||||
if (id === null) {
|
||||
route.push('../..');
|
||||
} else if (this.isNew) {
|
||||
|
@ -241,6 +244,11 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
|||
this.persistEntity();
|
||||
}
|
||||
|
||||
saveWithClose(close: boolean){
|
||||
this.close = close;
|
||||
this.formSubmit();
|
||||
}
|
||||
|
||||
public delete() {
|
||||
const value = this.formGroup.value;
|
||||
if (value.id) {
|
||||
|
@ -1007,6 +1015,31 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
|||
|
||||
}
|
||||
|
||||
cloneFieldSet(fieldset: FormGroup, validationRootPath: string){
|
||||
const values = fieldset.getRawValue();
|
||||
const parentArray = fieldset.parent as FormArray;
|
||||
|
||||
values.id = Guid.create().toString();
|
||||
values.ordinal = parentArray.length;
|
||||
|
||||
values.fields.forEach(element => {
|
||||
element.id = Guid.create().toString()
|
||||
});
|
||||
|
||||
|
||||
const clonedModel = new DescriptionTemplateFieldSetEditorModel(this.editorModel.validationErrorModel).fromModel(values);
|
||||
const clonedForm = clonedModel.buildForm({rootPath: validationRootPath + '.fieldSets[' + parentArray.length + ']' + '.fields[' + 0 + '].'});
|
||||
parentArray.push(clonedForm);
|
||||
|
||||
//update tocentries and make selected tocentry the cloedn
|
||||
let entries = this.refreshToCEntries();
|
||||
|
||||
const entryfound = this._findTocEntryById(clonedForm.get('id').value, entries);
|
||||
if(entryfound){
|
||||
this.selectedTocEntry = entryfound;
|
||||
}
|
||||
}
|
||||
|
||||
private _updateSelectedItem(tce: ToCEntry) {
|
||||
|
||||
if (this.selectedTocEntry) {
|
||||
|
|
|
@ -229,7 +229,7 @@ export class DescriptionTemplateDefinitionEditorModel implements DescriptionTemp
|
|||
|
||||
const baseContext: ValidationContext = new ValidationContext();
|
||||
const baseValidationArray: Validation[] = new Array<Validation>();
|
||||
baseValidationArray.push({ key: 'pages', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}pages`)] });
|
||||
baseValidationArray.push({ key: 'pages', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}pages`)] });
|
||||
|
||||
baseContext.validation = baseValidationArray;
|
||||
return baseContext;
|
||||
|
|
Loading…
Reference in New Issue