Skip to content

Commit

Permalink
feat: display address extra errors
Browse files Browse the repository at this point in the history
  • Loading branch information
fterra-encora committed Sep 13, 2023
1 parent 9344a5d commit 48c1646
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 27 deletions.
79 changes: 54 additions & 25 deletions frontend/src/helpers/validators/ExternalFormValidations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,55 +204,84 @@ export const validate = (keys: string[], target: FormDataDto, notify: boolean =
}

// This function will run the validators and return the errors
export const runValidation = (key: string, target: FormDataDto, validation: (value: string) => string, notify: boolean = false, formErrors?: Record<string, string>): boolean => {
export const runValidation = (
key: string,
target: FormDataDto,
validation: (value: string) => string,
notify: boolean = false,
formErrors?: Record<string, ValidationMessageType>,
exhaustive = false,
): boolean => {
// We split the field key and the condition if it has one
const [fieldKey, fieldCondition] = key.includes('(')
? key.replace(')', '').split('(')
: [key, 'true']
// We then load the field value
const fieldValue = getField(fieldKey, target)
// We define a function that will run the validation if the condition is true
const buildEval = (condition: string) =>
condition === 'true' ? 'true' : `target.${condition}`
const executeValidation = (item: any, condition: string,fieldId: string = fieldKey) : string =>{
const buildEval = (condition: string) => (condition === 'true' ? 'true' : `target.${condition}`)
const executeValidation = (item: any, condition: string, fieldId: string = fieldKey): string => {
// eslint-disable-next-line no-eval
if(eval(condition)){
if (eval(condition)) {
const validationResponse = validation(item)
if(notify && validationResponse){
notificationBus.emit({fieldId,errorMsg:validationResponse}, item)
if (notify && validationResponse) {
notificationBus.emit({ fieldId, errorMsg: validationResponse }, item)
}
if(formErrors){
formErrors[fieldId] = validationResponse
if (formErrors) {
formErrors[fieldId] = {
fieldId,
errorMsg: validationResponse,
originalValue: item,
}
}
return validationResponse
}else{
} else {
return ''
}
}
// If the field value is an array we run the validation for every item in the array
if (Array.isArray(fieldValue)) {
return fieldValue.every((item: any, index: number) => {
let hasInvalidItem = false
for (let index = 0; index < fieldValue.length; index++) {
const item = fieldValue[index]
// And sometimes we can end up with another array inside, that's life
if (Array.isArray(item)) {
if (item.length === 0) item.push('')
return item.every((subItem: any) =>
executeValidation(
subItem,
buildEval(fieldCondition.replace('.*.', `[${index}].`)),
fieldKey.replace('.*.', `[${index}].`)
) === '',
)
let hasInvalidSubItem = false
for (const subItem of item) {
const valid =
executeValidation(
subItem,
buildEval(fieldCondition.replace('.*.', `[${index}].`)),
fieldKey.replace('.*.', `[${index}].`),
) === ''
if (!valid) {
hasInvalidSubItem = true
if (!exhaustive) {
break
}
}
}
return !hasInvalidSubItem
}
// If it is not an array here, just validate it
return executeValidation(
item,
buildEval(fieldCondition.replace('.*.', `[${index}].`)),
fieldKey.replace('.*.', `[${index}].`)
) === ''
})
const valid =
executeValidation(
item,
buildEval(fieldCondition.replace('.*.', `[${index}].`)),
fieldKey.replace('.*.', `[${index}].`),
) === ''
if (!valid) {
hasInvalidItem = true
if (!exhaustive) {
break
}
}
}
return !hasInvalidItem
}
// If the field value is not an array we run the validation for the field
return executeValidation(fieldValue, fieldCondition) === ''
return executeValidation(fieldValue, fieldCondition) === ''
}

export const addValidation = (key: string, validation: (value: string) => string): void => {
Expand Down
37 changes: 35 additions & 2 deletions frontend/src/pages/FormBCeIDPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,26 @@ let formData = reactive<FormDataDto>({
},
});
const formErrors = reactive<Record<string, string>>({})
const addressFieldStart = 'location.addresses['
const addressFieldEnd = '].locationName'
const ADDRESS_LOCATION_NAME_KEY = addressFieldStart + addressFieldEnd
const rawExtraErrors = reactive<Record<string, ValidationMessageType>>({})
const extraErrors = reactive<Record<string, any>>({
[ADDRESS_LOCATION_NAME_KEY]: []
})
watch(rawExtraErrors, () => {
const addressNameErrors: ValidationMessageType[] = []
for (const fieldId in rawExtraErrors) {
const message = rawExtraErrors[fieldId].errorMsg;
if(message && fieldId.startsWith(addressFieldStart) && fieldId.endsWith(addressFieldEnd)){
addressNameErrors.push(rawExtraErrors[fieldId])
}
}
extraErrors[ADDRESS_LOCATION_NAME_KEY] = addressNameErrors
})
const locations = computed(() =>
formData.location.addresses.map((address: any) => address.locationName)
Expand Down Expand Up @@ -209,7 +228,7 @@ const checkStepValidity = (stepNumber: number): boolean => {
if(!progressData[stepNumber]
.extraValidations
.every((validation: any) => runValidation(validation.field, formData, validation.validation, false, formErrors))
.every((validation: any) => runValidation(validation.field, formData, validation.validation, false, rawExtraErrors, true))
)
return false;
Expand Down Expand Up @@ -319,6 +338,20 @@ const reEval = () => (revalidateBus.emit())
</cds-progress-step>
</cds-progress-indicator>
<error-notification-grouping-component />
<cds-inline-notification
v-for="item in (extraErrors[ADDRESS_LOCATION_NAME_KEY] as ValidationMessageType[])"
:key="item"
v-shadow="true"
low-contrast="true"
hide-close-button="true"
open="true"
kind="error"
>
<p class="body-compact-01">
<span class="heading-compact-01 heading-compact-01-dark">Assigned contact required:</span>
You must associate <span class="heading-compact-01 heading-compact-01-dark">“{{ item.originalValue }}”</span> address with an existing contact or <a href="#">add a new contact</a> before submitting the application again.
</p>
</cds-inline-notification>
</div>

<div class="form-steps">
Expand Down

0 comments on commit 48c1646

Please sign in to comment.