From 8c8c9635d0a9db4721847de69065f8b93a8f293e Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 24 May 2023 10:53:04 -0400 Subject: [PATCH 1/2] allow comparing dates in json schema forms and also allow checking nested fields w/ burnettk --- .../src/routes/TaskShow.tsx | 71 +++++++++++++++---- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index 6f1407d5b..b50111d1f 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -167,6 +167,7 @@ export default function TaskShow() { if (disabled) { return; } + return; const dataToSubmit = formObject?.formData; if (!dataToSubmit) { @@ -270,32 +271,74 @@ export default function TaskShow() { formData: any, errors: any ) => { - if ('properties' in jsonSchema) { - Object.keys(jsonSchema.properties).forEach((propertyKey: string) => { - const propertyMetadata = jsonSchema.properties[propertyKey]; + // 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 ( typeof propertyMetadata === 'object' && - 'minimumDate' in propertyMetadata && - propertyMetadata.minimumDate === 'today' + 'minimumDate' in propertyMetadata ) { - 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 (propertyMetadata.minimumDate === 'today') { + const dateToday = new Date(); + const dateTodayString = dateToday.toISOString().split('T')[0]; + if (dateTodayString > dateValueString) { + errors[propertyKey].addError('must be today or after'); + } + } else if (propertyMetadata.minimumDate.startsWith('field:')) { + const fieldIdentifierToCompareWith = propertyMetadata.minimumDate + .split(':') + .slice(1) + .join(':'); + if (fieldIdentifierToCompareWith in formData) { + const dateToCompareWith = + formData[fieldIdentifierToCompareWith]; + const dateObjectToCompareWith = new Date(dateToCompareWith); + const dateStringToCompareWith = dateObjectToCompareWith + .toISOString() + .split('T')[0]; + if (dateToCompareWith) { + if (dateStringToCompareWith > dateValueString) { + errors[propertyKey].addError( + `this field must be equal to greater than '${fieldIdentifierToCompareWith}'` + ); + } + } else { + errors[propertyKey].addError( + `this field was supposed to be compared against '${fieldIdentifierToCompareWith}' but that field did not have a value` + ); + } + } else { + errors[propertyKey].addError( + `this field was supposed to be compared against '${fieldIdentifierToCompareWith}' but that field cannot be found` + ); + } } } } // 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; From de5f1550169a42d32689b96071677f03d5e7a6ba Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 24 May 2023 11:47:02 -0400 Subject: [PATCH 2/2] cleaned up comparing dates in forms w/ burnettk --- .../src/routes/TaskShow.tsx | 114 +++++++++++------- 1 file changed, 69 insertions(+), 45 deletions(-) diff --git a/spiffworkflow-frontend/src/routes/TaskShow.tsx b/spiffworkflow-frontend/src/routes/TaskShow.tsx index b50111d1f..af8f94464 100644 --- a/spiffworkflow-frontend/src/routes/TaskShow.tsx +++ b/spiffworkflow-frontend/src/routes/TaskShow.tsx @@ -167,7 +167,6 @@ export default function TaskShow() { if (disabled) { return; } - return; const dataToSubmit = formObject?.formData; if (!dataToSubmit) { @@ -266,10 +265,77 @@ 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 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 @@ -279,50 +345,8 @@ export default function TaskShow() { if ('properties' in jsonSchemaToUse) { Object.keys(jsonSchemaToUse.properties).forEach((propertyKey: string) => { const propertyMetadata = jsonSchemaToUse.properties[propertyKey]; - if ( - typeof propertyMetadata === 'object' && - 'minimumDate' in propertyMetadata - ) { - const dateValue = formData[propertyKey]; - if (dateValue) { - const dateValueObject = new Date(dateValue); - const dateValueString = dateValueObject.toISOString().split('T')[0]; - if (propertyMetadata.minimumDate === 'today') { - const dateToday = new Date(); - const dateTodayString = dateToday.toISOString().split('T')[0]; - if (dateTodayString > dateValueString) { - errors[propertyKey].addError('must be today or after'); - } - } else if (propertyMetadata.minimumDate.startsWith('field:')) { - const fieldIdentifierToCompareWith = propertyMetadata.minimumDate - .split(':') - .slice(1) - .join(':'); - if (fieldIdentifierToCompareWith in formData) { - const dateToCompareWith = - formData[fieldIdentifierToCompareWith]; - const dateObjectToCompareWith = new Date(dateToCompareWith); - const dateStringToCompareWith = dateObjectToCompareWith - .toISOString() - .split('T')[0]; - if (dateToCompareWith) { - if (dateStringToCompareWith > dateValueString) { - errors[propertyKey].addError( - `this field must be equal to greater than '${fieldIdentifierToCompareWith}'` - ); - } - } else { - errors[propertyKey].addError( - `this field was supposed to be compared against '${fieldIdentifierToCompareWith}' but that field did not have a value` - ); - } - } else { - errors[propertyKey].addError( - `this field was supposed to be compared against '${fieldIdentifierToCompareWith}' but that field cannot be found` - ); - } - } - } + if ('minimumDate' in propertyMetadata) { + checkMinimumDate(formData, propertyKey, propertyMetadata, errors); } // recurse through all nested properties as well