diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/SectionPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/SectionPersist.java index 0fa58deb2..e56da9699 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/SectionPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/SectionPersist.java @@ -160,7 +160,10 @@ public class SectionPersist { .iff(() -> !this.isListNullOrEmpty(item.getFieldSets())) .on(SectionPersist._fieldSets) .over(item.getFieldSets()) - .using((itm) -> this.validatorFactory.validator(FieldSetPersist.FieldSetPersistValidator.class)) + .using((itm) -> this.validatorFactory.validator(FieldSetPersist.FieldSetPersistValidator.class)), + this.spec() + .must(() -> !this.isListNullOrEmpty(item.getFieldSets()) || !this.isListNullOrEmpty(item.getSections())) + .failOn(SectionPersist._fieldSets).failWith(messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._fieldSets}, LocaleContextHolder.getLocale())) ); } } diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.model.ts b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.model.ts index d84c7ab45..b8a87d7c4 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.model.ts +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.model.ts @@ -12,6 +12,7 @@ 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"; import { Guid } from "@common/types/guid"; +import { EditorCustomValidators } from "./custom-validators/editor-custom-validators"; export class DescriptionTemplateEditorModel extends BaseEditorModel implements DescriptionTemplatePersist { label: string; @@ -399,7 +400,7 @@ export class DescriptionTemplateSectionEditorModel implements DescriptionTemplat }); } - return this.formBuilder.group({ + const formGroup= this.formBuilder.group({ id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators], ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal').validators], defaultVisibility: [{ value: this.defaultVisibility, disabled: disabled }, context.getValidation('defaultVisibility').validators], @@ -421,6 +422,10 @@ export class DescriptionTemplateSectionEditorModel implements DescriptionTemplat ), context.getValidation('fieldSets').validators ) }); + + formGroup.setValidators(EditorCustomValidators.sectionHasAtLeastOneChildOf('fieldSets','sections')); + + return formGroup; } static createValidationContext(params: { diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.html b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.html index 16c5b3fc5..bd8dae266 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.html @@ -39,8 +39,9 @@ {{'GENERAL.VALIDATION.REQUIRED' | translate}} -

{{'DMP-BLUEPRINT-EDITOR.FIELDS.SECTIONS' | translate}}

- +

{{'DMP-BLUEPRINT-EDITOR.FIELDS.SECTIONS' | translate}} + {{'DMP-BLUEPRINT-EDITOR.SYSTEM-FIELDS-REQUIRED' | translate}} +

diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.model.ts b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.model.ts index 6632f6e6d..ade0c6dbd 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.model.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.model.ts @@ -5,7 +5,7 @@ import { DmpBlueprintStatus } from "@app/core/common/enum/dmp-blueprint-status"; import { DmpBlueprintSystemFieldType } from "@app/core/common/enum/dmp-blueprint-system-field-type"; import { DescriptionTemplatesInSection, DescriptionTemplatesInSectionPersist, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionPersist, DmpBlueprintDefinitionSection, DmpBlueprintDefinitionSectionPersist, DmpBlueprintPersist, ExtraFieldInSection, FieldInSection, FieldInSectionPersist, ReferenceTypeFieldInSection, SystemFieldInSection } from "@app/core/model/dmp-blueprint/dmp-blueprint"; import { BaseEditorModel } from "@common/base/base-form-editor-model"; -import { BackendErrorValidator } from "@common/forms/validation/custom-validator"; +import { BackendErrorValidator, DmpBlueprintSystemFieldRequiredValidator } 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"; import { Guid } from "@common/types/guid"; @@ -142,7 +142,7 @@ export class DmpBlueprintDefinitionEditorModel implements DmpBlueprintDefinition const baseContext: ValidationContext = new ValidationContext(); const baseValidationArray: Validation[] = new Array(); - baseValidationArray.push({ key: 'sections', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}sections`)] }); + baseValidationArray.push({ key: 'sections', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}sections`), DmpBlueprintSystemFieldRequiredValidator()] }); baseContext.validation = baseValidationArray; return baseContext; diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 54b4451e7..c4f803dd3 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -1274,6 +1274,7 @@ }, "SECTIONS-REQUIRED": "Required", "FIELDS-REQUIRED": "Required", + "SYSTEM-FIELDS-REQUIRED": "Title and Description are required", "FIELDS": { "NAME": "Name", "SECTIONS": "Sections", diff --git a/dmp-frontend/src/common/forms/validation/custom-validator.ts b/dmp-frontend/src/common/forms/validation/custom-validator.ts index e8db1e8af..a3f0c4040 100644 --- a/dmp-frontend/src/common/forms/validation/custom-validator.ts +++ b/dmp-frontend/src/common/forms/validation/custom-validator.ts @@ -1,6 +1,7 @@ -import { AbstractControl, ValidatorFn, Validators } from '@angular/forms'; +import { AbstractControl, UntypedFormArray, UntypedFormGroup, ValidatorFn, Validators } from '@angular/forms'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; export function BackendErrorValidator(errorModel: ValidationErrorModel, propertyName: string): ValidatorFn { return (control: AbstractControl): { [key: string]: any } => { @@ -98,3 +99,27 @@ export function PasswordMatchValidator(passwordControlName: string, repeatPasswo return null; }; } + +export function DmpBlueprintSystemFieldRequiredValidator(): ValidatorFn { + return (control: AbstractControl): { [key: string]: any } => { + let foundTitle = false; + let foundDescription = false; + + const sectionsFormArray = (control as UntypedFormArray); + if (sectionsFormArray.controls != null && sectionsFormArray.controls.length > 0 ){ + sectionsFormArray.controls.forEach((section, index) => { + const fieldsFormArray = section.get('fields') as UntypedFormArray; + if (fieldsFormArray && fieldsFormArray.length > 0){ + if (fieldsFormArray.controls.some(y => (y as UntypedFormGroup).get('systemFieldType')?.value === DmpBlueprintSystemFieldType.Title)){ + foundTitle = true; + } + if (fieldsFormArray.controls.some(y => (y as UntypedFormGroup).get('systemFieldType')?.value === DmpBlueprintSystemFieldType.Description)){ + foundDescription = true; + } + } + }); + } + return foundTitle && foundDescription ? null : { 'dmpBlueprintSystemFieldRequired': true }; + + }; +}