From 5bbf4fd624b42306f04658dd3dd50bfc38f78550 Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Mon, 18 Nov 2024 15:46:26 +0300 Subject: [PATCH] Revert "(feat) HIE-9: Add MPI workflows to OpenMRS frontend (#1313)" This reverts commit e00996941414834e10447c6f7d4b4e3c56615ec7. --- .../src/config-schema.ts | 16 -- .../mpi/mpi-patient.resource.ts | 18 -- .../patient-registration-hooks.ts | 53 +----- .../patient-registration-utils.ts | 44 +---- .../patient-registration.component.tsx | 6 +- .../patient-registration.test.tsx | 177 +----------------- .../index.tsx | 10 +- .../compact-patient-search.component.tsx | 10 +- packages/esm-patient-search-app/src/index.ts | 1 - .../esm-patient-search-app/src/mpi/utils.ts | 49 ----- .../patient-search-button.test.tsx | 10 +- .../advanced-patient-search.component.tsx | 4 +- .../banner/patient-banner.component.tsx | 32 +--- .../patient-search-lg.component.tsx | 19 +- .../patient-search-page.component.tsx | 2 - .../patient-search-views.component.tsx | 61 +----- .../patient-search.workspace.tsx | 11 +- .../src/patient-search.resource.tsx | 31 +-- .../esm-patient-search-app/src/routes.json | 7 - .../esm-patient-search-app/src/types/index.ts | 1 - .../translations/en.json | 2 - tools/index.ts | 1 - tools/test-utils.tsx | 34 ---- 23 files changed, 48 insertions(+), 551 deletions(-) delete mode 100644 packages/esm-patient-registration-app/src/patient-registration/mpi/mpi-patient.resource.ts delete mode 100644 packages/esm-patient-search-app/src/mpi/utils.ts diff --git a/packages/esm-patient-registration-app/src/config-schema.ts b/packages/esm-patient-registration-app/src/config-schema.ts index 43bd591f4..ccb4bc6ba 100644 --- a/packages/esm-patient-registration-app/src/config-schema.ts +++ b/packages/esm-patient-registration-app/src/config-schema.ts @@ -68,7 +68,6 @@ export interface RegistrationConfig { month: number; }; }; - identifier: [{ identifierTypeSystem: string; identifierTypeUuid: string }]; phone: { personAttributeUuid: string; validation?: { @@ -352,21 +351,6 @@ export const esmPatientRegistrationSchema = { }, }, }, - identifier: { - _type: Type.Array, - _elements: { - identifierTypeSystem: { - _type: Type.String, - _description: 'Identifier system from the fhir server', - }, - identifierTypeUuid: { - _type: Type.String, - _default: null, - _description: 'Identifier type uuid of OpenMRS to map the identifier system', - }, - }, - _default: [], - }, phone: { personAttributeUuid: { _type: Type.UUID, diff --git a/packages/esm-patient-registration-app/src/patient-registration/mpi/mpi-patient.resource.ts b/packages/esm-patient-registration-app/src/patient-registration/mpi/mpi-patient.resource.ts deleted file mode 100644 index a79cb3fe9..000000000 --- a/packages/esm-patient-registration-app/src/patient-registration/mpi/mpi-patient.resource.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { fhirBaseUrl, openmrsFetch } from '@openmrs/esm-framework'; -import useSWR from 'swr'; - -export function useMpiPatient(patientId: string) { - const url = `${fhirBaseUrl}/Patient/${patientId}/$cr`; - - const { - data: patient, - error: error, - isLoading: isLoading, - } = useSWR<{ data: fhir.Patient }, Error>(url, openmrsFetch); - - return { - isLoading, - patient, - error: error, - }; -} diff --git a/packages/esm-patient-registration-app/src/patient-registration/patient-registration-hooks.ts b/packages/esm-patient-registration-app/src/patient-registration/patient-registration-hooks.ts index 0a9ec8176..ff50d4b20 100644 --- a/packages/esm-patient-registration-app/src/patient-registration/patient-registration-hooks.ts +++ b/packages/esm-patient-registration-app/src/patient-registration/patient-registration-hooks.ts @@ -24,27 +24,20 @@ import { import { getAddressFieldValuesFromFhirPatient, getFormValuesFromFhirPatient, - getIdentifierFieldValuesFromFhirPatient, getPatientUuidMapFromFhirPatient, getPhonePersonAttributeValueFromFhirPatient, latestFirstEncounter, } from './patient-registration-utils'; import { useInitialPatientRelationships } from './section/patient-relationships/relationships.resource'; import dayjs from 'dayjs'; -import { useMpiPatient } from './mpi/mpi-patient.resource'; - -export function useInitialFormValues(patientUuid: string, isLocal: boolean): [FormValues, Dispatch] { - const { freeTextFieldConceptUuid, fieldConfigurations } = useConfig(); - const { isLoading: isLoadingPatientToEdit, patient: patientToEdit } = usePatient(isLocal ? patientUuid : null); - const { isLoading: isLoadingMpiPatient, patient: mpiPatient } = useMpiPatient(!isLocal ? patientUuid : null); - const { data: deathInfo, isLoading: isLoadingDeathInfo } = useInitialPersonDeathInfo(isLocal ? patientUuid : null); - const { data: attributes, isLoading: isLoadingAttributes } = useInitialPersonAttributes(isLocal ? patientUuid : null); - const { data: identifiers, isLoading: isLoadingIdentifiers } = useInitialPatientIdentifiers( - isLocal ? patientUuid : null, - ); - const { data: relationships, isLoading: isLoadingRelationships } = useInitialPatientRelationships( - isLocal ? patientUuid : null, - ); + +export function useInitialFormValues(patientUuid: string): [FormValues, Dispatch] { + const { freeTextFieldConceptUuid } = useConfig(); + const { isLoading: isLoadingPatientToEdit, patient: patientToEdit } = usePatient(patientUuid); + const { data: deathInfo, isLoading: isLoadingDeathInfo } = useInitialPersonDeathInfo(patientUuid); + const { data: attributes, isLoading: isLoadingAttributes } = useInitialPersonAttributes(patientUuid); + const { data: identifiers, isLoading: isLoadingIdentifiers } = useInitialPatientIdentifiers(patientUuid); + const { data: relationships, isLoading: isLoadingRelationships } = useInitialPatientRelationships(patientUuid); const { data: encounters } = useInitialEncounters(patientUuid, patientToEdit); const [initialFormValues, setInitialFormValues] = useState({ @@ -88,12 +81,12 @@ export function useInitialFormValues(patientUuid: string, isLocal: boolean): [Fo ...initialFormValues, ...getFormValuesFromFhirPatient(patientToEdit), address: getAddressFieldValuesFromFhirPatient(patientToEdit), - ...getPhonePersonAttributeValueFromFhirPatient(patientToEdit, fieldConfigurations.phone.personAttributeUuid), + ...getPhonePersonAttributeValueFromFhirPatient(patientToEdit), birthdateEstimated: !/^\d{4}-\d{2}-\d{2}$/.test(patientToEdit.birthDate), yearsEstimated, monthsEstimated, }); - } else if (!isLoadingPatientToEdit && patientUuid && isLocal) { + } else if (!isLoadingPatientToEdit && patientUuid) { const registration = await getPatientRegistration(patientUuid); if (!registration._patientRegistrationData.formValues) { @@ -108,32 +101,6 @@ export function useInitialFormValues(patientUuid: string, isLocal: boolean): [Fo })(); }, [isLoadingPatientToEdit, patientToEdit, patientUuid]); - useEffect(() => { - const fetchValues = async () => { - if (mpiPatient?.data?.identifier) { - const identifiers = await getIdentifierFieldValuesFromFhirPatient( - mpiPatient.data, - fieldConfigurations.identifier, - ); - - const values = { - ...initialFormValues, - ...getFormValuesFromFhirPatient(mpiPatient.data), - address: getAddressFieldValuesFromFhirPatient(mpiPatient.data), - identifiers, - attributes: getPhonePersonAttributeValueFromFhirPatient( - mpiPatient.data, - fieldConfigurations.phone.personAttributeUuid, - ), - }; - - setInitialFormValues(values); - } - }; - - fetchValues(); - }, [mpiPatient, isLoadingMpiPatient]); - // Set initial patient death info useEffect(() => { if (!isLoadingDeathInfo && deathInfo?.dead) { diff --git a/packages/esm-patient-registration-app/src/patient-registration/patient-registration-utils.ts b/packages/esm-patient-registration-app/src/patient-registration/patient-registration-utils.ts index 2a9f0e3a3..3aa777a2c 100644 --- a/packages/esm-patient-registration-app/src/patient-registration/patient-registration-utils.ts +++ b/packages/esm-patient-registration-app/src/patient-registration/patient-registration-utils.ts @@ -1,6 +1,6 @@ import * as Yup from 'yup'; import camelCase from 'lodash-es/camelCase'; -import { openmrsFetch, parseDate, restBaseUrl } from '@openmrs/esm-framework'; +import { parseDate } from '@openmrs/esm-framework'; import { type AddressValidationSchemaType, type Encounter, @@ -192,48 +192,10 @@ export function getPatientIdentifiersFromFhirPatient(patient: fhir.Patient): Arr }); } -export async function getIdentifierFieldValuesFromFhirPatient( - patient: fhir.Patient, - identifierConfig, -): Promise<{ [identifierFieldName: string]: PatientIdentifierValue }> { - const identifiers: FormValues['identifiers'] = {}; - - for (const identifier of patient.identifier) { - for (const config of identifierConfig) { - const identifierConfig = config.identifierTypeSystem === identifier.system ? config : null; - - if (identifierConfig) { - let identifierTypeName; - - const url = `${restBaseUrl}/patientidentifiertype/${identifierConfig.identifierTypeUuid}`; - await openmrsFetch(url).then((response) => { - if (response.status == 200 && response.data) { - identifierTypeName = response.data.name; - } - }); - - identifiers[identifierTypeName] = { - identifierUuid: null, - preferred: false, // consider identifier.use === 'official' ?? by default autogen is preferred - initialValue: identifier.value, - identifierValue: identifier.value, - identifierTypeUuid: identifierConfig.identifierTypeUuid, - identifierName: identifierTypeName, - required: false, - selectedSource: null, - autoGeneration: false, - }; - } - } - } - - return identifiers; -} - -export function getPhonePersonAttributeValueFromFhirPatient(patient: fhir.Patient, phoneUuid) { +export function getPhonePersonAttributeValueFromFhirPatient(patient: fhir.Patient) { const result = {}; if (patient.telecom) { - result[phoneUuid] = patient.telecom[0].value; + result['phone'] = patient.telecom[0].value; } return result; } diff --git a/packages/esm-patient-registration-app/src/patient-registration/patient-registration.component.tsx b/packages/esm-patient-registration-app/src/patient-registration/patient-registration.component.tsx index d2926852e..55b250bda 100644 --- a/packages/esm-patient-registration-app/src/patient-registration/patient-registration.component.tsx +++ b/packages/esm-patient-registration-app/src/patient-registration/patient-registration.component.tsx @@ -39,14 +39,10 @@ export const PatientRegistration: React.FC = ({ savePa const config = useConfig() as RegistrationConfig; const [target, setTarget] = useState(); const { patientUuid: uuidOfPatientToEdit } = useParams(); - const sourcePatientId = new URLSearchParams(search).get('sourceRecord'); const { isLoading: isLoadingPatientToEdit, patient: patientToEdit } = usePatient(uuidOfPatientToEdit); const { t } = useTranslation(); const [capturePhotoProps, setCapturePhotoProps] = useState(null); - const [initialFormValues, setInitialFormValues] = useInitialFormValues( - uuidOfPatientToEdit || sourcePatientId, - !!uuidOfPatientToEdit, - ); + const [initialFormValues, setInitialFormValues] = useInitialFormValues(uuidOfPatientToEdit); const [initialAddressFieldValues] = useInitialAddressFieldValues(uuidOfPatientToEdit); const [patientUuidMap] = usePatientUuidMap(uuidOfPatientToEdit); const location = currentSession?.sessionLocation?.uuid; diff --git a/packages/esm-patient-registration-app/src/patient-registration/patient-registration.test.tsx b/packages/esm-patient-registration-app/src/patient-registration/patient-registration.test.tsx index 532f2bebf..f2c93fd80 100644 --- a/packages/esm-patient-registration-app/src/patient-registration/patient-registration.test.tsx +++ b/packages/esm-patient-registration-app/src/patient-registration/patient-registration.test.tsx @@ -1,8 +1,8 @@ import React from 'react'; import dayjs from 'dayjs'; import userEvent from '@testing-library/user-event'; -import { BrowserRouter as Router, useParams, useLocation } from 'react-router-dom'; -import { act, render, screen, within } from '@testing-library/react'; +import { BrowserRouter as Router, useParams } from 'react-router-dom'; +import { render, screen, within } from '@testing-library/react'; import { type FetchResponse, getDefaultsFromConfigSchema, @@ -10,17 +10,15 @@ import { showSnackbar, useConfig, usePatient, - openmrsFetch, } from '@openmrs/esm-framework'; import { mockedAddressTemplate } from '__mocks__'; -import { mockPatient, mockOpenMRSIdentificationNumberIdType } from 'tools'; +import { mockPatient } from 'tools'; import { saveEncounter, savePatient } from './patient-registration.resource'; import { esmPatientRegistrationSchema, type RegistrationConfig } from '../config-schema'; import type { AddressTemplate, Encounter } from './patient-registration.types'; import { ResourcesContext } from '../offline.resources'; import { FormManager } from './form-manager'; import { PatientRegistration } from './patient-registration.component'; -import { useMpiPatient } from './mpi/mpi-patient.resource'; const mockSaveEncounter = jest.mocked(saveEncounter); const mockSavePatient = savePatient as jest.Mock; @@ -28,11 +26,6 @@ const mockShowSnackbar = jest.mocked(showSnackbar); const mockUseConfig = jest.mocked(useConfig); const mockUsePatient = jest.mocked(usePatient); const mockOpenmrsDatePicker = jest.mocked(OpenmrsDatePicker); -const mockUseMpiPatient = useMpiPatient as jest.Mock; - -jest.mock('./mpi/mpi-patient.resource', () => ({ - useMpiPatient: jest.fn(), -})); jest.mock('./field/field.resource', () => ({ useConcept: jest.fn().mockImplementation((uuid: string) => { @@ -93,7 +86,7 @@ jest.mock('./field/field.resource', () => ({ jest.mock('react-router-dom', () => ({ ...(jest.requireActual('react-router-dom') as any), - useLocation: jest.fn().mockReturnValue({ + useLocation: () => ({ pathname: 'openmrs/spa/patient-registration', }), useHistory: () => [], @@ -136,7 +129,7 @@ const mockResourcesContextValue = { let mockOpenmrsConfig: RegistrationConfig = { sections: ['demographics', 'contact'], sectionDefinitions: [ - { id: 'demographics', name: 'Demographics', fields: ['name', 'gender', 'dob', 'id'] }, + { id: 'demographics', name: 'Demographics', fields: ['name', 'gender', 'dob'] }, { id: 'contact', name: 'Contact Info', fields: ['address'] }, { id: 'relationships', name: 'Relationships', fields: ['relationship'] }, ], @@ -167,9 +160,6 @@ let mockOpenmrsConfig: RegistrationConfig = { label: 'Male', }, ], - identifier: [ - { identifierTypeSystem: 'MPI OpenMRS ID', identifierTypeUuid: '8d793bee-c2cc-11de-8d13-0010c6dffd0f' }, - ], address: { useAddressHierarchy: { enabled: true, @@ -184,7 +174,7 @@ let mockOpenmrsConfig: RegistrationConfig = { links: { submitButton: '#', }, - defaultPatientIdentifierTypes: ['8d793bee-c2cc-11de-8d13-0010c6dffd0f'], + defaultPatientIdentifierTypes: [], registrationObs: { encounterTypeUuid: null, encounterProviderRoleUuid: 'asdf', @@ -266,24 +256,6 @@ describe('Registering a new patient', () => { ...mockOpenmrsConfig, }); mockSavePatient.mockReturnValue({ data: { uuid: 'new-pt-uuid' }, ok: true }); - mockUseMpiPatient.mockReturnValue({ - isLoading: false, - patient: { data: null }, - error: undefined, - }); - mockUsePatient.mockReturnValue({ - isLoading: false, - patient: null, - patientUuid: null, - error: null, - }); - (useLocation as jest.Mock).mockReturnValue({ - pathname: 'openmrs/spa/patient-registration', - state: undefined, - key: '', - search: '', - hash: '', - }); }); it('renders without crashing', () => { @@ -425,11 +397,7 @@ describe('Updating an existing patient record', () => { const mockUseParams = useParams as jest.Mock; mockUseParams.mockReturnValue({ patientUuid: mockPatient.id }); - mockUseMpiPatient.mockReturnValue({ - isLoading: false, - patient: { data: null }, - error: undefined, - }); + mockUsePatient.mockReturnValue({ isLoading: false, patient: mockPatient, @@ -470,9 +438,6 @@ describe('Updating an existing patient record', () => { '1': { openMrsId: '100GEJ', }, - '2': { - mpiOpenMrsId: '100GEG', - }, addNameInLocalLanguage: undefined, additionalFamilyName: '', additionalGivenName: '', @@ -510,131 +475,3 @@ describe('Updating an existing patient record', () => { ); }); }); - -describe('Import an MPI patient record', () => { - beforeEach(() => { - mockUseConfig.mockReturnValue(mockOpenmrsConfig); - mockSavePatient.mockReturnValue({ data: { uuid: 'new-pt-uuid' }, ok: true }); - (useParams as jest.Mock).mockReturnValue({ patientUuid: undefined }), - (useLocation as jest.Mock).mockReturnValue({ - pathname: 'openmrs/spa/patient-registration', - state: undefined, - key: '', - search: '?sourceRecord=55', - hash: '', - }); - }); - - it('fills patient demographics from MPI patient', async () => { - const user = userEvent.setup(); - mockSavePatient.mockResolvedValue({} as FetchResponse); - - mockUsePatient.mockReturnValue({ - isLoading: false, - patient: null, - patientUuid: null, - error: null, - }); - - mockUseMpiPatient.mockReturnValue({ - isLoading: false, - patient: { data: mockPatient }, - error: undefined, - }); - - const mockOpenmrsFetch = openmrsFetch as jest.Mock; - const mockResponse = { status: 200, data: mockOpenMRSIdentificationNumberIdType }; - mockOpenmrsFetch.mockResolvedValue(mockResponse); - - // eslint-disable-next-line testing-library/no-unnecessary-act - await act(async () => { - render(, { wrapper: Wrapper }); - }); - expect(mockOpenmrsFetch.mock.calls[0][0]).toEqual( - `/ws/rest/v1/patientidentifiertype/8d793bee-c2cc-11de-8d13-0010c6dffd0f`, - ); - - const givenNameInput: HTMLInputElement = screen.getByLabelText(/First Name/); - const familyNameInput: HTMLInputElement = screen.getByLabelText(/Family Name/); - const middleNameInput: HTMLInputElement = screen.getByLabelText(/Middle Name/); - const dateOfBirthInput: HTMLInputElement = screen.getByLabelText(/Date of Birth/i); - const genderInput: HTMLInputElement = screen.getByLabelText(/Male/); - - // assert initial values - expect(givenNameInput.value).toBe('John'); - expect(familyNameInput.value).toBe('Wilson'); - expect(middleNameInput.value).toBeFalsy(); - expect(dateOfBirthInput.value).toBe('04/04/1972'); - expect(genderInput.value).toBe('male'); - - // do some edits - await user.clear(givenNameInput); - await user.clear(middleNameInput); - await user.clear(familyNameInput); - await user.type(givenNameInput, 'Eric'); - await user.type(middleNameInput, 'Johnson'); - await user.type(familyNameInput, 'Smith'); - await user.click(screen.getByText(/Register patient/i)); - - expect(mockSavePatient).toHaveBeenCalledWith( - true, - { - '0': { - oldIdentificationNumber: '100732HE', - }, - '1': { - openMrsId: '100GEJ', - }, - '2': { - mpiOpenMrsId: '100GEG', - }, - addNameInLocalLanguage: undefined, - additionalFamilyName: '', - additionalGivenName: '', - additionalMiddleName: '', - address: {}, - attributes: {}, - birthdate: new Date('1972-04-04T00:00:00.000Z'), - birthdateEstimated: false, - deathCause: '', - nonCodedCauseOfDeath: '', - deathDate: undefined, - deathTime: undefined, - deathTimeFormat: 'AM', - familyName: 'Smith', - gender: expect.stringMatching(/male/i), - givenName: 'Eric', - identifiers: { - 'OpenMRS Identification Number': { - identifierUuid: null, - preferred: false, - initialValue: '100GEG', - identifierValue: '100GEG', - identifierTypeUuid: '8d793bee-c2cc-11de-8d13-0010c6dffd0f', - identifierName: 'OpenMRS Identification Number', - required: false, - selectedSource: null, - autoGeneration: false, - }, - }, - isDead: false, - middleName: 'Johnson', - monthsEstimated: 0, - patientUuid: '8673ee4f-e2ab-4077-ba55-4980f408773e', - relationships: [], - telephoneNumber: '', - unidentifiedPatient: undefined, - yearsEstimated: 0, - }, - expect.anything(), - expect.anything(), - null, - undefined, - expect.anything(), - expect.anything(), - expect.anything(), - { patientSaved: false }, - expect.anything(), - ); - }); -}); diff --git a/packages/esm-patient-search-app/src/compact-patient-search-extension/index.tsx b/packages/esm-patient-search-app/src/compact-patient-search-extension/index.tsx index 3c5c3a6fa..047e7e9e9 100644 --- a/packages/esm-patient-search-app/src/compact-patient-search-extension/index.tsx +++ b/packages/esm-patient-search-app/src/compact-patient-search-extension/index.tsx @@ -8,8 +8,6 @@ import { PatientSearchContext } from '../patient-search-context'; import useArrowNavigation from '../hooks/useArrowNavigation'; import PatientSearch from '../compact-patient-search/patient-search.component'; import styles from './compact-patient-search.scss'; -import { useSearchParams } from 'react-router-dom'; -import { inferModeFromSearchParams } from '../mpi/utils'; interface CompactPatientSearchProps { initialSearchTerm: string; @@ -29,13 +27,7 @@ const CompactPatientSearchComponent: React.FC = ({ const bannerContainerRef = useRef(null); const [searchTerm, setSearchTerm] = useState(initialSearchTerm); const showSearchResults = useMemo(() => !!searchTerm?.trim(), [searchTerm]); - const [searchParams] = useSearchParams(); - const patientSearchResponse = useInfinitePatientSearch( - searchTerm, - inferModeFromSearchParams(searchParams), - config.includeDead, - showSearchResults, - ); + const patientSearchResponse = useInfinitePatientSearch(searchTerm, config.includeDead, showSearchResults); const { data: patients } = patientSearchResponse; const handleChange = useCallback((val) => setSearchTerm(val), [setSearchTerm]); diff --git a/packages/esm-patient-search-app/src/compact-patient-search/compact-patient-search.component.tsx b/packages/esm-patient-search-app/src/compact-patient-search/compact-patient-search.component.tsx index cdeda3f95..7973a5bc9 100644 --- a/packages/esm-patient-search-app/src/compact-patient-search/compact-patient-search.component.tsx +++ b/packages/esm-patient-search-app/src/compact-patient-search/compact-patient-search.component.tsx @@ -10,8 +10,6 @@ import PatientSearch from './patient-search.component'; import PatientSearchBar from '../patient-search-bar/patient-search-bar.component'; import RecentlySearchedPatients from './recently-searched-patients.component'; import styles from './compact-patient-search.scss'; -import { useSearchParams } from 'react-router-dom'; -import { inferModeFromSearchParams } from '../mpi/utils'; interface CompactPatientSearchProps { isSearchPage: boolean; @@ -37,17 +35,13 @@ const CompactPatientSearchComponent: React.FC = ({ const config = useConfig(); const { showRecentlySearchedPatients } = config.search; + const { user, sessionLocation: { uuid: currentLocation }, } = useSession(); - const [searchParams] = useSearchParams(); - const patientSearchResponse = useInfinitePatientSearch( - debouncedSearchTerm, - inferModeFromSearchParams(searchParams), - config.includeDead, - ); + const patientSearchResponse = useInfinitePatientSearch(debouncedSearchTerm, config.includeDead); const { data: searchedPatients } = patientSearchResponse; const { diff --git a/packages/esm-patient-search-app/src/index.ts b/packages/esm-patient-search-app/src/index.ts index 0237fa27d..33c6575e3 100644 --- a/packages/esm-patient-search-app/src/index.ts +++ b/packages/esm-patient-search-app/src/index.ts @@ -6,7 +6,6 @@ import { getSyncLifecycle, makeUrl, messageOmrsServiceWorker, - registerFeatureFlag, setupDynamicOfflineDataHandler, } from '@openmrs/esm-framework'; import { configSchema } from './config-schema'; diff --git a/packages/esm-patient-search-app/src/mpi/utils.ts b/packages/esm-patient-search-app/src/mpi/utils.ts deleted file mode 100644 index 446caae67..000000000 --- a/packages/esm-patient-search-app/src/mpi/utils.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { capitalize } from 'lodash-es'; -import { type SearchedPatient } from '../types'; -import { getCoreTranslation } from '@openmrs/esm-framework'; -export function inferModeFromSearchParams(searchParams: URLSearchParams) { - return searchParams.get('mode')?.toLowerCase() === 'external' ? 'external' : 'internal'; -} - -export function mapToOpenMRSPatient(fhirPatients: Array): Array { - if (fhirPatients[0].total < 1) { - return []; - } - //Consider patient // https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/patient-resource.ts - const pts: Array = []; - - fhirPatients[0].entry.forEach((pt, index) => { - let fhirPatient = pt.resource; - pts.push({ - externalId: fhirPatient.id, - uuid: null, - identifiers: null, - person: { - addresses: fhirPatient?.address?.map((address) => ({ - cityVillage: address.city, - stateProvince: address.state, - country: address.country, - postalCode: address.postalCode, - preferred: false, - address1: '', - })), - age: null, - birthdate: fhirPatient.birthDate, - gender: getCoreTranslation(fhirPatient.gender), - dead: fhirPatient.deceasedBoolean, - deathDate: fhirPatient.deceasedDateTime, - personName: { - display: fhirPatient.name[0].text - ? fhirPatient.name[0].text - : `${fhirPatient.name[0].family} ${fhirPatient.name[0].given[0]}`, - givenName: fhirPatient.name[0].given[0], - familyName: fhirPatient.name[0].family, - middleName: fhirPatient.name[0].given[1], - }, - }, - attributes: [], - }); - }); - - return pts; -} diff --git a/packages/esm-patient-search-app/src/patient-search-button/patient-search-button.test.tsx b/packages/esm-patient-search-app/src/patient-search-button/patient-search-button.test.tsx index c91dc5e5b..99a9c9102 100644 --- a/packages/esm-patient-search-app/src/patient-search-button/patient-search-button.test.tsx +++ b/packages/esm-patient-search-app/src/patient-search-button/patient-search-button.test.tsx @@ -4,7 +4,6 @@ import { render, screen } from '@testing-library/react'; import { getDefaultsFromConfigSchema, launchWorkspace, useConfig } from '@openmrs/esm-framework'; import { type PatientSearchConfig, configSchema } from '../config-schema'; import PatientSearchButton from './patient-search-button.component'; -import { MemoryRouter, Route, Routes } from 'react-router-dom'; const mockUseConfig = jest.mocked(useConfig); const mockedLaunchWorkspace = jest.mocked(launchWorkspace); @@ -39,13 +38,8 @@ describe('PatientSearchButton', () => { it('displays workspace when patient search button is clicked', async () => { const user = userEvent.setup(); - render( - - - } /> - - , - ); + render(); + const searchButton = screen.getByLabelText('Search Patient Button'); await user.click(searchButton); diff --git a/packages/esm-patient-search-app/src/patient-search-page/advanced-patient-search.component.tsx b/packages/esm-patient-search-app/src/patient-search-page/advanced-patient-search.component.tsx index 9f3eb5a4c..2c45f992e 100644 --- a/packages/esm-patient-search-app/src/patient-search-page/advanced-patient-search.component.tsx +++ b/packages/esm-patient-search-app/src/patient-search-page/advanced-patient-search.component.tsx @@ -11,14 +11,12 @@ interface AdvancedPatientSearchProps { query: string; inTabletOrOverlay?: boolean; stickyPagination?: boolean; - searchMode: string; } const AdvancedPatientSearchComponent: React.FC = ({ query, stickyPagination, inTabletOrOverlay, - searchMode, }) => { const [filters, setFilters] = useState(initialState); const filtersApplied = useMemo(() => { @@ -38,7 +36,7 @@ const AdvancedPatientSearchComponent: React.FC = ({ hasMore, isLoading, fetchError, - } = useInfinitePatientSearch(query, searchMode, false, !!query, 50); + } = useInfinitePatientSearch(query, false, !!query, 50); useEffect(() => { if (searchResults?.length === currentPage * 50 && hasMore) { diff --git a/packages/esm-patient-search-app/src/patient-search-page/patient-banner/banner/patient-banner.component.tsx b/packages/esm-patient-search-app/src/patient-search-page/patient-banner/banner/patient-banner.component.tsx index 385b63a40..dfd278042 100644 --- a/packages/esm-patient-search-app/src/patient-search-page/patient-banner/banner/patient-banner.component.tsx +++ b/packages/esm-patient-search-app/src/patient-search-page/patient-banner/banner/patient-banner.component.tsx @@ -1,7 +1,7 @@ import React, { type MouseEvent, useContext, useCallback, useState } from 'react'; import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; -import { Button, ButtonSkeleton, SkeletonIcon, SkeletonText, Tag } from '@carbon/react'; +import { ButtonSkeleton, SkeletonIcon, SkeletonText } from '@carbon/react'; import { age, ConfigurableLink, @@ -15,8 +15,6 @@ import { useConfig, usePatient, useVisit, - navigate, - UserFollowIcon, } from '@openmrs/esm-framework'; import { type PatientSearchConfig } from '../../../config-schema'; import { type SearchedPatient } from '../../../types'; @@ -32,10 +30,9 @@ interface PatientBannerProps { patient: SearchedPatient; patientUuid: string; hideActionsOverflow?: boolean; - isMPIPatient: boolean; } -const PatientBanner: React.FC = ({ patient, patientUuid, hideActionsOverflow, isMPIPatient }) => { +const PatientBanner: React.FC = ({ patient, patientUuid, hideActionsOverflow }) => { const { t } = useTranslation(); const { currentVisit } = useVisit(patientUuid); const { patient: fhirPatient, isLoading } = usePatient(patientUuid); @@ -83,13 +80,6 @@ const PatientBanner: React.FC = ({ patient, patientUuid, hid
{patientName} - {isMPIPatient && ( -
- - 🌐 {'MPI'} - -
- )} = ({ patient, patientUuid, hid patientUuid={patientUuid} /> ) : null} - {isMPIPatient && ( -
- -
- )} - {!isDeceased && !currentVisit && !isMPIPatient && ( + {!isDeceased && !currentVisit && ( = ({ const { t } = useTranslation(); const resultsToShow = inTabletOrOverlay ? 15 : 20; const totalResults = searchResults.length; - const [searchParams] = useSearchParams(); - const searchMode = inferModeFromSearchParams(searchParams); const { results, goTo, totalPages, currentPage, showNextButton, paginated } = usePagination( searchResults, @@ -48,25 +45,23 @@ const PatientSearchComponent: React.FC = ({ const searchResultsView = useMemo(() => { if (!query) { - return ; + return ; } if (isLoading) { - return ; + return ; } if (fetchError) { - return ; + return ; } if (results?.length === 0) { - return ( - - ); + return ; } - return ; - }, [query, isLoading, inTabletOrOverlay, results, fetchError, searchMode]); + return ; + }, [query, isLoading, inTabletOrOverlay, results, fetchError]); return (
= () query={searchParams?.get('query') ?? ''} inTabletOrOverlay={!isDesktop(layout)} stickyPagination - searchMode={inferModeFromSearchParams(searchParams)} />
diff --git a/packages/esm-patient-search-app/src/patient-search-page/patient-search-views.component.tsx b/packages/esm-patient-search-app/src/patient-search-page/patient-search-views.component.tsx index e8d743d56..118cec871 100644 --- a/packages/esm-patient-search-app/src/patient-search-page/patient-search-views.component.tsx +++ b/packages/esm-patient-search-app/src/patient-search-page/patient-search-views.component.tsx @@ -1,8 +1,7 @@ import React from 'react'; import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; -import { Button, Layer, Tile } from '@carbon/react'; -import { navigate, useFeatureFlag } from '@openmrs/esm-framework'; +import { Layer, Tile } from '@carbon/react'; import EmptyDataIllustration from '../ui-components/empty-data-illustration.component'; import PatientBanner, { PatientBannerSkeleton } from './patient-banner/banner/patient-banner.component'; import { type SearchedPatient } from '../types'; @@ -10,14 +9,10 @@ import styles from './patient-search-lg.scss'; interface CommonProps { inTabletOrOverlay: boolean; - searchMode: string; - searchTerm: string; } interface PatientSearchResultsProps { searchResults: SearchedPatient[]; - searchTerm: string; - searchMode: string; } export const EmptyState: React.FC = ({ inTabletOrOverlay }) => { @@ -78,9 +73,8 @@ export const ErrorState: React.FC = ({ inTabletOrOverlay }) => { ); }; -export const SearchResultsEmptyState: React.FC = ({ inTabletOrOverlay, searchMode, searchTerm }) => { +export const SearchResultsEmptyState: React.FC = ({ inTabletOrOverlay }) => { const { t } = useTranslation(); - const isMPIEnabled = useFeatureFlag('mpiFlag'); return ( = ({ inTabletOrOverl

{t('noPatientChartsFoundMessage', 'Sorry, no patient charts were found')}

- {isMPIEnabled ? ( - <> -
-
-
- {searchMode == 'internal' && ( - <> -
-

- {t( - 'trySearchFromClientRegistry', - "Try searching using the patient's unique ID number or search the external registry", - )} -

-
- - - )} - - ) : ( -

- {t('trySearchWithPatientUniqueID', "Try to search again using the patient's unique ID number")} -

- )} +

+ {t('trySearchWithPatientUniqueID', "Try to search again using the patient's unique ID number")} +

); }; -export const PatientSearchResults: React.FC = ({ searchResults, searchMode }) => { - const { t } = useTranslation(); +export const PatientSearchResults: React.FC = ({ searchResults }) => { return (
{searchResults.map((patient, indx) => ( - + ))}
); }; - -function doMPISearch(searchTerm: string) { - navigate({ - to: '${openmrsSpaBase}/search?query=${searchTerm}&mode=external', - templateParams: { searchTerm: searchTerm }, - }); -} diff --git a/packages/esm-patient-search-app/src/patient-search-workspace/patient-search.workspace.tsx b/packages/esm-patient-search-app/src/patient-search-workspace/patient-search.workspace.tsx index e9519047e..c8419cfa2 100644 --- a/packages/esm-patient-search-app/src/patient-search-workspace/patient-search.workspace.tsx +++ b/packages/esm-patient-search-app/src/patient-search-workspace/patient-search.workspace.tsx @@ -4,8 +4,6 @@ import { type PatientSearchConfig } from '../config-schema'; import PatientSearchBar from '../patient-search-bar/patient-search-bar.component'; import { PatientSearchContext, type PatientSearchContextProps } from '../patient-search-context'; import AdvancedPatientSearchComponent from '../patient-search-page/advanced-patient-search.component'; -import { inferModeFromSearchParams } from '../mpi/utils'; -import { useSearchParams } from 'react-router-dom'; export interface PatientSearchWorkspaceProps extends PatientSearchContextProps { initialQuery?: string; @@ -27,7 +25,6 @@ const PatientSearchWorkspace: React.FC = ({ const [searchTerm, setSearchTerm] = useState(initialQuery); const showSearchResults = Boolean(searchTerm?.trim()); const debouncedSearchTerm = useDebounce(searchTerm); - const [searchParams] = useSearchParams(); const handleClearSearchTerm = useCallback(() => setSearchTerm(''), [setSearchTerm]); @@ -44,13 +41,7 @@ const PatientSearchWorkspace: React.FC = ({ onClear={handleClearSearchTerm} onSubmit={onSearchTermChange} /> - {showSearchResults && ( - - )} + {showSearchResults && } ); }; diff --git a/packages/esm-patient-search-app/src/patient-search.resource.tsx b/packages/esm-patient-search-app/src/patient-search.resource.tsx index 547fedb08..bda4ccc82 100644 --- a/packages/esm-patient-search-app/src/patient-search.resource.tsx +++ b/packages/esm-patient-search-app/src/patient-search.resource.tsx @@ -1,15 +1,8 @@ import { useCallback, useMemo } from 'react'; import useSWR from 'swr'; import useSWRInfinite from 'swr/infinite'; -import { - openmrsFetch, - useSession, - type FetchResponse, - restBaseUrl, - fhirBaseUrl, -} from '@openmrs/esm-framework'; +import { openmrsFetch, useSession, type FetchResponse, restBaseUrl } from '@openmrs/esm-framework'; import type { PatientSearchResponse, SearchedPatient, User } from './types'; -import { mapToOpenMRSPatient } from './mpi/utils'; type InfinitePatientSearchResponse = FetchResponse<{ results: Array; @@ -50,7 +43,6 @@ const patientSearchCustomRepresentation = `custom:(${patientProperties.join(',') */ export function useInfinitePatientSearch( searchQuery: string, - searchMode: string, includeDead: boolean, isSearching: boolean = true, resultsToFetch: number = 10, @@ -80,31 +72,14 @@ export function useInfinitePatientSearch( [searchQuery, customRepresentation, includeDead, resultsToFetch], ); - const getExtUrl = useCallback( - ( - page, - prevPageData: FetchResponse<{ results: Array; links: Array<{ rel: 'prev' | 'next' }> }>, - ) => { - if (prevPageData && !prevPageData?.data?.links.some((link) => link.rel === 'next')) { - return null; - } - let url = `${fhirBaseUrl}/Patient/$cr-search?name=${searchQuery}`; - - return url; - }, - [searchQuery, customRepresentation, includeDead, resultsToFetch], - ); - const shouldFetch = isSearching && searchQuery; const { data, isLoading, isValidating, setSize, error, size } = useSWRInfinite( - shouldFetch ? (searchMode == 'external' ? getExtUrl : getUrl) : null, + shouldFetch ? getUrl : null, openmrsFetch, ); - const mappedData = searchMode === 'internal' - ? data?.flatMap((response) => response?.data?.results ?? []) ?? null - : data ? mapToOpenMRSPatient(data.map(response => response?.data)) : null; + const mappedData = data?.flatMap((res) => res.data?.results ?? []) ?? null; return useMemo( () => ({ diff --git a/packages/esm-patient-search-app/src/routes.json b/packages/esm-patient-search-app/src/routes.json index 08ddf95ed..062ee7b8a 100644 --- a/packages/esm-patient-search-app/src/routes.json +++ b/packages/esm-patient-search-app/src/routes.json @@ -35,12 +35,5 @@ "component": "patientSearchWorkspace", "title": "searchPatient" } - ], - "featureFlags": [ - { - "flagName": "mpiFlag", - "label": "MPI Service", - "description": "Enables the Master Patient Index workflows." - } ] } diff --git a/packages/esm-patient-search-app/src/types/index.ts b/packages/esm-patient-search-app/src/types/index.ts index 23ba6e271..ad7507831 100644 --- a/packages/esm-patient-search-app/src/types/index.ts +++ b/packages/esm-patient-search-app/src/types/index.ts @@ -1,7 +1,6 @@ import type { OpenmrsResource } from '@openmrs/esm-framework'; export interface SearchedPatient { - externalId?: string; uuid: string; identifiers: Array; person: { diff --git a/packages/esm-patient-search-app/translations/en.json b/packages/esm-patient-search-app/translations/en.json index 57955f66b..6ab1b0c7b 100644 --- a/packages/esm-patient-search-app/translations/en.json +++ b/packages/esm-patient-search-app/translations/en.json @@ -6,7 +6,6 @@ "clearSearch": "Clear", "closeSearch": "Close Search Panel", "countOfFiltersApplied": "filters applied", - "createPatientRecord": "Create Patient Record", "dayOfBirth": "Day of Birth", "error": "Error", "errorCopy": "Sorry, there was a an error. You can try to reload this page, or contact the site administrator and quote the error code above.", @@ -37,7 +36,6 @@ "searchResultsCount_one": "{{count}} search result", "searchResultsCount_other": "{{count}} search results", "sex": "Sex", - "trySearchFromClientRegistry": "Try searching using the patient's unique ID number or search the external registry", "trySearchWithPatientUniqueID": "Try to search again using the patient's unique ID number", "unknown": "Unknown", "yearOfBirth": "Year of Birth" diff --git a/tools/index.ts b/tools/index.ts index 4ab3560a8..07e8c58c4 100644 --- a/tools/index.ts +++ b/tools/index.ts @@ -1,7 +1,6 @@ export { getByTextWithMarkup, mockPatient, - mockOpenMRSIdentificationNumberIdType, mockPatientWithLongName, mockPatientWithoutFormattedName, patientChartBasePath, diff --git a/tools/test-utils.tsx b/tools/test-utils.tsx index dbebe233c..81aaeb4f5 100644 --- a/tools/test-utils.tsx +++ b/tools/test-utils.tsx @@ -48,33 +48,6 @@ function getByTextWithMarkup(text: RegExp | string) { } } -const mockOpenMRSIdentificationNumberIdType = { - uuid: '8d793bee-c2cc-11de-8d13-0010c6dffd0f', - display: 'OpenMRS Identification Number', - name: 'OpenMRS Identification Number', - description: 'Unique number used in OpenMRS', - format: '', - formatDescription: null, - required: false, - validator: 'org.openmrs.patient.impl.LuhnIdentifierValidator', - locationBehavior: null, - uniquenessBehavior: null, - retired: false, - links: [ - { - rel: 'self', - uri: 'http://localhost/openmrs/ws/rest/v1/patientidentifiertype/8d793bee-c2cc-11de-8d13-0010c6dffd0f', - resourceAlias: 'patientidentifiertype', - }, - { - rel: 'full', - uri: 'http://localhost/openmrs/ws/rest/v1/patientidentifiertype/8d793bee-c2cc-11de-8d13-0010c6dffd0f?v=full', - resourceAlias: 'patientidentifiertype', - }, - ], - resourceVersion: '2.0', -}; - const mockPatient = { resourceType: 'Patient', id: '8673ee4f-e2ab-4077-ba55-4980f408773e', @@ -101,12 +74,6 @@ const mockPatient = { system: 'OpenMRS ID', value: '100GEJ', }, - { - id: '2f0ad7a1-430f-4397-b571-59ea654a52db', - use: 'official', - system: 'MPI OpenMRS ID', - value: '100GEG', - }, ], active: true, name: [ @@ -154,7 +121,6 @@ const patientChartBasePath = `/patient/${mockPatient.id}/chart`; export { getByTextWithMarkup, mockPatient, - mockOpenMRSIdentificationNumberIdType, mockPatientWithLongName, mockPatientWithoutFormattedName, patientChartBasePath,