diff --git a/src/notes/visit-notes-form.component.tsx b/src/notes/visit-notes-form.component.tsx index f4b9c32..8dab0a9 100644 --- a/src/notes/visit-notes-form.component.tsx +++ b/src/notes/visit-notes-form.component.tsx @@ -1,17 +1,9 @@ -import React, { - type SyntheticEvent, - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from "react"; +import React, { useCallback, useMemo, useState } from "react"; import dayjs from "dayjs"; import { useTranslation } from "react-i18next"; -import debounce from "lodash-es/debounce"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; -import { useForm, Controller, type Control } from "react-hook-form"; +import { useForm, Controller } from "react-hook-form"; import { Button, ButtonSet, @@ -25,14 +17,10 @@ import { RadioButton, RadioButtonGroup, Row, - Search, - SkeletonText, Stack, - Tag, TextArea, - Tile, } from "@carbon/react"; -import { Add, Edit, WarningFilled } from "@carbon/react/icons"; +import { Add, Edit } from "@carbon/react/icons"; import { type UploadedFile, createErrorHandler, @@ -47,16 +35,9 @@ import { } from "@openmrs/esm-framework"; import { type DefaultWorkspaceProps } from "@openmrs/esm-patient-common-lib"; import type { ConfigObject } from "../config-schema"; -import type { - Concept, - Diagnosis, - DiagnosisPayload, - VisitNotePayload, -} from "../types"; +import type { VisitNotePayload } from "../types"; import { extractDate, - fetchConceptDiagnosisByName, - savePatientDiagnosis, saveVisitNote, useConceptAnswers, useVisitNotes, @@ -68,35 +49,17 @@ const allowedImageTypes = ["image/jpeg", "image/png", "image/webp"]; const visitNoteFormSchema = z.object({ noteDate: z.date(), - primaryDiagnosisSearch: z.string({ - required_error: "Choose at least one primary diagnosis", - }), - secondaryDiagnosisSearch: z.string().optional(), clinicalNote: z.string().optional(), + revievwOfBodySystems: z.array(z.string()).optional(), image: z.any(), }); type VisitNotesFormData = z.infer; -interface DiagnosisSearchProps { - name: - | "noteDate" - | "primaryDiagnosisSearch" - | "secondaryDiagnosisSearch" - | "clinicalNote"; - labelText: string; - placeholder: string; - control: Control; - handleSearch: (fieldName) => void; - - error?: object; -} - const VisitNotesForm: React.FC = ({ closeWorkspace, patientUuid, }) => { - const searchTimeoutInMs = 500; const { t } = useTranslation(); const isTablet = useLayoutType() === "tablet"; const session = useSession(); @@ -109,23 +72,6 @@ const VisitNotesForm: React.FC = ({ formConceptUuid, } = config.visitNoteConfig; const [isHandlingSubmit, setIsHandlingSubmit] = useState(false); - const [loadingPrimary, setLoadingPrimary] = useState(false); - const [loadingSecondary, setLoadingSecondary] = useState(false); - const [selectedPrimaryDiagnoses, setSelectedPrimaryDiagnoses] = useState< - Array - >([]); - const [selectedSecondaryDiagnoses, setSelectedSecondaryDiagnoses] = useState< - Array - >([]); - const [searchPrimaryResults, setSearchPrimaryResults] = useState< - Array - >([]); - const [searchSecondaryResults, setSearchSecondaryResults] = useState< - Array - >([]); - const [combinedDiagnoses, setCombinedDiagnoses] = useState>( - [] - ); const { conceptAnswers } = useConceptAnswers( "dce0e02a-30ab-102d-86b0-7a5022ba4115" @@ -147,7 +93,7 @@ const VisitNotesForm: React.FC = ({ const [rows, setRows] = useState(); - const { control, handleSubmit, watch, getValues, setValue, formState } = + const { control, handleSubmit, watch, setValue } = useForm({ mode: "onSubmit", resolver: zodResolver(visitNoteFormSchema), @@ -166,108 +112,6 @@ const VisitNotesForm: React.FC = ({ const locationUuid = session?.sessionLocation?.uuid; const providerUuid = session?.currentProvider?.uuid; - const handleSearch = (fieldName) => { - const fieldQuery = watch(fieldName); - if (fieldQuery) { - debouncedSearch(fieldQuery, fieldName); - } - }; - - const debouncedSearch = useMemo( - () => - debounce((fieldQuery, fieldName) => { - if (fieldQuery) { - if (fieldName === "primaryDiagnosisSearch") { - setLoadingPrimary(true); - } else if (fieldName === "secondaryDiagnosisSearch") { - setLoadingSecondary(true); - } - const sub = fetchConceptDiagnosisByName(fieldQuery).subscribe( - (matchingConceptDiagnoses: Array) => { - if (fieldName == "primaryDiagnosisSearch") { - setSearchPrimaryResults(matchingConceptDiagnoses); - setLoadingPrimary(false); - } else if (fieldName == "secondaryDiagnosisSearch") { - setSearchSecondaryResults(matchingConceptDiagnoses); - setLoadingSecondary(false); - } - }, - () => createErrorHandler() - ); - return () => { - sub.unsubscribe(); - }; - } - }, searchTimeoutInMs), - [] - ); - - const handleAddDiagnosis = ( - conceptDiagnosisToAdd: Concept, - searchInputField: string - ) => { - const newDiagnosis = createDiagnosis(conceptDiagnosisToAdd); - if (searchInputField == "primaryDiagnosisSearch") { - newDiagnosis.rank = 1; - setValue("primaryDiagnosisSearch", ""); - setSearchPrimaryResults([]); - setSelectedPrimaryDiagnoses((selectedDiagnoses) => [ - ...selectedDiagnoses, - newDiagnosis, - ]); - } else if (searchInputField == "secondaryDiagnosisSearch") { - setValue("secondaryDiagnosisSearch", ""); - setSearchSecondaryResults([]); - setSelectedSecondaryDiagnoses((selectedDiagnoses) => [ - ...selectedDiagnoses, - newDiagnosis, - ]); - } - setCombinedDiagnoses((diagnosisCombined) => [ - ...diagnosisCombined, - newDiagnosis, - ]); - }; - - const handleRemoveDiagnosis = ( - diagnosisToRemove: Diagnosis, - searchInputField: string - ) => { - if (searchInputField == "primaryInputSearch") { - setSelectedPrimaryDiagnoses( - selectedPrimaryDiagnoses.filter( - (diagnosis) => - diagnosis.diagnosis.coded !== diagnosisToRemove.diagnosis.coded - ) - ); - } else if (searchInputField == "secondaryInputSearch") { - setSelectedSecondaryDiagnoses( - selectedSecondaryDiagnoses.filter( - (diagnosis) => - diagnosis.diagnosis.coded !== diagnosisToRemove.diagnosis.coded - ) - ); - } - setCombinedDiagnoses( - combinedDiagnoses.filter( - (diagnosis) => - diagnosis.diagnosis.coded !== diagnosisToRemove.diagnosis.coded - ) - ); - }; - - const createDiagnosis = (concept: Concept) => { - return { - patient: patientUuid, - diagnosis: { - coded: concept.uuid, - }, - rank: 2, - certainty: "PROVISIONAL", - display: concept.display, - }; - }; - const showImageCaptureModal = useCallback(() => { const close = showModal("capture-photo-modal", { saveFile: (file: UploadedFile) => { @@ -285,15 +129,10 @@ const VisitNotesForm: React.FC = ({ }, [patientUuid]); const onSubmit = useCallback( - (data: VisitNotesFormData, event: SyntheticEvent) => { + (data: VisitNotesFormData) => { const { noteDate, clinicalNote } = data; setIsHandlingSubmit(true); - if (!selectedPrimaryDiagnoses.length) { - setIsHandlingSubmit(false); - return; - } - const visitNotePayload: VisitNotePayload = { encounterDatetime: dayjs(noteDate).format(), form: formConceptUuid, @@ -318,25 +157,6 @@ const VisitNotesForm: React.FC = ({ const abortController = new AbortController(); saveVisitNote(abortController, visitNotePayload) - .then((response) => { - if (response.status === 201) { - return Promise.all( - combinedDiagnoses.map((diagnosis, position: number) => { - const diagnosisPayload: DiagnosisPayload = { - encounter: response.data.uuid, - patient: patientUuid, - condition: null, - diagnosis: { - coded: diagnosis.diagnosis.coded, - }, - certainty: diagnosis.certainty, - rank: diagnosis.rank, - }; - return savePatientDiagnosis(abortController, diagnosisPayload); - }) - ); - } - }) .then(() => { if (data.image) { return createAttachment(patientUuid, data.image); @@ -375,7 +195,6 @@ const VisitNotesForm: React.FC = ({ }); }, [ - selectedPrimaryDiagnoses.length, formConceptUuid, patientUuid, locationUuid, @@ -383,7 +202,6 @@ const VisitNotesForm: React.FC = ({ providerUuid, encounterTypeUuid, encounterNoteTextConceptUuid, - combinedDiagnoses, mutateVisitNotes, closeWorkspace, t, @@ -437,6 +255,25 @@ const VisitNotesForm: React.FC = ({ /> + + + + {t("reviewBodySystems", "Review of Body Systems")} + + + +
+ { + // Empty function + }} + /> +
+
+
{age < 5 && ( @@ -496,260 +333,6 @@ const VisitNotesForm: React.FC = ({ )} - - - - {t("primaryDiagnosis", "Primary diagnosis")} - - - -
- {selectedPrimaryDiagnoses && selectedPrimaryDiagnoses.length ? ( - <> - {selectedPrimaryDiagnoses.map((diagnosis, index) => ( - - handleRemoveDiagnosis(diagnosis, "primaryInputSearch") - } - style={{ marginRight: "0.5rem" }} - type={"red"} - > - {diagnosis.display} - - ))} - - ) : ( - <> - )} - {selectedSecondaryDiagnoses && - selectedSecondaryDiagnoses.length ? ( - <> - {selectedSecondaryDiagnoses.map((diagnosis, index) => ( - - handleRemoveDiagnosis(diagnosis, "secondaryInputSearch") - } - style={{ marginRight: "0.5rem" }} - type={"blue"} - > - {diagnosis.display} - - ))} - - ) : ( - <> - )} - {selectedPrimaryDiagnoses && - !selectedPrimaryDiagnoses.length && - selectedSecondaryDiagnoses && - !selectedSecondaryDiagnoses.length && ( - - {t( - "emptyDiagnosisText", - "No diagnosis selected — Enter a diagnosis below" - )} - - )} -
- - -
- {(() => { - if (!getValues("primaryDiagnosisSearch")) return null; - if (loadingPrimary) - return ( - <> - - - - - - - ); - if ( - !loadingPrimary && - searchPrimaryResults && - searchPrimaryResults.length > 0 - ) { - return ( -
    - {searchPrimaryResults.map((diagnosis, index) => ( -
  • - handleAddDiagnosis( - diagnosis, - "primaryDiagnosisSearch" - ) - } - > - {diagnosis.display} -
  • - ))} -
- ); - } - return ( - <> - {isTablet ? ( - - - - {t( - "noMatchingDiagnoses", - "No diagnoses found matching" - )}{" "} - - "{watch("primaryDiagnosisSearch")}" - - - - - ) : ( - - - {t( - "noMatchingDiagnoses", - "No diagnoses found matching" - )}{" "} - "{watch("primaryDiagnosisSearch")}" - - - )} - - ); - })()} -
-
-
-
- - - - {t("secondaryDiagnosis", "Secondary diagnosis")} - - - - - -
- {(() => { - if (!getValues("secondaryDiagnosisSearch")) return null; - if (loadingSecondary) - return ( - <> - - - - - - - ); - if ( - !loadingSecondary && - searchSecondaryResults && - searchSecondaryResults.length > 0 - ) - return ( -
    - {searchSecondaryResults.map((diagnosis, index) => ( -
  • - handleAddDiagnosis( - diagnosis, - "secondaryDiagnosisSearch" - ) - } - > - {diagnosis.display} -
  • - ))} -
- ); - return ( - - - - {t( - "noMatchingDiagnoses", - "No diagnoses found matching" - )}{" "} - "{watch("secondaryDiagnosisSearch")}" - - - - ); - })()} -
-
-
-
- - - - {t("reviewBodySystems", "Review of Body Systems")} - - - -
- { - // Empty function - }} - /> -
-
-
{t("note", "Note")} @@ -853,59 +436,6 @@ const VisitNotesForm: React.FC = ({ export default VisitNotesForm; -function DiagnosisSearch({ - name, - control, - labelText, - placeholder, - handleSearch, - error, -}: DiagnosisSearchProps) { - const isTablet = useLayoutType() === "tablet"; - const inputRef = useRef(null); - - const searchInputFocus = () => { - inputRef.current.focus(); - }; - - useEffect(() => { - if (error) { - searchInputFocus(); - } - }, [error]); - - return ( - ( - <> - - ) - } - onChange={(e) => { - onChange(e); - handleSearch(name); - }} - value={value} - onBlur={onBlur} - /> - -

{fieldState?.error?.message}

- - )} - /> - ); -} - function ResponsiveWrapper({ children, isTablet,