diff --git a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/notificationtemplate/NotificationTemplateValuePersist.java b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/notificationtemplate/NotificationTemplateValuePersist.java index 4768488e2..028dc6fa7 100644 --- a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/notificationtemplate/NotificationTemplateValuePersist.java +++ b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/notificationtemplate/NotificationTemplateValuePersist.java @@ -205,7 +205,7 @@ public class NotificationTemplateValuePersist { .must(() -> !this.isNull(item.getAllowAttachments())) .failOn(NotificationTemplateValuePersist._allowAttachments).failWith(messageSource.getMessage("Validation_Required", new Object[]{NotificationTemplateValuePersist._allowAttachments}, LocaleContextHolder.getLocale())), this.spec() - .must(() -> !this.isNull(item.getPriorityKey())) + .must(() -> !this.isEmpty(item.getPriorityKey())) .failOn(NotificationTemplateValuePersist._priorityKey).failWith(messageSource.getMessage("Validation_Required", new Object[]{NotificationTemplateValuePersist._priorityKey}, LocaleContextHolder.getLocale())), this.spec() .must(() -> !this.isNull(item.getCcMode())) diff --git a/dmp-frontend/src/app/core/model/contact/contact-support-form-model.ts b/dmp-frontend/src/app/core/model/contact/contact-support-form-model.ts index 10c76e52d..eec01a950 100644 --- a/dmp-frontend/src/app/core/model/contact/contact-support-form-model.ts +++ b/dmp-frontend/src/app/core/model/contact/contact-support-form-model.ts @@ -1,5 +1,7 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; +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"; export interface ContactSupportPersist{ subject: string, @@ -25,10 +27,21 @@ export class ContactEmailFormModel implements ContactSupportPersist{ } buildForm(): UntypedFormGroup { + const context = this.createValidationContext(); const formGroup = new UntypedFormBuilder().group({ - subject: [this.subject, [Validators.required]], - description: [this.description, [Validators.required]] + subject: [this.subject, context.getValidation('subject').validators], + description: [this.description, context.getValidation('description').validators] }); return formGroup; } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'subject', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'subject')] }); + baseValidationArray.push({ key: 'description', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'description')] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } } 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 673ab26af..619249fc6 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 @@ -1,4 +1,4 @@ -import { FormControl, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; +import { FormArray, FormControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { DescriptionTemplateFieldAutocompleteType } from "@app/core/common/enum/description-template-field-autocomplete-type"; import { DescriptionTemplateFieldType } from "@app/core/common/enum/description-template-field-type"; import { DescriptionTemplateFieldValidationType } from "@app/core/common/enum/description-template-field-validation-type"; @@ -17,7 +17,7 @@ export class DescriptionTemplateEditorModel extends BaseEditorModel implements D description: string; language: string; type: Guid; - status: DescriptionTemplateStatus = DescriptionTemplateStatus.Draft; + status: DescriptionTemplateStatus = DescriptionTemplateStatus.Finalized; //TODO CHANGE TO DRAFT definition: DescriptionTemplateDefinitionEditorModel = new DescriptionTemplateDefinitionEditorModel(); users: UserDescriptionTemplateEditorModel[] = []; permissions: string[]; @@ -35,7 +35,7 @@ export class DescriptionTemplateEditorModel extends BaseEditorModel implements D this.language = item.language; this.type = item.type?.id; this.status = item.status; - this.definition = new DescriptionTemplateDefinitionEditorModel().fromModel(item.definition); + this.definition = new DescriptionTemplateDefinitionEditorModel(this.validationErrorModel).fromModel(item.definition); if (item.users) { item.users.map(x => this.users.push(new UserDescriptionTemplateEditorModel().fromModel(x))); } } return this; @@ -83,6 +83,35 @@ export class DescriptionTemplateEditorModel extends BaseEditorModel implements D baseContext.validation = baseValidationArray; return baseContext; } + + static reApplyDefinitionValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + }): void { + + const { formGroup, validationErrorModel } = params; + const control = formGroup?.get('definition'); + DescriptionTemplateDefinitionEditorModel.reapplyPagesValidators({ + formArray: control.get('pages') as UntypedFormArray, + rootPath: `definition.`, + validationErrorModel: validationErrorModel + }); + + DescriptionTemplateDefinitionEditorModel.reapplySectionsValidators({ + formArray: control.get('sections') as UntypedFormArray, + rootPath: `definition.`, + validationErrorModel: validationErrorModel + }); + + (formGroup.get('users') as FormArray).controls?.forEach( + (control, index) => UserDescriptionTemplateEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `users[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + } + } export class UserDescriptionTemplateEditorModel implements UserDescriptionTemplatePersist { @@ -137,6 +166,25 @@ export class UserDescriptionTemplateEditorModel implements UserDescriptionTempla return baseContext; } + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = UserDescriptionTemplateEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['userId', 'role'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } + } export class DescriptionTemplateDefinitionEditorModel implements DescriptionTemplateDefinitionPersist { @@ -151,8 +199,8 @@ export class DescriptionTemplateDefinitionEditorModel implements DescriptionTemp public fromModel(item: DescriptionTemplateDefinition): DescriptionTemplateDefinitionEditorModel { if (item) { - if (item.pages) { item.pages.map(x => this.pages.push(new DescriptionTemplatePageEditorModel().fromModel(x))); } - if (item.sections) { item.sections.map(x => this.sections.push(new DescriptionTemplateSectionEditorModel().fromModel(x))); } + if (item.pages) { item.pages.map(x => this.pages.push(new DescriptionTemplatePageEditorModel(this.validationErrorModel).fromModel(x))); } + if (item.sections) { item.sections.map(x => this.sections.push(new DescriptionTemplateSectionEditorModel(this.validationErrorModel).fromModel(x))); } } return this; } @@ -176,7 +224,7 @@ export class DescriptionTemplateDefinitionEditorModel implements DescriptionTemp (item, index) => new DescriptionTemplatePageEditorModel( this.validationErrorModel ).fromModel(item).buildForm({ - rootPath: `pages[${index}].` + rootPath: `${rootPath}pages[${index}].` }), context.getValidation('pages') ) ), @@ -185,7 +233,7 @@ export class DescriptionTemplateDefinitionEditorModel implements DescriptionTemp (item, index) => new DescriptionTemplateSectionEditorModel( this.validationErrorModel ).fromModel(item).buildForm({ - rootPath: `sections[${index}].` + rootPath: `${rootPath}sections[${index}].` }), context.getValidation('sections') ) ), @@ -207,6 +255,36 @@ export class DescriptionTemplateDefinitionEditorModel implements DescriptionTemp return baseContext; } + static reapplyPagesValidators(params: { + formArray: UntypedFormArray, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + const { validationErrorModel, rootPath, formArray } = params; + formArray?.controls?.forEach( + (control, index) => DescriptionTemplatePageEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}pages[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + } + + static reapplySectionsValidators(params: { + formArray: UntypedFormArray, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + const { validationErrorModel, rootPath, formArray } = params; + formArray?.controls?.forEach( + (control, index) => DescriptionTemplateSectionEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}sections[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + } + } export class DescriptionTemplatePageEditorModel implements DescriptionTemplatePagePersist { @@ -265,6 +343,25 @@ export class DescriptionTemplatePageEditorModel implements DescriptionTemplatePa return baseContext; } + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplatePageEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['id', 'ordinal', 'title'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } + } export class DescriptionTemplateSectionEditorModel implements DescriptionTemplateSectionPersist { @@ -293,8 +390,8 @@ export class DescriptionTemplateSectionEditorModel implements DescriptionTemplat this.page = item.page; this.title = item.title; this.description = item.description; - if (item.sections) { item.sections.map(x => this.sections.push(new DescriptionTemplateSectionEditorModel().fromModel(x))); } - if (item.fieldSets) { item.fieldSets.map(x => this.fieldSets.push(new DescriptionTemplateFieldSetEditorModel().fromModel(x))); } + if (item.sections) { item.sections.map(x => this.sections.push(new DescriptionTemplateSectionEditorModel(this.validationErrorModel).fromModel(x))); } + if (item.fieldSets) { item.fieldSets.map(x => this.fieldSets.push(new DescriptionTemplateFieldSetEditorModel(this.validationErrorModel).fromModel(x))); } } return this; } @@ -325,7 +422,7 @@ export class DescriptionTemplateSectionEditorModel implements DescriptionTemplat (item, index) => new DescriptionTemplateSectionEditorModel( this.validationErrorModel ).fromModel(item).buildForm({ - rootPath: `sections[${index}].` + rootPath: `${rootPath}sections[${index}].` }), context.getValidation('sections') ) ), @@ -334,7 +431,7 @@ export class DescriptionTemplateSectionEditorModel implements DescriptionTemplat (item, index) => new DescriptionTemplateFieldSetEditorModel( this.validationErrorModel ).fromModel(item).buildForm({ - rootPath: `fieldSets[${index}].` + rootPath: `${rootPath}fieldSets[${index}].` }), context.getValidation('fieldSets') ) ) @@ -363,6 +460,41 @@ export class DescriptionTemplateSectionEditorModel implements DescriptionTemplat return baseContext; } + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateSectionEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['id', 'ordinal', 'defaultVisibility', 'multiplicity', 'page', 'title', 'description'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }); + + (formGroup.get('sections') as FormArray).controls?.forEach( + (control, index) => DescriptionTemplateSectionEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}sections[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + + (formGroup.get('fieldSets') as FormArray).controls?.forEach( + (control, index) => DescriptionTemplateFieldSetEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}fieldSets[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + } + } export class DescriptionTemplateFieldSetEditorModel implements DescriptionTemplateFieldSetPersist { @@ -394,8 +526,8 @@ export class DescriptionTemplateFieldSetEditorModel implements DescriptionTempla this.additionalInformation = item.additionalInformation; this.hasCommentField = item.hasCommentField; - this.multiplicity = new DescriptionTemplateMultiplicityEditorModel().fromModel(item.multiplicity); - if (item.fields) { item.fields.map(x => this.fields.push(new DescriptionTemplateFieldEditorModel().fromModel(x))); } + this.multiplicity = new DescriptionTemplateMultiplicityEditorModel(this.validationErrorModel).fromModel(item.multiplicity); + if (item.fields) { item.fields.map(x => this.fields.push(new DescriptionTemplateFieldEditorModel(this.validationErrorModel).fromModel(x))); } } return this; } @@ -423,14 +555,14 @@ export class DescriptionTemplateFieldSetEditorModel implements DescriptionTempla additionalInformation: [{ value: this.additionalInformation, disabled: disabled }, context.getValidation('additionalInformation').validators], hasCommentField: [{ value: this.hasCommentField, disabled: disabled }, context.getValidation('hasCommentField').validators], multiplicity: this.multiplicity.buildForm({ - rootPath: `multiplicity.` + rootPath: `${rootPath}multiplicity.` }), fields: this.formBuilder.array( (this.fields ?? []).map( (item, index) => new DescriptionTemplateFieldEditorModel( this.validationErrorModel ).fromModel(item).buildForm({ - rootPath: `fields[${index}].` + rootPath: `${rootPath}fields[${index}].` }), context.getValidation('fields') ) ) @@ -458,6 +590,39 @@ export class DescriptionTemplateFieldSetEditorModel implements DescriptionTempla baseContext.validation = baseValidationArray; return baseContext; } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateFieldSetEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['id', 'ordinal', 'numbering', 'title', 'description', 'extendedDescription', 'additionalInformation', 'hasCommentField'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }); + + DescriptionTemplateMultiplicityEditorModel.reapplyValidators({ + formGroup: formGroup?.get('multiplicity') as UntypedFormGroup, + rootPath: `${rootPath}multiplicity.`, + validationErrorModel: validationErrorModel + }); + + (formGroup.get('fields') as FormArray).controls?.forEach( + (control, index) => DescriptionTemplateFieldEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}fields[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + } } export class DescriptionTemplateMultiplicityEditorModel implements DescriptionTemplateMultiplicityPersist { @@ -519,6 +684,25 @@ export class DescriptionTemplateMultiplicityEditorModel implements DescriptionTe baseContext.validation = baseValidationArray; return baseContext; } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateMultiplicityEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['min', 'max', 'placeholder', 'tableView'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } } // @@ -552,7 +736,7 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF this.includeInExport = item.includeInExport; this.data = this.getFieldEditorModel(item.data.fieldType).fromModel(item.data); - if (item.visibilityRules) { item.visibilityRules.map(x => this.visibilityRules.push(new DescriptionTemplateRuleEditorModel().fromModel(x))); } + if (item.visibilityRules) { item.visibilityRules.map(x => this.visibilityRules.push(new DescriptionTemplateRuleEditorModel(this.validationErrorModel).fromModel(x))); } } return this; } @@ -578,14 +762,14 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF validations: [{ value: this.validations, disabled: disabled }, context.getValidation('validations').validators], includeInExport: [{ value: this.includeInExport, disabled: disabled }, context.getValidation('includeInExport').validators], data: this.data.buildForm({ - rootPath: `data.` + rootPath: `${rootPath}data.` }), visibilityRules: this.formBuilder.array( (this.visibilityRules ?? []).map( (item, index) => new DescriptionTemplateRuleEditorModel( this.validationErrorModel ).fromModel(item).buildForm({ - rootPath: `visibilityRules[${index}].` + rootPath: `${rootPath}visibilityRules[${index}].` }), context.getValidation('visibilityRules') ) ) @@ -615,11 +799,11 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF private getFieldEditorModel(fieldType: DescriptionTemplateFieldType): DescriptionTemplateBaseFieldEditorModel { switch (fieldType) { case DescriptionTemplateFieldType.AUTO_COMPLETE: - return new DescriptionTemplateAutoCompleteFieldEditorModel(); + return new DescriptionTemplateAutoCompleteFieldEditorModel(this.validationErrorModel); case DescriptionTemplateFieldType.RADIO_BOX: - return new DescriptionTemplateRadioBoxFieldEditorModel(); + return new DescriptionTemplateRadioBoxFieldEditorModel(this.validationErrorModel); case DescriptionTemplateFieldType.WORD_LIST: - return new DescriptionTemplateRadioBoxFieldEditorModel(); + return new DescriptionTemplateRadioBoxFieldEditorModel(this.validationErrorModel); case DescriptionTemplateFieldType.BOOLEAN_DECISION: case DescriptionTemplateFieldType.CHECK_BOX: case DescriptionTemplateFieldType.FREE_TEXT: @@ -630,7 +814,7 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF case DescriptionTemplateFieldType.DATASET_IDENTIFIER: case DescriptionTemplateFieldType.CURRENCY: case DescriptionTemplateFieldType.VALIDATION: - return new DescriptionTemplateBaseFieldEditorModel(); + return new DescriptionTemplateBaseFieldEditorModel(this.validationErrorModel); case DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES_RESEARCHERS: case DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES_DMPS: case DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES_DATASETS: @@ -645,11 +829,44 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF case DescriptionTemplateFieldType.SERVICES: case DescriptionTemplateFieldType.RESEARCHERS: case DescriptionTemplateFieldType.ORGANIZATIONS: - return new DescriptionTemplatePlaceholderAndMultiplicityFieldEditorModel(); + return new DescriptionTemplatePlaceholderAndMultiplicityFieldEditorModel(this.validationErrorModel); case DescriptionTemplateFieldType.UPLOAD: - return new DescriptionTemplateUploadFieldEditorModel(); + return new DescriptionTemplateUploadFieldEditorModel(this.validationErrorModel); } } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateFieldEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['id', 'ordinal', 'schematics', 'defaultValue', 'validations', 'includeInExport'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }); + + DescriptionTemplateBaseFieldEditorModel.reapplyBaseFieldValidators({ + formGroup: formGroup?.get('data') as UntypedFormGroup, + rootPath: `${rootPath}data.`, + validationErrorModel: validationErrorModel + }); + + (formGroup.get('visibilityRules') as FormArray).controls?.forEach( + (control, index) => DescriptionTemplateRuleEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}visibilityRules[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + } } export class DescriptionTemplateBaseFieldEditorModel implements DescriptionTemplateBaseFieldDataPersist { @@ -702,6 +919,25 @@ export class DescriptionTemplateBaseFieldEditorModel implements DescriptionTempl baseContext.validation = baseValidationArray; return baseContext; } + + static reapplyBaseFieldValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateBaseFieldEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['label', 'fieldType'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } } export class DescriptionTemplatePlaceholderAndMultiplicityFieldEditorModel extends DescriptionTemplateBaseFieldEditorModel implements DescriptionTemplatePlaceholderAndMultiplicityDataPersist { @@ -747,6 +983,25 @@ export class DescriptionTemplatePlaceholderAndMultiplicityFieldEditorModel exten baseContext.validation.push({ key: 'multiAutoComplete', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}multiAutoComplete`)] }); return baseContext; } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplatePlaceholderAndMultiplicityFieldEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['multiAutoComplete'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } } // @@ -767,7 +1022,7 @@ export class DescriptionTemplateAutoCompleteFieldEditorModel extends Description if (item) { super.fromModel(item); this.multiAutoComplete = item.multiAutoComplete; - if (item.autoCompleteSingleDataList) { item.autoCompleteSingleDataList.map(x => this.autoCompleteSingleDataList.push(new DescriptionTemplateAutoCompleteSingleDataEditorModel().fromModel(x))); } + if (item.autoCompleteSingleDataList) { item.autoCompleteSingleDataList.map(x => this.autoCompleteSingleDataList.push(new DescriptionTemplateAutoCompleteSingleDataEditorModel(this.validationErrorModel).fromModel(x))); } } return this; } @@ -792,7 +1047,7 @@ export class DescriptionTemplateAutoCompleteFieldEditorModel extends Description (item, index) => new DescriptionTemplateAutoCompleteSingleDataEditorModel( this.validationErrorModel ).fromModel(item).buildForm({ - rootPath: `autoCompleteSingleDataList[${index}].` + rootPath: `${rootPath}autoCompleteSingleDataList[${index}].` }), context.getValidation('autoCompleteSingleDataList') ))); return formGroup; @@ -808,6 +1063,34 @@ export class DescriptionTemplateAutoCompleteFieldEditorModel extends Description baseContext.validation.push({ key: 'autoCompleteSingleDataList', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}autoCompleteSingleDataList`)] }); return baseContext; } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateAutoCompleteFieldEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['multiAutoComplete'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }); + + (formGroup.get('options') as FormArray).controls?.forEach( + (control, index) => DescriptionTemplateAutoCompleteSingleDataEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}autoCompleteSingleDataList[${index}].`, + validationErrorModel: validationErrorModel + } + ) + ); + } } export class DescriptionTemplateAutoCompleteSingleDataEditorModel implements DescriptionTemplateAutoCompleteSingleDataPersist { @@ -828,10 +1111,10 @@ export class DescriptionTemplateAutoCompleteSingleDataEditorModel implements Des if (item) { this.autocompleteType = item.autocompleteType; this.url = item.url; - this.autoCompleteOptions = new DescriptionTemplateComboBoxOptionEditorModel().fromModel(item.autoCompleteOptions); + this.autoCompleteOptions = new DescriptionTemplateComboBoxOptionEditorModel(this.validationErrorModel).fromModel(item.autoCompleteOptions); this.optionsRoot = item.optionsRoot; this.hasAuth = item.hasAuth; - this.auth = new DescriptionTemplateAuthAutoCompleteDataEditorModel().fromModel(item.auth); + this.auth = new DescriptionTemplateAuthAutoCompleteDataEditorModel(this.validationErrorModel).fromModel(item.auth); this.method = item.method; } return this; @@ -857,10 +1140,10 @@ export class DescriptionTemplateAutoCompleteSingleDataEditorModel implements Des hasAuth: [{ value: this.hasAuth, disabled: disabled }, context.getValidation('hasAuth').validators], method: [{ value: this.method, disabled: disabled }, context.getValidation('method').validators], autoCompleteOptions: this.autoCompleteOptions.buildForm({ - rootPath: `autoCompleteOptions.` + rootPath: `${rootPath}autoCompleteOptions.` }), auth: this.auth.buildForm({ - rootPath: `auth.` + rootPath: `${rootPath}auth.` }), }); } @@ -886,6 +1169,38 @@ export class DescriptionTemplateAutoCompleteSingleDataEditorModel implements Des baseContext.validation = baseValidationArray; return baseContext; } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateAutoCompleteSingleDataEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['autocompleteType', 'url', 'optionsRoot', 'hasAuth', 'method'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }); + + DescriptionTemplateComboBoxOptionEditorModel.reapplyValidators({ + formGroup: formGroup?.get('autoCompleteOptions') as UntypedFormGroup, + rootPath: `${rootPath}autoCompleteOptions.`, + validationErrorModel: validationErrorModel + }); + + DescriptionTemplateComboBoxOptionEditorModel.reapplyValidators({ + formGroup: formGroup?.get('auth') as UntypedFormGroup, + rootPath: `${rootPath}auth.`, + validationErrorModel: validationErrorModel + }); + + } } export class DescriptionTemplateComboBoxOptionEditorModel implements DescriptionTemplateComboBoxOptionPersist { @@ -946,6 +1261,25 @@ export class DescriptionTemplateComboBoxOptionEditorModel implements Description baseContext.validation = baseValidationArray; return baseContext; } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateComboBoxOptionEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['label', 'value', 'source', 'uri'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } } export class DescriptionTemplateAuthAutoCompleteDataEditorModel implements DescriptionTemplateAuthAutoCompleteDataPersist { @@ -1010,6 +1344,25 @@ export class DescriptionTemplateAuthAutoCompleteDataEditorModel implements Descr baseContext.validation = baseValidationArray; return baseContext; } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateAuthAutoCompleteDataEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['url', 'method', 'body', 'path', 'type'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } } // @@ -1028,7 +1381,7 @@ export class DescriptionTemplateRadioBoxFieldEditorModel extends DescriptionTemp fromModel(item: DescriptionTemplateRadioBoxDataPersist): DescriptionTemplateRadioBoxFieldEditorModel { if (item) { super.fromModel(item); - if (item.options) { item.options.map(x => this.options.push(new DescriptionTemplateRadioBoxDataEditorModel().fromModel(x))); } + if (item.options) { item.options.map(x => this.options.push(new DescriptionTemplateRadioBoxDataEditorModel(this.validationErrorModel).fromModel(x))); } } return this; } @@ -1052,7 +1405,7 @@ export class DescriptionTemplateRadioBoxFieldEditorModel extends DescriptionTemp (item, index) => new DescriptionTemplateRadioBoxDataEditorModel( this.validationErrorModel ).fromModel(item).buildForm({ - rootPath: `options[${index}].` + rootPath: `${rootPath}options[${index}].` }), context.getValidation('options') ))); return formGroup; @@ -1067,6 +1420,21 @@ export class DescriptionTemplateRadioBoxFieldEditorModel extends DescriptionTemp baseContext.validation.push({ key: 'options', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}options`)] }); return baseContext; } + + static reapplyRadioBoxValidators(params: { + formArray: UntypedFormArray, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + const { validationErrorModel, rootPath, formArray } = params; + formArray?.controls?.forEach( + (control, index) => DescriptionTemplateRadioBoxDataEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}options[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + } } export class DescriptionTemplateRadioBoxDataEditorModel implements DescriptionTemplateRadioBoxOptionPersist { @@ -1119,6 +1487,25 @@ export class DescriptionTemplateRadioBoxDataEditorModel implements DescriptionTe baseContext.validation = baseValidationArray; return baseContext; } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateRadioBoxDataEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['label', 'value'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } } // @@ -1139,7 +1526,7 @@ export class DescriptionTemplateWordListFieldEditorModel extends DescriptionTemp if (item) { super.fromModel(item); this.multiList = item.multiList; - if (item.options) { item.options.map(x => this.options.push(new DescriptionTemplateComboBoxOptionEditorModel().fromModel(x))); } + if (item.options) { item.options.map(x => this.options.push(new DescriptionTemplateComboBoxOptionEditorModel(this.validationErrorModel).fromModel(x))); } } return this; } @@ -1164,7 +1551,7 @@ export class DescriptionTemplateWordListFieldEditorModel extends DescriptionTemp (item, index) => new DescriptionTemplateComboBoxOptionEditorModel( this.validationErrorModel ).fromModel(item).buildForm({ - rootPath: `options[${index}].` + rootPath: `${rootPath}options[${index}].` }), context.getValidation('options') ))); return formGroup; @@ -1180,6 +1567,33 @@ export class DescriptionTemplateWordListFieldEditorModel extends DescriptionTemp baseContext.validation.push({ key: 'multiList', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}multiList`)] }); return baseContext; } + + static reapplyDepedencyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateWordListFieldEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['multiList'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }); + + (formGroup.get('options') as FormArray).controls?.forEach( + (control, index) => DescriptionTemplateComboBoxOptionEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}options[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + } } // @@ -1198,7 +1612,7 @@ export class DescriptionTemplateUploadFieldEditorModel extends DescriptionTempla fromModel(item: DescriptionTemplateUploadDataPersist): DescriptionTemplateUploadFieldEditorModel { if (item) { super.fromModel(item); - if (item.types) { item.types.map(x => this.types.push(new DescriptionTemplateUploadOptionEditorModel().fromModel(x))); } + if (item.types) { item.types.map(x => this.types.push(new DescriptionTemplateUploadOptionEditorModel(this.validationErrorModel).fromModel(x))); } } return this; } @@ -1222,7 +1636,7 @@ export class DescriptionTemplateUploadFieldEditorModel extends DescriptionTempla (item, index) => new DescriptionTemplateUploadOptionEditorModel( this.validationErrorModel ).fromModel(item).buildForm({ - rootPath: `types[${index}].` + rootPath: `${rootPath}types[${index}].` }), context.getValidation('types') ))); return formGroup; @@ -1237,6 +1651,22 @@ export class DescriptionTemplateUploadFieldEditorModel extends DescriptionTempla baseContext.validation.push({ key: 'types', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}types`)] }); return baseContext; } + + static reapplyUploadDataValidators(params: { + formArray: UntypedFormArray, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { validationErrorModel, rootPath, formArray } = params; + formArray?.controls?.forEach( + (control, index) => DescriptionTemplateUploadOptionEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}types[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + } } export class DescriptionTemplateUploadOptionEditorModel implements DescriptionTemplateUploadOptionPersist { @@ -1289,6 +1719,25 @@ export class DescriptionTemplateUploadOptionEditorModel implements DescriptionTe baseContext.validation = baseValidationArray; return baseContext; } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateUploadOptionEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['label', 'value'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } } export class DescriptionTemplateRuleEditorModel implements DescriptionTemplateRulePersist { @@ -1342,4 +1791,23 @@ export class DescriptionTemplateRuleEditorModel implements DescriptionTemplateRu baseContext.validation = baseValidationArray; return baseContext; } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateRuleEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['target', 'value'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/tenant/editor/tenant-editor.component.html b/dmp-frontend/src/app/ui/admin/tenant/editor/tenant-editor.component.html index 01d1ea236..77382a90d 100644 --- a/dmp-frontend/src/app/ui/admin/tenant/editor/tenant-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/tenant/editor/tenant-editor.component.html @@ -118,10 +118,10 @@ {{'TENANT-EDITOR.FIELDS.CODES' | translate}} - + (edited)="editDepositCode(code, $event, sourceIndex)"> {{code}}