From 78087a72cb8df95d072aac4b9a65f2f8d8a462f4 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 | 7 +- .../useUpdateIdentifierRequirement.tsx | 83 +++++++++++++++++++ 2 files changed, 87 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..e351351f05 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,8 @@ const CustomPersonAttributeField: React.FC = ({ }) => { const { t } = useTranslation(); const fieldName = `attributes.${personAttributeType.uuid}`; - const context = useContext(PatientRegistrationContext) as PatientRegistrationContextType; - const { setFieldValue, values } = context; - + const { setFieldValue, values } = useContext(PatientRegistrationContext); + useUpdateIdentifierRequirement(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..4e92d00637 --- /dev/null +++ b/packages/esm-patient-registration-app/src/patient-registration/field/person-attributes/useUpdateIdentifierRequirement.tsx @@ -0,0 +1,83 @@ +import { useEffect, useCallback, useRef, useMemo, useContext } from 'react'; +import { deleteIdentifierType, initializeIdentifier } from '../id/id-field.component'; +import { ResourcesContext } from '../../../offline.resources'; + +const useUpdateIdentifierRequirement = (setFieldValue, values) => { + const { identifierTypes = [] } = useContext(ResourcesContext); + 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], + ); + // Only run the effect if isCivilian is true + 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; + const isDependant = Object.values(values.attributes ?? {}).includes('Dependant'); + // Only proceed if the user is a civilian + if (isCivilian && isDependant) { + 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 { + // Before deleting the publication number identifier, check if it exists + if (values.identifiers[publicationNumberIdentifier.fieldName]) { + setFieldValue('identifiers', deleteIdentifierType(values.identifiers, publicationNumberIdentifier.fieldName)); + } + } + }, [ + values.attributes, + values.identifiers, + isCivilian, + publicationNumberIdentifier, + initializePublicationIdentifier, + setFieldValue, + ]); +}; + +export default useUpdateIdentifierRequirement;