import { required , IValidationResult } from '@client/utils/validate' ; import { IFormField , IFormSectionData , IDynamicFormField , IFormData , RADIO_GROUP_WITH_NESTED_FIELDS } from '@client/forms' ; import { getConditionalActionsForField , getFieldValidation } from '@opencrvs/client/src/forms/utils' ; import { IOfflineData } from '@client/offline/reducer' ; import { MessageDescriptor } from 'react-intl' ; export interface IFieldErrors { errors : IValidationResult [ ] ; nestedFields : { [ fieldName ] : IValidationResult [ ] ; } ; } export type Errors = { [ fieldName ] : IFieldErrors ; } ; const getValidationErrors = { forField : function ( field , values , resources ? , drafts ? , requiredErrorMessage ? ) { const value = field . nestedFields && values [ field . name ] ? ( values [ field . name ] as IFormSectionData ) . value : values [ field . name ] ; const conditionalActions = getConditionalActionsForField ( field , values , resources , drafts ) ; if ( conditionalActions . includes ( 'hide' ) || conditionalActions . includes ( 'disable' ) ) { return { errors : [ ] , nestedFields : { } } ; } let validators = Array . from ( field . validate ) ; validators . push ( ... getFieldValidation ( field as IDynamicFormField , values ) ) ; if ( field . required ) { validators . push ( required ( requiredErrorMessage ) ) ; } else if ( ! value ) { validators = [ ] ; } const validationResults = validators . map ( ( validator ) => validator ( value , drafts , resources ) ) . filter ( ( error ) => error !== undefined ) as IValidationResult [ ] ; return { errors : validationResults , nestedFields : this . forNestedField ( field , values , resources , drafts , requiredErrorMessage ) } ; } , forNestedField : function ( field , values , resource ? , drafts ? , requiredErrorMessage ? ) : { [ fieldName ] : IValidationResult [ ] ; } { if ( field . type === RADIO_GROUP_WITH_NESTED_FIELDS ) { const parentValue = values [ field . name ] && ( values [ field . name ] as IFormSectionData ) . value ; const nestedFieldDefinitions = ( parentValue && field . nestedFields [ parentValue as string ] ) || [ ] ; return nestedFieldDefinitions . reduce ( ( nestedErrors , nestedField ) => { const errors = this . forField ( nestedField , ( values [ field . name ] as IFormSectionData ) . nestedFields as IFormSectionData , resource , drafts , requiredErrorMessage ) . errors ; return { ... nestedErrors , [ nestedField . name ] : errors } ; } , { } ) ; } return { } ; } } ; export function getValidationErrorsForForm ( fields , values , resource ? , drafts ? , requiredErrorMessage ? ) { return fields . reduce ( ( errorsForAllFields , field ) => errorsForAllFields [ field . name ] && errorsForAllFields [ field . name ] . errors . length > 0 ? errorsForAllFields : { ... errorsForAllFields , [ field . name ] : getValidationErrors . forField ( field , values , resource , drafts , requiredErrorMessage ) } , { } ) ; }