Merge pull request #277 from sartography/feature/support_date_comparisons_in_forms

Feature/support date comparisons in forms
This commit is contained in:
jasquat 2023-05-24 11:48:52 -04:00 committed by GitHub
commit f1b8349c6e
1 changed files with 90 additions and 23 deletions

View File

@ -265,37 +265,104 @@ export default function TaskShow() {
return null;
};
const formatDateString = (dateString?: string) => {
let dateObject = new Date();
if (dateString) {
dateObject = new Date(dateString);
}
return dateObject.toISOString().split('T')[0];
};
const checkFieldComparisons = (
formData: any,
propertyKey: string,
propertyMetadata: any,
formattedDateString: string,
errors: any
) => {
const fieldIdentifierToCompareWith = propertyMetadata.minimumDate.replace(
/^field:/,
''
);
if (fieldIdentifierToCompareWith in formData) {
const dateToCompareWith = formData[fieldIdentifierToCompareWith];
if (dateToCompareWith) {
const dateStringToCompareWith = formatDateString(dateToCompareWith);
if (dateStringToCompareWith > formattedDateString) {
errors[propertyKey].addError(
`must be equal to or greater than '${fieldIdentifierToCompareWith}'`
);
}
} else {
errors[propertyKey].addError(
`was supposed to be compared against '${fieldIdentifierToCompareWith}' but that field did not have a value`
);
}
} else {
errors[propertyKey].addError(
`was supposed to be compared against '${fieldIdentifierToCompareWith}' but it either doesn't have a value or does not exist`
);
}
};
const checkMinimumDate = (
formData: any,
propertyKey: string,
propertyMetadata: any,
errors: any
) => {
const dateString = formData[propertyKey];
if (dateString) {
const formattedDateString = formatDateString(dateString);
if (propertyMetadata.minimumDate === 'today') {
const dateTodayString = formatDateString();
if (dateTodayString > formattedDateString) {
errors[propertyKey].addError('must be today or after');
}
} else if (propertyMetadata.minimumDate.startsWith('field:')) {
checkFieldComparisons(
formData,
propertyKey,
propertyMetadata,
formattedDateString,
errors
);
}
}
};
const getFieldsWithDateValidations = (
jsonSchema: any,
formData: any,
errors: any
// eslint-disable-next-line sonarjs/cognitive-complexity
) => {
if ('properties' in jsonSchema) {
Object.keys(jsonSchema.properties).forEach((propertyKey: string) => {
const propertyMetadata = jsonSchema.properties[propertyKey];
if (
typeof propertyMetadata === 'object' &&
'minimumDate' in propertyMetadata &&
propertyMetadata.minimumDate === 'today'
) {
const dateToday = new Date();
const dateValue = formData[propertyKey];
if (dateValue) {
const dateValueObject = new Date(dateValue);
const dateValueString = dateValueObject.toISOString().split('T')[0];
const dateTodayString = dateToday.toISOString().split('T')[0];
if (dateTodayString > dateValueString) {
errors[propertyKey].addError('must be today or after');
}
}
// if the jsonSchema has an items attribute then assume the element itself
// doesn't have a custom validation but it's children could so use that
const jsonSchemaToUse =
'items' in jsonSchema ? jsonSchema.items : jsonSchema;
if ('properties' in jsonSchemaToUse) {
Object.keys(jsonSchemaToUse.properties).forEach((propertyKey: string) => {
const propertyMetadata = jsonSchemaToUse.properties[propertyKey];
if ('minimumDate' in propertyMetadata) {
checkMinimumDate(formData, propertyKey, propertyMetadata, errors);
}
// recurse through all nested properties as well
getFieldsWithDateValidations(
propertyMetadata,
formData[propertyKey],
errors[propertyKey]
);
let formDataToSend = formData[propertyKey];
if (formDataToSend) {
if (formDataToSend.constructor.name !== 'Array') {
formDataToSend = [formDataToSend];
}
formDataToSend.forEach((item: any, index: number) => {
let errorsToSend = errors[propertyKey];
if (index in errorsToSend) {
errorsToSend = errorsToSend[index];
}
getFieldsWithDateValidations(propertyMetadata, item, errorsToSend);
});
}
});
}
return errors;