From fbd80c19712e573b0e12559ad8aef0eee177489b Mon Sep 17 00:00:00 2001 From: Donald Kibet Date: Thu, 31 Oct 2024 14:35:23 +0300 Subject: [PATCH] (feat) add dynamic showing of publication number --- ...ustom-person-attribute-field.component.tsx | 8 +- .../useUpdateIdentifierRequirement.tsx | 78 +++++++++++++++++++ 2 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 packages/esm-patient-registration-app/src/patient-registration/field/person-attributes/useUpdateIdentifierRequirement.tsx diff --git a/packages/esm-patient-registration-app/src/patient-registration/field/person-attributes/custom-person-attribute-field.component.tsx b/packages/esm-patient-registration-app/src/patient-registration/field/person-attributes/custom-person-attribute-field.component.tsx index 63db707000..d3fc2c46ef 100644 --- a/packages/esm-patient-registration-app/src/patient-registration/field/person-attributes/custom-person-attribute-field.component.tsx +++ b/packages/esm-patient-registration-app/src/patient-registration/field/person-attributes/custom-person-attribute-field.component.tsx @@ -5,6 +5,8 @@ import { useTranslation } from 'react-i18next'; import classNames from 'classnames'; import { PatientRegistrationContext } from '../../patient-registration-context'; import styles from './../field.scss'; +import { ResourcesContext } from '../../../offline.resources'; +import useUpdateIdentifierRequirement from './useUpdateIdentifierRequirement'; interface PersonAttributeTypeResponse { uuid: string; @@ -46,9 +48,9 @@ const CustomPersonAttributeField: React.FC = ({ }) => { const { t } = useTranslation(); const fieldName = `attributes.${personAttributeType.uuid}`; - const context = useContext(PatientRegistrationContext) as PatientRegistrationContextType; - const { setFieldValue, values } = context; - + const { identifierTypes } = useContext(ResourcesContext); + const { setFieldValue, values } = useContext(PatientRegistrationContext); + useUpdateIdentifierRequirement(identifierTypes, setFieldValue, values); // TODO: Improve this logic const filteredCustomConceptAnswers = customConceptAnswers.filter((answer) => { const showExpression = answer.showServiceExpression; diff --git a/packages/esm-patient-registration-app/src/patient-registration/field/person-attributes/useUpdateIdentifierRequirement.tsx b/packages/esm-patient-registration-app/src/patient-registration/field/person-attributes/useUpdateIdentifierRequirement.tsx new file mode 100644 index 0000000000..ea166bdfa0 --- /dev/null +++ b/packages/esm-patient-registration-app/src/patient-registration/field/person-attributes/useUpdateIdentifierRequirement.tsx @@ -0,0 +1,78 @@ +import { useEffect, useCallback, useRef, useMemo } from 'react'; +import { deleteIdentifierType, initializeIdentifier } from '../id/id-field.component'; + +const useUpdateIdentifierRequirement = (identifierTypes, setFieldValue, values) => { + const previousAttributes = useRef(values.attributes); + const previousIdentifiers = useRef(values.identifiers); + + const publicationNumberIdentifier = useMemo( + () => identifierTypes?.find((identifier) => identifier.name === 'Publication Number'), + [identifierTypes], + ); + + // Memoize the civilian check + const isCivilian = useMemo(() => Object.values(values.attributes ?? {}).includes('Civilian'), [values.attributes]); + + // Memoize the identifier initialization logic + const initializePublicationIdentifier = useCallback( + (currentIdentifiers) => { + if (!publicationNumberIdentifier) { + console.warn('Publication Number identifier type not found'); + return null; + } + + const initializedIdentifier = initializeIdentifier( + publicationNumberIdentifier, + currentIdentifiers[publicationNumberIdentifier.uuid], + ); + + return initializedIdentifier; + }, + [publicationNumberIdentifier], + ); + + useEffect(() => { + // Skip if we don't have the required data + if (!values.attributes || !publicationNumberIdentifier) { + return; + } + + // Check if relevant values have actually changed + const attributesChanged = previousAttributes.current !== values.attributes; + const identifiersChanged = previousIdentifiers.current !== values.identifiers; + + if (!attributesChanged && !identifiersChanged) { + return; + } + + // Update refs + previousAttributes.current = values.attributes; + previousIdentifiers.current = values.identifiers; + + // Only proceed if the user is a civilian + if (isCivilian) { + const initializedIdentifier = initializePublicationIdentifier(values.identifiers); + + // check if values.identifiers already has the publication number identifier + const hasPublicationNumberIdentifier = values.identifiers[publicationNumberIdentifier.fieldName]; + + if (initializedIdentifier && !hasPublicationNumberIdentifier) { + setFieldValue('identifiers', { + ...values.identifiers, + [publicationNumberIdentifier.fieldName]: { ...initializedIdentifier, required: true }, + }); + } + } else { + setFieldValue('identifiers', deleteIdentifierType(values.identifiers, publicationNumberIdentifier.fieldName)); + } + }, [ + values.attributes, + values.identifiers, + isCivilian, + publicationNumberIdentifier, + initializePublicationIdentifier, + setFieldValue, + ]); +}; + +export default useUpdateIdentifierRequirement;