-
Notifications
You must be signed in to change notification settings - Fork 3
BN-71 | Add. DiagnosesForm To Consultation Pad #23
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
Changes from 18 commits
8a29e59
c88ecea
1c5796e
50d7d5a
2eda88b
867e15a
edc068d
bd2cec6
b50bc35
0b65a44
a05c2ab
246a3de
c9f4b6c
4f5f093
9883cee
53f805a
cf0be3c
398c4e2
cac38b5
1ae26f0
594404e
10f3e4b
b884bbc
6438eab
6042931
7f7644a
26ba6d0
1e9e003
f4c612f
2961f02
eae7df1
441a3ce
226a8f6
92fab4a
a73492d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,10 +5,14 @@ import { useCurrentEncounter } from '@hooks/useCurrentEncounter'; | |
| import { useActivePractitioner } from '@hooks/useActivePractitioner'; | ||
| import { useEncounterConcepts } from '@hooks/useEncounterConcepts'; | ||
| import { useLocations } from '@hooks/useLocations'; | ||
| import { useConceptSearch } from '@hooks/useConceptSearch'; | ||
| import { Column, Grid, Loading } from '@carbon/react'; | ||
| import * as styles from './styles/ConsultationPad.module.scss'; | ||
| import BasicForm from '@components/clinical/basicForm/BasicForm'; | ||
| import DiagnosesForm from '@components/clinical/diagnosesForm/DiagnosesForm'; | ||
| import { SelectedDiagnosisItemProps } from '@components/clinical/diagnosesForm/SelectedDiagnosisItem'; | ||
| import { Concept } from '@types/encounterConcepts'; | ||
| import { ConceptSearch } from '@types/concepts'; | ||
| import { ConsultationBundle } from '@types/consultationBundle'; | ||
| import { postConsultationBundle } from '@services/consultationBundleService'; | ||
| import useNotification from '@hooks/useNotification'; | ||
|
|
@@ -18,6 +22,8 @@ import { | |
| createBundleEntry, | ||
| createConsultationBundle, | ||
| } from '@utils/fhir/consultationBundleCreator'; | ||
| import { CERTAINITY_CONCEPTS } from '@constants/concepts'; | ||
| import { Coding } from 'fhir/r4'; | ||
|
|
||
| interface ConsultationPadProps { | ||
| patientUUID: string; | ||
|
|
@@ -29,8 +35,91 @@ const ConsultationPad: React.FC<ConsultationPadProps> = ({ | |
| onClose, | ||
| }) => { | ||
| const [isSubmitting, setIsSubmitting] = React.useState(false); | ||
|
|
||
| // DiagnosesForm state management | ||
| const [searchDiagnosesTerm, setSearchDiagnosesTerm] = React.useState(''); | ||
| const [selectedDiagnoses, setSelectedDiagnoses] = React.useState< | ||
| SelectedDiagnosisItemProps[] | ||
| >([]); | ||
| const [diagnosisErrors, setDiagnosisErrors] = React.useState<Error[]>([]); | ||
|
|
||
| const { t } = useTranslation(); | ||
| const { addNotification } = useNotification(); | ||
|
|
||
| // Use concept search hook for diagnoses | ||
| const { | ||
|
||
| searchResults, | ||
| loading: isSearchLoading, | ||
| error: searchError, | ||
| } = useConceptSearch(searchDiagnosesTerm); | ||
|
|
||
| // Handle search errors | ||
| React.useEffect(() => { | ||
| if (searchError) { | ||
| setDiagnosisErrors([searchError]); | ||
| } | ||
| }, [searchError]); | ||
|
|
||
| // DiagnosesForm handler functions | ||
| const handleSearch = (searchTerm: string) => { | ||
| setSearchDiagnosesTerm(searchTerm); | ||
| // Clear previous errors when new search starts | ||
| setDiagnosisErrors([]); | ||
| }; | ||
|
|
||
| const handleResultSelection = ( | ||
| selectedItem: ConceptSearch | null | undefined, | ||
| ) => { | ||
| if (!selectedItem) { | ||
| return; | ||
| } | ||
|
|
||
| // Check for duplicate diagnosis | ||
| const isDuplicate = selectedDiagnoses.some( | ||
| (diagnosis) => diagnosis.id === selectedItem.conceptUuid, | ||
| ); | ||
|
|
||
| if (isDuplicate) { | ||
| setDiagnosisErrors([new Error(t('DIAGNOSES_DUPLICATE_ERROR'))]); | ||
| return; | ||
| } | ||
|
|
||
| // Create new diagnosis with certainty handler | ||
| const newDiagnosis: SelectedDiagnosisItemProps = { | ||
| id: selectedItem.conceptUuid, | ||
| title: selectedItem.conceptName, | ||
| certaintyConcepts: CERTAINITY_CONCEPTS, | ||
| selectedCertainty: null, | ||
| handleCertaintyChange: (data) => { | ||
| handleCertaintyChange(selectedItem.conceptUuid, data.selectedItem); | ||
| }, | ||
| }; | ||
|
|
||
| setSelectedDiagnoses([...selectedDiagnoses, newDiagnosis]); | ||
| setSearchDiagnosesTerm(''); // Clear search | ||
| setDiagnosisErrors([]); // Clear errors | ||
| }; | ||
|
|
||
| const handleRemoveDiagnosis = (index: number) => { | ||
| setSelectedDiagnoses((prevDiagnoses) => | ||
| prevDiagnoses.filter((_, i) => i !== index), | ||
| ); | ||
| setDiagnosisErrors([]); // Clear any existing errors | ||
| }; | ||
|
|
||
| const handleCertaintyChange = ( | ||
| diagnosisId: string, | ||
| selectedCertainty: Coding | null | undefined, | ||
| ) => { | ||
| setSelectedDiagnoses((prevDiagnoses) => | ||
| prevDiagnoses.map((diagnosis) => | ||
| diagnosis.id === diagnosisId | ||
| ? { ...diagnosis, selectedCertainty: selectedCertainty || null } | ||
| : diagnosis, | ||
| ), | ||
| ); | ||
| }; | ||
|
|
||
| const { | ||
| locations, | ||
| loading: loadingLocations, | ||
|
|
@@ -79,11 +168,11 @@ const ConsultationPad: React.FC<ConsultationPadProps> = ({ | |
| const submitConsultation = () => { | ||
| const enconterResourceURL = `urn:uuid:${crypto.randomUUID()}`; | ||
| const encounterResource = createEncounterResource( | ||
| encounterTypeSelected?.uuid, | ||
| encounterTypeSelected?.name, | ||
| encounterTypeSelected!.uuid, | ||
| encounterTypeSelected!.name, | ||
| patientUUID, | ||
| [practitioner?.uuid], | ||
| currentEncounter?.id, | ||
| [practitioner!.uuid], | ||
| currentEncounter!.id, | ||
| locations[0].uuid, | ||
| new Date(), | ||
| ); | ||
|
|
@@ -192,16 +281,31 @@ const ConsultationPad: React.FC<ConsultationPadProps> = ({ | |
| secondaryButtonText={t('CONSULTATION_PAD_CANCEL_BUTTON')} | ||
| onSecondaryButtonClick={handleOnSecondaryButtonClick} | ||
| content={ | ||
| <BasicForm | ||
| practitioner={practitioner} | ||
| encounterTypes={encounterConcepts.encounterTypes} | ||
| encounterTypeSelected={encounterTypeSelected} | ||
| visitTypes={encounterConcepts.visitTypes} | ||
| visitTypeSelected={visitTypeSelected} | ||
| location={locations[0]} | ||
| locationSelected={locations[0]} | ||
| defaultDate={formattedDate.formattedResult} | ||
| /> | ||
| <> | ||
| <BasicForm | ||
| practitioner={practitioner} | ||
| encounterTypes={encounterConcepts.encounterTypes} | ||
| encounterTypeSelected={encounterTypeSelected} | ||
| visitTypes={encounterConcepts.visitTypes} | ||
| visitTypeSelected={visitTypeSelected} | ||
| location={locations[0]} | ||
| locationSelected={locations[0]} | ||
| defaultDate={formattedDate.formattedResult} | ||
| /> | ||
| <DiagnosesForm | ||
| handleResultSelection={handleResultSelection} | ||
| handleSearch={handleSearch} | ||
| searchResults={searchResults} | ||
| isSearchEmpty={ | ||
| searchResults.length === 0 && | ||
| !isSearchLoading && | ||
| searchDiagnosesTerm.length > 2 | ||
| } | ||
| errors={diagnosisErrors} | ||
| selectedDiagnoses={selectedDiagnoses} | ||
| handleRemoveDiagnosis={handleRemoveDiagnosis} | ||
| /> | ||
| </> | ||
| } | ||
| /> | ||
| ); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The searchTerm, diagnosesErrors doesn't need to be a concern / part of consultation pad. This can be controlled within DiagnosisForm. Only the selectedDiagnosis can be part of ConsultationPad, which will be consumed during Consultation Bundle creation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have addressed this. Thanks for taking a look