Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Reason for delayed registration in v2 birth #8533

Merged
merged 14 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,10 @@ class FormSectionComponent extends React.Component<AllProps> {
...field,
id: field.id.replaceAll('.', FIELD_SEPARATOR)
}))
const valuesWithFormattedDate = getValuesWithFormattedDate(
fieldsWithDotIds,
values
)

return (
<section>
Expand All @@ -477,7 +481,9 @@ class FormSectionComponent extends React.Component<AllProps> {
const conditionalActions: string[] = getConditionalActionsForField(
field,
{
$form: makeFormikFieldIdsOpenCRVSCompatible(values),
$form: makeFormikFieldIdsOpenCRVSCompatible(
valuesWithFormattedDate
),
$now: formatISO(new Date(), { representation: 'date' })
}
)
Expand Down Expand Up @@ -548,6 +554,36 @@ function makeFormikFieldIdsOpenCRVSCompatible<T>(data: Record<string, T>) {
])
)
}
/**
*
* @param fields field config in OpenCRVS format (separated with `.`)
* @param values form values in formik format (separated with `FIELD_SEPARATOR`)
* @returns adds 0 before single digit days and months to make them 2 digit
* @because ajv's `formatMaximum` and `formatMinimum` does not allow single digit day or months
*/
function getValuesWithFormattedDate(
Copy link
Collaborator

@makelicious makelicious Jan 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appreciate the comment 🙏 @ because might not be supported. It seems that we are going through all the values but only touching one. Would there be more specific names to functions, or could the implementation be more generic?

fields: FieldConfig[],
values: Record<string, FieldValue>
) {
return fields.reduce(
(acc, field) => {
const fieldId = field.id.replaceAll('.', FIELD_SEPARATOR)

if (field.type === 'DATE' && fieldId in values) {
const value = values[fieldId as keyof typeof values]
if (typeof value === 'string') {
const formattedDate = value
.split('-')
.map((d: string) => d.padStart(2, '0'))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens to years here? Could you move this under utils.ts next to FormFieldGenerator? We could write test cases under utils.test.ts and run this function with different values.

I think with -- this returns 00-00-00

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid years are always of four digits. So, if there is a year which is of less than two digits, it should be considered invalid. In that sense, we don't need to make it four digits. What do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, let me rephrase.

Could we write few test cases for this function. If I understand correctly, it receives values from formik. Formik DateField returns a string. When DATE input is empty, '--' is returned.

When we are building on top of that, I'm more worried that the functionality goes undocumented. Tests could help us there if we are not changing DateField behavior.

Pseudocode:

const cases = [
{
   expected: '--',
   actual: // whatever you expect
},
{
   expected: '01-02-',
   actual: // whatever you expect
},
{
   expected: '1-2-3',
   actual: // whatever you expect
},
{
   expected: '01-2-32',
   actual: // whatever you expect
},
...,
];


cases.forEach((case) => {
 // or snapshot if you prefer
  expect(case.input).toBe(case.output)
})

.join('-')
acc[fieldId] = formattedDate
}
}
return acc
},
{ ...values }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this does not need to be destructured. Let's aim that we don't mutate as a principle

)
}

export const FormFieldGenerator: React.FC<ExposedProps> = (props) => {
const intl = useIntl()
Expand All @@ -569,7 +605,9 @@ export const FormFieldGenerator: React.FC<ExposedProps> = (props) => {
validate={(values) =>
getValidationErrorsForForm(
props.fields,
makeFormikFieldIdsOpenCRVSCompatible(values),
makeFormikFieldIdsOpenCRVSCompatible(
getValuesWithFormattedDate(props.fields, values)
),
props.requiredErrorMessage
)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/toolkit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@opencrvs/toolkit",
"version": "0.0.32-jr",
"version": "0.0.33-jr",
"description": "OpenCRVS toolkit for building country configurations",
"license": "MPL-2.0",
"exports": {
Expand Down
49 changes: 49 additions & 0 deletions packages/toolkit/src/conditionals/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,14 @@ export function eventHasAction(type: ActionDocument['type']) {
export type FieldAPI = {
inArray: (values: string[]) => FieldAPI
isBeforeNow: () => FieldAPI
/**
* Checks if the date is within `days` days in the past from now.
*/
isAfter: (days: number) => FieldAPI
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could inPast work? Then possible inFuture would work. (or
Would it make isBeforeNow -> isPast?
Something that would work both ways and we could unify the terms under.

daysInPast daysAgo daysAfter daysSince daysPassedSince

isEqualTo: (value: string) => FieldAPI
isUndefined: () => FieldAPI
not: {
isBeforeNow: () => FieldAPI
inArray: (values: string[]) => FieldAPI
equalTo: (value: string) => FieldAPI
}
Expand Down Expand Up @@ -158,6 +163,26 @@ export function field(fieldId: string) {
},
required: ['$form', '$now']
}),
isAfter: (days: number) =>
addCondition({
type: 'object',
properties: {
$form: {
type: 'object',
properties: {
[fieldId]: {
type: 'string',
format: 'date',
formatMinimum: new Date(Date.now() - days * 24 * 60 * 60 * 1000)
.toISOString()
.split('T')[0]
}
},
required: [fieldId]
}
},
required: ['$form']
}),
isEqualTo: (value: string) =>
addCondition({
type: 'object',
Expand Down Expand Up @@ -205,6 +230,30 @@ export function field(fieldId: string) {
required: ['$form']
}),
not: {
isBeforeNow: () =>
addCondition({
type: 'object',
properties: {
$form: {
type: 'object',
properties: {
[fieldId]: {
type: 'string',
not: {
format: 'date',
formatMaximum: { $data: '2/$now' }
}
}
},
required: [fieldId]
},
$now: {
type: 'string',
format: 'date'
}
},
required: ['$form', '$now']
}),
inArray: (values: string[]) =>
addCondition({
type: 'object',
Expand Down
Loading