From 6249d3963b67519f70fa8d48611d7b910fa06c0b Mon Sep 17 00:00:00 2001 From: CynthiaKamau Date: Wed, 10 Jul 2024 14:31:21 +0300 Subject: [PATCH] OHRI-2295 Update OHRI endpoints to use SWR --- packages/esm-commons-lib/src/api.resource.ts | 144 +++++-------- .../banner-tags/.patient-status-tag.test.tsx | 36 ---- .../patient-status-tag.component.tsx | 25 ++- .../banner-tags/patient-status-tag.test.tsx | 46 ++++ .../banner-tags/patientHivStatus.ts | 44 ---- .../banner-tags/patientStatus.test.ts | 16 -- .../banner-tags/usePatientHivStatus.ts | 16 ++ .../cohort-patient-list/helpers.tsx | 82 +++---- packages/esm-commons-lib/src/config-schema.ts | 142 +++++++++++++ packages/esm-commons-lib/src/constants.ts | 200 ------------------ .../src/hooks/useEncounterRows.ts | 4 +- .../src/hooks/useLastEncounter.ts | 4 +- .../src/hooks/useLastEncounter.tsx | 4 +- .../src/hooks/usePatientDeathStatus.ts | 4 +- .../src/hooks/usePatientList.tsx | 4 +- packages/esm-commons-lib/src/index.ts | 2 +- .../src/tests/mambaReports.test.ts | 34 --- packages/esm-commons-lib/src/types/index.ts | 12 ++ .../esm-ohri-pmtct-app/src/api.resource.ts | 23 +- ...maternal-child-summary-tiles.component.tsx | 39 +--- .../tb-summary-tiles.component.tsx | 37 ++-- 21 files changed, 374 insertions(+), 544 deletions(-) delete mode 100644 packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx create mode 100644 packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.test.tsx delete mode 100644 packages/esm-commons-lib/src/components/banner-tags/patientHivStatus.ts delete mode 100644 packages/esm-commons-lib/src/components/banner-tags/patientStatus.test.ts create mode 100644 packages/esm-commons-lib/src/components/banner-tags/usePatientHivStatus.ts create mode 100644 packages/esm-commons-lib/src/config-schema.ts delete mode 100644 packages/esm-commons-lib/src/tests/mambaReports.test.ts diff --git a/packages/esm-commons-lib/src/api.resource.ts b/packages/esm-commons-lib/src/api.resource.ts index 0cacbd838..d28746489 100644 --- a/packages/esm-commons-lib/src/api.resource.ts +++ b/packages/esm-commons-lib/src/api.resource.ts @@ -1,28 +1,21 @@ -import { openmrsFetch } from '@openmrs/esm-framework'; +import { fhirBaseUrl, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; import dayjs from 'dayjs'; -import { - finalHIVCodeConcept, - finalPositiveHIVValueConcept, - computedHIV_StatusConcept, - encounterRepresentation, - covidOutcomesCohortUUID, -} from './constants'; +import { encounterRepresentation } from './constants'; import useSWR from 'swr'; - -const BASE_WS_API_URL = '/ws/rest/v1/'; -const BASE_FHIR_API_URL = '/ws/fhir2/R4/'; +import { configSchema } from './config-schema'; +import { type ReportDataArray } from './types'; export function fetchLastVisit(uuid: string) { - return openmrsFetch(`/ws/fhir2/R4/Encounter?patient=${uuid}&_sort=-date&_count=1`); + return openmrsFetch(`${fhirBaseUrl}/Encounter?patient=${uuid}&_sort=-date&_count=1`); } export function fetchPatientList(offSet: number = 0, pageSize: number = 10) { - return openmrsFetch(`/ws/fhir2/R4/Patient?_getpagesoffset=${offSet}&_count=${pageSize}&_summary=data`); + return openmrsFetch(`${fhirBaseUrl}/Patient?_getpagesoffset=${offSet}&_count=${pageSize}&_summary=data`); } export function fetchTodayClients() { let date = dayjs().format('YYYY-MM-DD'); - return openmrsFetch(`/ws/fhir2/R4/Encounter?date=${date}`).then(({ data }) => { + return openmrsFetch(`${fhirBaseUrl}/Encounter?date=${date}`).then(({ data }) => { if (data.entry?.length) { return cleanDuplicatePatientReferences(data); } @@ -35,7 +28,7 @@ export function fetchPatientsFromObservationCodeConcept(codeConcept: string, val let startDate = dayjs().subtract(cutOffDays, 'day').format('YYYY-MM-DD'); return openmrsFetch( - `/ws/fhir2/R4/Observation?code=${codeConcept}${valueConcept ? `&value-concept=${valueConcept}` : ''}${ + `${fhirBaseUrl}/Observation?code=${codeConcept}${valueConcept ? `&value-concept=${valueConcept}` : ''}${ cutOffDays ? `&_lastUpdated=ge${startDate}&_lastUpdated=le${endDate}` : '' }`, ).then(({ data }) => { @@ -54,13 +47,13 @@ function cleanDuplicatePatientReferences(data) { patientRefs = Array.from(patientRefs); return Promise.all( patientRefs.map((ref) => { - return openmrsFetch(BASE_FHIR_API_URL + ref); + return openmrsFetch(fhirBaseUrl + ref); }), ); } export function performPatientSearch(query, objectVersion) { - return openmrsFetch(`${BASE_WS_API_URL}/patient?q=${query}${objectVersion ? `&v=${objectVersion}` : ''}`, { + return openmrsFetch(`${restBaseUrl}/patient?q=${query}${objectVersion ? `&v=${objectVersion}` : ''}`, { method: 'GET', }); } @@ -77,27 +70,25 @@ export function getPatients(searchPhrase?: string, offset?: number, pageSize: nu } export async function getCohort(cohortUuid: string, version?: string) { - const { data } = await openmrsFetch( - BASE_WS_API_URL + `cohortm/cohort/${cohortUuid}${version ? `?v=${version}` : ``}`, - ); + const { data } = await openmrsFetch(restBaseUrl + `/cohortm/cohort/${cohortUuid}${version ? `?v=${version}` : ``}`); data.cohortMembers = data.cohortMembers.filter((member) => !member.voided); return data; } export async function getReportingCohort(cohortUuid: string, queryParams?: string[]) { const params = queryParams ? queryParams.join('&') : ''; - const url = params ? `reportingrest/cohort/${cohortUuid}?${params}` : `reportingrest/cohort/${cohortUuid}`; - const { data } = await openmrsFetch(BASE_WS_API_URL + url); + const url = params ? `/reportingrest/cohort/${cohortUuid}?${params}` : `/reportingrest/cohort/${cohortUuid}`; + const { data } = await openmrsFetch(restBaseUrl + url); return data; } export async function getReportingCohortMembers(cohortUuid: string, queryParams?: string[]) { const params = queryParams ? queryParams.join('&') : ''; - const url = params ? `reportingrest/cohort/${cohortUuid}?${params}` : `reportingrest/cohort/${cohortUuid}`; - const { data } = await openmrsFetch(BASE_WS_API_URL + url); + const url = params ? `/reportingrest/cohort/${cohortUuid}?${params}` : `/reportingrest/cohort/${cohortUuid}`; + const { data } = await openmrsFetch(restBaseUrl + url); return Promise.all( data.members.map((member) => { - return openmrsFetch(BASE_WS_API_URL + `patient/${member.uuid}?v=full`); + return openmrsFetch(restBaseUrl + `/patient/${member.uuid}?v=full`); }), ); } @@ -106,8 +97,7 @@ export async function getCohorts(cohortTypeUuid?: string) { const { data: { results, error }, } = await openmrsFetch( - BASE_WS_API_URL + - `cohortm/cohort?v=custom:(uuid,name,voided)${cohortTypeUuid ? `&cohortType=${cohortTypeUuid}` : ''}`, + restBaseUrl + `/cohortm/cohort?v=custom:(uuid,name,voided)${cohortTypeUuid ? `&cohortType=${cohortTypeUuid}` : ''}`, ); if (error) { throw error; @@ -116,7 +106,7 @@ export async function getCohorts(cohortTypeUuid?: string) { } export function addPatientToCohort(patientUuid: string, cohortUuid: string) { - return openmrsFetch(`${BASE_WS_API_URL}cohortm/cohortmember`, { + return openmrsFetch(`${restBaseUrl}/cohortm/cohortmember`, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -130,13 +120,13 @@ export function addPatientToCohort(patientUuid: string, cohortUuid: string) { } export function evictCohortMembership(membershipUuid: string) { - return openmrsFetch(`${BASE_WS_API_URL}cohortm/cohortmember/${membershipUuid}`, { method: 'DELETE' }); + return openmrsFetch(`${restBaseUrl}/cohortm/cohortmember/${membershipUuid}`, { method: 'DELETE' }); } export async function getPatientListsForPatient(patientUuid: string) { const { data: { results, error }, - } = await openmrsFetch(`${BASE_WS_API_URL}cohortm/cohortmember?patient=${patientUuid}&v=full`); + } = await openmrsFetch(`${restBaseUrl}/cohortm/cohortmember?patient=${patientUuid}&v=full`); if (error) { throw error; } @@ -145,7 +135,7 @@ export async function getPatientListsForPatient(patientUuid: string) { export function fetchPatientsFinalHIVStatus(patientUUID: string) { return openmrsFetch( - `/ws/fhir2/R4/Observation?code=${finalHIVCodeConcept}&value-concept=${finalPositiveHIVValueConcept}&patient=${patientUUID}&_sort=-date&_count=1`, + `${fhirBaseUrl}/Observation?code=${configSchema.obsConcepts._default.finalHIVCodeConcept}&value-concept=${configSchema.obsConcepts._default.finalPositiveHIVValueConcept}&patient=${patientUUID}&_sort=-date&_count=1`, ).then(({ data }) => { if (data.entry?.length) { return data.entry[0].resource.valueCodeableConcept.coding[0].display; @@ -160,13 +150,13 @@ export function fetchPatientObservationFromEncounter( observationCode: string, ) { return openmrsFetch( - `/ws/fhir2/R4/Observation?patient=${patientUUID}&encounter=${encounterUUID}&code=${observationCode}&_sort=-date&_count=1`, + `${fhirBaseUrl}/Observation?patient=${patientUUID}&encounter=${encounterUUID}&code=${observationCode}&_sort=-date&_count=1`, ); } export function fetchPatientComputedConcept_HIV_Status(patientUUID: string) { return openmrsFetch( - `/ws/fhir2/R4/Observation?code=${computedHIV_StatusConcept}&value-concept=${computedHIV_StatusConcept}&patient=${patientUUID}&_sort=-date&_count=1`, + `${fhirBaseUrl}/Observation?code=${configSchema.obsConcepts._default.computedHIV_StatusConcept}&value-concept=${configSchema.obsConcepts._default.computedHIV_StatusConcept}&patient=${patientUUID}&_sort=-date&_count=1`, ).then(({ data }) => { if (data.entry?.length) { return data.entry[0].resource.valueCodeableConcept.coding[0].display; @@ -177,7 +167,7 @@ export function fetchPatientComputedConcept_HIV_Status(patientUUID: string) { export function fetchPatientLastEncounter(patientUuid: string, encounterType) { const query = `encounterType=${encounterType}&patient=${patientUuid}`; - return openmrsFetch(`/ws/rest/v1/encounter?${query}&v=${encounterRepresentation}`).then(({ data }) => { + return openmrsFetch(`${restBaseUrl}/encounter?${query}&v=${encounterRepresentation}`).then(({ data }) => { if (data.results.length) { const sortedEncounters = data.results.sort( (firstEncounter, secondEncounter) => @@ -190,26 +180,8 @@ export function fetchPatientLastEncounter(patientUuid: string, encounterType) { }); } -export function fetchPatientCovidOutcome() { - return openmrsFetch(`/ws/rest/v1/reportingrest/cohort/${covidOutcomesCohortUUID}`).then(({ data }) => { - if (data.members?.length) { - let patientRefs = data.members.map((member) => { - return member.uuid; - }); - patientRefs = new Set([...patientRefs]); - patientRefs = Array.from(patientRefs); - return Promise.all( - patientRefs.map((ref) => { - return openmrsFetch(BASE_FHIR_API_URL + '/Person/' + ref); - }), - ); - } - return []; - }); -} - export function fetchConceptNameByUuid(conceptUuid: string) { - return openmrsFetch(`/ws/rest/v1/concept/${conceptUuid}/name?limit=1`).then(({ data }) => { + return openmrsFetch(`${restBaseUrl}/concept/${conceptUuid}/name?limit=1`).then(({ data }) => { if (data.results.length) { const concept = data.results[data.results.length - 1]; return concept.display; @@ -219,7 +191,7 @@ export function fetchConceptNameByUuid(conceptUuid: string) { } export function fetchPatientRelationships(patientUuid: string) { - return openmrsFetch(`${BASE_WS_API_URL}relationship?person=${patientUuid}&v=full`).then(({ data }) => { + return openmrsFetch(`${restBaseUrl}/relationship?person=${patientUuid}&v=full`).then(({ data }) => { if (data.results.length) { return data.results; } @@ -228,35 +200,15 @@ export function fetchPatientRelationships(patientUuid: string) { } export function fetchOpenMRSForms(formNames: string[]) { - const fetch = (name) => openmrsFetch(`/ws/rest/v1/form?q=${name}&v=full`); + const fetch = (name) => openmrsFetch(`${restBaseUrl}/form?q=${name}&v=full`); return Promise.all(formNames.map((name) => fetch(name))); } export function fetchFormsClobData(valueReferences: string[]) { - const fetch = (ref: string) => openmrsFetch(`/ws/rest/v1/clobdata/${ref}`); + const fetch = (ref: string) => openmrsFetch(`${restBaseUrl}/clobdata/${ref}`); return Promise.all(valueReferences?.map((ref) => fetch(ref))); } -export async function fetchMambaReportData(reportId: string) { - try { - const response = await openmrsFetch(`ws/rest/v1/mamba/report?report_id=${reportId}`); - const data = await response.json(); - - if (data && data.results && data.results.length > 0) { - const record = data.results[0].record; - - for (const item of record) { - return item.value ? parseInt(item.value, 10) : 0; - } - } - - return 0; - } catch (error) { - console.error(`Error fetching data for report_id=${reportId}: `, error); - throw new Error(`Error fetching data for report_id=${reportId}: ${error}`); - } -} - export function fetchEtlData( reportType: 'fetchMambaAncData' | 'MotherHivStatus', reportId?: string, @@ -285,10 +237,10 @@ export function fetchEtlData( let endpoint = ''; switch (reportType) { case 'fetchMambaAncData': - endpoint = `/ws/rest/v1/mamba/report?report_id=${reportId}&person_uuid=${patientUuid}`; + endpoint = `${restBaseUrl}/mamba/report?report_id=${reportId}&person_uuid=${patientUuid}`; break; case 'MotherHivStatus': - endpoint = `/ws/rest/v1/mamba/report?report_id=${reportId}&ptracker_id=${pTrackerId}&person_uuid=${patientUuid}`; + endpoint = `${restBaseUrl}/mamba/report?report_id=${reportId}&ptracker_id=${pTrackerId}&person_uuid=${patientUuid}`; break; default: throw new Error('Invalid report type'); @@ -323,19 +275,19 @@ export async function getCohortList( ) { const params = queryParams ? queryParams.join('&') : ''; const cohortMembersUrl = params - ? `reportingrest/cohort/${cohortUuid}?${params}` - : `reportingrest/cohort/${cohortUuid}`; - const cohortUrl = `cohortm/cohort/${cohortUuid}?v=full`; + ? `/reportingrest/cohort/${cohortUuid}?${params}` + : `/reportingrest/cohort/${cohortUuid}`; + const cohortUrl = `/cohortm/cohort/${cohortUuid}?v=full`; const url = isReportingCohort ? cohortMembersUrl : cohortUrl; - const { data } = await openmrsFetch(BASE_WS_API_URL + url); + const { data } = await openmrsFetch(restBaseUrl + url); if (data?.members) { return Promise.all( data.members.map((member) => { return openmrsFetch( - `/ws/rest/v1/encounter?encounterType=${encounterType}&patient=${member.uuid}&v=${encounterRepresentation}`, + `${restBaseUrl}/encounter?encounterType=${encounterType}&patient=${member.uuid}&v=${encounterRepresentation}`, ).then(({ data }) => { if (data.results.length) { const sortedEncounters = data.results.sort( @@ -355,15 +307,14 @@ export async function getCohortList( return Promise.all( data.cohortMembers.map((member) => { return openmrsFetch( - `/ws/rest/v1/encounter?encounterType=${encounterType}&patient=${member.patient.uuid}&v=${encounterRepresentation}`, + `${restBaseUrl}/encounter?encounterType=${encounterType}&patient=${member.patient.uuid}&v=${encounterRepresentation}`, ).then(({ data }) => { if (data.results.length) { - const sortedEncounters = data.results - .sort( - (firstEncounter, secondEncounter) => - new Date(secondEncounter.encounterDatetime).getTime() - - new Date(firstEncounter.encounterDatetime).getTime(), - ); + const sortedEncounters = data.results.sort( + (firstEncounter, secondEncounter) => + new Date(secondEncounter.encounterDatetime).getTime() - + new Date(firstEncounter.encounterDatetime).getTime(), + ); return sortedEncounters[0]; } return null; @@ -372,3 +323,16 @@ export async function getCohortList( ); } } + +export function useMambaReportData(reportId: string) { + const { data, error, isLoading } = useSWR<{ data: { results: ReportDataArray } }, Error>( + `${restBaseUrl}/mamba/report?report_id=${reportId}`, + openmrsFetch, + ); + + return { + data: data?.data?.results[0]?.record[0]?.value ?? 0, + error, + isLoading, + }; +} diff --git a/packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx b/packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx deleted file mode 100644 index d1f7dc74a..000000000 --- a/packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import { render, act, screen } from '@testing-library/react'; -import '@testing-library/jest-dom'; -import { PatientStatusBannerTag } from './patient-status-tag.component'; -import { isPatientHivPositive } from './patientHivStatus'; - -const mockIsPatientHivPositive = isPatientHivPositive as jest.Mock; -jest.mock('./patientHivStatus'); - -describe('PatientStatusBannerTag', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - const hivPositiveSampleUuid = '703AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; - - describe('PatientStatusBannerTag', () => { - it('renders red tag when patient is HIV positive', async () => { - mockIsPatientHivPositive.mockResolvedValue(true); - await act(async () => { - render(); - }); - - expect(screen.getByText(/HIV Positive/i)).toBeInTheDocument(); - }); - }); - - it('does not render red tag when patient is not HIV positive', async () => { - await act(async () => { - (isPatientHivPositive as jest.Mock).mockResolvedValue(false); - render(); - }); - - expect(screen.queryByText('HIV Positive')).not.toBeInTheDocument(); - }); -}); diff --git a/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx b/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx index 8c6a6368b..08a9045ea 100644 --- a/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx +++ b/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx @@ -1,18 +1,25 @@ -import React, { useEffect, useState } from 'react'; +import React from 'react'; import { Tag } from '@carbon/react'; import { useTranslation } from 'react-i18next'; -import { isPatientHivPositive } from './patientHivStatus'; +import { usePatientsFinalHIVStatus } from './usePatientHivStatus'; +import { useConfig } from '@openmrs/esm-framework'; export function PatientStatusBannerTag({ patientUuid }) { const { t } = useTranslation(); - const [hivPositive, setHivPositive] = useState(false); + const { obsConcepts } = useConfig(); + const { isLoading, hivStatus, error } = usePatientsFinalHIVStatus( + patientUuid, + obsConcepts.finalHIVCodeConcept, + obsConcepts.finalPositiveHIVValueConcept, + ); - useEffect(() => { - isPatientHivPositive(patientUuid).then((result) => setHivPositive(result)); - }, [hivPositive, patientUuid]); + if (isLoading) { + return

{t('loading', 'Loading...')}

; + } - //TODO: Improve refresh time - // forceRerender(); + if (error) { + return

{t('error', 'Error...')}

; + } - return <>{hivPositive && {t('hivPositive', 'HIV Positive')}}; + return <>{hivStatus && {t('hivPositive', 'HIV Positive')}}; } diff --git a/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.test.tsx b/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.test.tsx new file mode 100644 index 000000000..6f6336cd0 --- /dev/null +++ b/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.test.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { PatientStatusBannerTag } from './patient-status-tag.component'; +import { usePatientsFinalHIVStatus } from './usePatientHivStatus'; +import { useConfig } from '@openmrs/esm-framework'; + +const mockedUsePatientsFinalHIVStatus = jest.mocked(usePatientsFinalHIVStatus); +const mockUseConfig = jest.mocked(useConfig); + +jest.mock('./usePatientHivStatus', () => { + const originalModule = jest.requireActual('./usePatientHivStatus'); + + return { + ...originalModule, + usePatientsFinalHIVStatus: jest.fn().mockImplementation(() => ({ + hivStatus: true, + isLoading: false, + })), + }; +}); + +describe('PatientStatusBannerTag', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockUseConfig.mockReturnValue({ + obsConcepts: { + finalHIVCodeConcept: 'e16b0068-b6a2-46b7-aba9-e3be00a7b4ab', + finalPositiveHIVValueConcept: '703AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + }, + }); + }); + + const samplePatientUuid = '703AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; + + it('renders red tag when patient is HIV positive', async () => { + render(); + expect(screen.getByText(/HIV Positive/i)).toBeInTheDocument(); + }); + + it('does not render red tag when patient is not HIV positive', async () => { + mockedUsePatientsFinalHIVStatus.mockReturnValue({ hivStatus: false, isLoading: false, error: null }); + render(); + expect(screen.queryByText('HIV Positive')).not.toBeInTheDocument(); + }); +}); diff --git a/packages/esm-commons-lib/src/components/banner-tags/patientHivStatus.ts b/packages/esm-commons-lib/src/components/banner-tags/patientHivStatus.ts deleted file mode 100644 index c3df0b78e..000000000 --- a/packages/esm-commons-lib/src/components/banner-tags/patientHivStatus.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { openmrsFetch } from '@openmrs/esm-framework'; -import { fetchPatientsFinalHIVStatus, fetchPatientComputedConcept_HIV_Status } from '../../api.resource'; - -const fetchPatientHtsEncounters = (patientUuid: string) => { - const htsEncounterRepresentation = - 'custom:(uuid,encounterDatetime,location:(uuid,name),' + - 'encounterProviders:(uuid,provider:(uuid,name)),' + - 'obs:(uuid,obsDatetime,concept:(uuid,name:(uuid,name)),value:(uuid,name:(uuid,name))))'; - const htsRetrospectiveTypeUUID = '79c1f50f-f77d-42e2-ad2a-d29304dde2fe'; - const query = `encounterType=${htsRetrospectiveTypeUUID}&patient=${patientUuid}`; - - return openmrsFetch(`/ws/rest/v1/encounter?${query}&v=${htsEncounterRepresentation}`); -}; - -const isPatientHivPositive = async (patientUuid: string) => { - const hivTestResultConceptUUID = 'de18a5c1-c187-4698-9d75-258605ea07e8'; // Concept: Result of HIV test - - let isHivPositive = false; - let htsTestResult; - - await fetchPatientHtsEncounters(patientUuid).then((encounters) => { - encounters.data.results.forEach((encounter) => { - htsTestResult = encounter.obs.find((observation) => observation.concept.name.uuid === hivTestResultConceptUUID); - - if (htsTestResult && htsTestResult.value.name.uuid === 'ade5ba3f-3c7f-42b1-96d1-cfeb9b446980') { - isHivPositive = true; - } - }); - }); - - const hivFinalStatus = await fetchPatientsFinalHIVStatus(patientUuid); - - const computedConcept = await fetchPatientComputedConcept_HIV_Status(patientUuid); - - if (hivFinalStatus.toLowerCase().includes('positive') || computedConcept.toLowerCase().includes('positive')) { - isHivPositive = true; - } else { - isHivPositive = false; - } - - return isHivPositive; -}; - -export { isPatientHivPositive }; diff --git a/packages/esm-commons-lib/src/components/banner-tags/patientStatus.test.ts b/packages/esm-commons-lib/src/components/banner-tags/patientStatus.test.ts deleted file mode 100644 index 686e2f835..000000000 --- a/packages/esm-commons-lib/src/components/banner-tags/patientStatus.test.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @jest-environment jsdom - */ - -import { isPatientHivPositive } from './patientHivStatus'; - -describe('Patient HIV Status', () => { - it('Should return positive', () => { - let isHivPositive; - isPatientHivPositive('b280078a-c0ce-443b-9997-3c66c63ec2f8').then((result) => { - isHivPositive = result; - - expect(isHivPositive).toBe(true); - }); - }); -}); diff --git a/packages/esm-commons-lib/src/components/banner-tags/usePatientHivStatus.ts b/packages/esm-commons-lib/src/components/banner-tags/usePatientHivStatus.ts new file mode 100644 index 000000000..5cae13a30 --- /dev/null +++ b/packages/esm-commons-lib/src/components/banner-tags/usePatientHivStatus.ts @@ -0,0 +1,16 @@ +import { fhirBaseUrl, openmrsFetch } from '@openmrs/esm-framework'; +import useSWR from 'swr'; + +export function usePatientsFinalHIVStatus( + patientUuid: string, + finalHIVCodeConcept: string, + finalPositiveHIVValueConcept: string, +) { + const url = `${fhirBaseUrl}/Observation?code=${finalHIVCodeConcept}&value-concept=${finalPositiveHIVValueConcept}&patient=${patientUuid}&_sort=-date&_count=1`; + const { data, error, isLoading, mutate } = useSWR<{ data: any }, Error>(url, openmrsFetch); + + const hivStatusResult = data?.data?.entry[0].resource.valueCodeableConcept.coding[0].display; + const hivStatus = hivStatusResult.toLowerCase().includes('positive') ? true : false; + + return { hivStatus: hivStatus, isLoading: isLoading, error: error }; +} diff --git a/packages/esm-commons-lib/src/components/cohort-patient-list/helpers.tsx b/packages/esm-commons-lib/src/components/cohort-patient-list/helpers.tsx index 76394e274..ff609efb4 100644 --- a/packages/esm-commons-lib/src/components/cohort-patient-list/helpers.tsx +++ b/packages/esm-commons-lib/src/components/cohort-patient-list/helpers.tsx @@ -5,9 +5,9 @@ import dayjs from 'dayjs'; import localizedFormat from 'dayjs/plugin/localizedFormat'; import relativeTime from 'dayjs/plugin/relativeTime'; import { AddPatientToListOverflowMenuItem } from '../modals/add-patient-to-list-modal.component'; -import { fetchPatientLastEncounter } from '../../api.resource'; import { launchForm } from '../../utils/ohri-forms-commons'; import { navigate, WorkspaceContainer } from '@openmrs/esm-framework'; +import { useLastEncounter } from '../../hooks/useLastEncounter'; interface PatientMetaConfig { location: { name: string }; @@ -38,23 +38,25 @@ export const LaunchableFormMenuItem = ({ }) => { const [actionText, setActionText] = useState(launchableForm.actionText); const [encounterUuid, setEncounterUuid] = useState(null); - const [isLoading, setIsLoading] = useState(false); const continueEncounterActionText = launchableForm.actionText || 'Continue encounter '; + const { lastEncounter, isLoading } = useLastEncounter(patientUuid, encounterType); useEffect(() => { if (launchableForm.editLatestEncounter && encounterType && !encounterUuid) { - setIsLoading(true); - fetchPatientLastEncounter(patientUuid, encounterType).then((latestEncounter) => { - if (latestEncounter) { - setActionText(continueEncounterActionText); - setEncounterUuid(latestEncounter.uuid); - } - setIsLoading(false); - }); - } else { - setIsLoading(false); + if (!isLoading && lastEncounter) { + setActionText(continueEncounterActionText); + setEncounterUuid(lastEncounter.uuid); + } } - }, [continueEncounterActionText, encounterType, encounterUuid, launchableForm.editLatestEncounter, patientUuid]); + }, [ + continueEncounterActionText, + encounterType, + encounterUuid, + launchableForm.editLatestEncounter, + patientUuid, + lastEncounter, + isLoading, + ]); return ( <> @@ -79,23 +81,25 @@ export const LaunchableFormMenuItem = ({ export const ViewSummaryMenuItem = ({ patientUuid, ViewSummary, encounterType }) => { const [actionText, setActionText] = useState(ViewSummary.actionText); const [encounterUuid, setEncounterUuid] = useState(null); - const [isLoading, setIsLoading] = useState(false); const viewSummaryActionText = ViewSummary.actionText || 'View Summary '; + const { lastEncounter, isLoading } = useLastEncounter(patientUuid, encounterType); useEffect(() => { if (ViewSummary.editLatestEncounter && encounterType && !encounterUuid) { - setIsLoading(true); - fetchPatientLastEncounter(patientUuid, encounterType).then((latestEncounter) => { - if (latestEncounter) { - setActionText(viewSummaryActionText); - setEncounterUuid(latestEncounter.uuid); - } - setIsLoading(false); - }); - } else { - setIsLoading(false); + if (!isLoading && lastEncounter) { + setActionText(viewSummaryActionText); + setEncounterUuid(lastEncounter.uuid); + } } - }, [ViewSummary.editLatestEncounter, encounterType, encounterUuid, patientUuid, viewSummaryActionText]); + }, [ + ViewSummary.editLatestEncounter, + encounterType, + encounterUuid, + isLoading, + lastEncounter, + patientUuid, + viewSummaryActionText, + ]); return ( <> @@ -114,26 +118,29 @@ export const ViewSummaryMenuItem = ({ patientUuid, ViewSummary, encounterType }) ); }; + export const ViewTptSummaryMenuItem = ({ patientUuid, ViewTptSummary, encounterType }) => { const [actionText, setActionText] = useState(ViewTptSummary.actionText); const [encounterUuid, setEncounterUuid] = useState(null); - const [isLoading, setIsLoading] = useState(false); const viewTptSummaryActionText = ViewTptSummary.actionText || 'View Summary '; + const { lastEncounter, isLoading } = useLastEncounter(patientUuid, encounterType); useEffect(() => { if (ViewTptSummary.editLatestEncounter && encounterType && !encounterUuid) { - setIsLoading(true); - fetchPatientLastEncounter(patientUuid, encounterType).then((latestEncounter) => { - if (latestEncounter) { - setActionText(viewTptSummaryActionText); - setEncounterUuid(latestEncounter.uuid); - } - setIsLoading(false); - }); - } else { - setIsLoading(false); + if (!isLoading && lastEncounter) { + setActionText(viewTptSummaryActionText); + setEncounterUuid(lastEncounter.uuid); + } } - }, [ViewTptSummary.editLatestEncounter, encounterType, patientUuid, encounterUuid, viewTptSummaryActionText]); + }, [ + ViewTptSummary.editLatestEncounter, + encounterType, + patientUuid, + encounterUuid, + viewTptSummaryActionText, + isLoading, + lastEncounter, + ]); return ( <> @@ -152,6 +159,7 @@ export const ViewTptSummaryMenuItem = ({ patientUuid, ViewTptSummary, encounterT ); }; + export function consolidatatePatientMeta(rawPatientMeta, form, config: PatientMetaConfig) { const { isDynamicCohort, diff --git a/packages/esm-commons-lib/src/config-schema.ts b/packages/esm-commons-lib/src/config-schema.ts new file mode 100644 index 000000000..2cc157862 --- /dev/null +++ b/packages/esm-commons-lib/src/config-schema.ts @@ -0,0 +1,142 @@ +import { Type } from '@openmrs/esm-framework'; + +export const configSchema = { + encounterTypes: { + _type: Type.Object, + _description: 'Encounter type UUIDs for Covid.', + _default: { + PatnerNotificationEncounterType_UUID: '4dd0ee63-805f-43e9-833c-6386ba97fdc1', + PeadsDisclosureEncounterType_UUID: '390c2f21-c1c4-4246-94ca-a026157cd1db', + ServiceDeliveryEncounterType_UUID: '62ee5922-a229-48d3-a1da-875c1ffa9436', + ContactTracingEncounterType_UUID: '570e9e42-4306-41dc-9bf8-634bbc70a524', + IntimatePartnerEncounterType_UUID: '881fff34-b4a9-4d11-b2f5-a8a23a9f402b', + PatientTracingEncounterType_UUID: '0cd5d4cb-204e-419a-9dd7-1e18e939ce4c', + transferOutEncounterType_UUID: '3044916a-7e5f-478b-9091-803233f27f91', + deathFormEncounterType_UUID: '111c2104-991d-4b58-a30e-ce84bb275534', + hivLabResultsEncounterType_UUID: '15272be5-ae9c-4278-a303-4b8907eae73b', + covidVaccinationEncounterUUID: '5b37ce7a-c55e-4226-bdc8-5af04025a6de', + art_Therapy_EncounterUUID: '74bf4fe6-8fdb-4228-be39-680a93a9cf6d', + covidLabResultsEncounterType_UUID: '253a43d3-c99e-415c-8b78-ee7d4d3c1d54', + covid_Assessment_EncounterUUID: '253a43d3-c99e-415c-8b78-ee7d4d3c1d54', + htsRetrospectiveEncounterType: '79c1f50f-f77d-42e2-ad2a-d29304dde2fe', + covidCaseAssessmentEncType: '253a43d3-c99e-415c-8b78-ee7d4d3c1d54', + covidVaccinationEncType: '5b37ce7a-c55e-4226-bdc8-5af04025a6de', + covidLabTestEncType: 'a77d3e7f-5c8f-4074-a207-77a70e197b0c', + careAndTreatmentEncounterType: '7e54cd64-f9c3-11eb-8e6a-57478ce139b0', + clinicalVisitEncounterType: 'cb0a65a7-0587-477e-89b9-cf2fd144f1d4', + }, + }, + obsConcepts: { + _type: Type.Object, + _description: 'List of observation concept UUIDs related to Covid.', + _default: { + finalHIVCodeConcept: 'e16b0068-b6a2-46b7-aba9-e3be00a7b4ab', + finalPositiveHIVValueConcept: '703AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + computedHIV_StatusConcept: 'a5261998-c635-4e27-870c-e837faf6cf9a', + linkedToCareCodeConcept: 'e8e8fe71-adbb-48e7-b531-589985094d30', + linkedToCareYesValueConcept: '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + // COVID Cohorts + clientsAssessedForCovid: 'ec373b01-4ba3-488e-a322-9dd6a50cfdf7', + covidClientsWithPendingLabResults: '166aa2b1-ce55-4d16-9643-ca9d2e2694ea', + clientsWithoutCovidOutcomes: 'db6c4a18-28c6-423c-9da0-58d19e364a7f', + allCovidAssessments: 'ec373b01-4ba3-488e-a322-9dd6a50cfdf7', + covidVaccinatedClients: 'b5d52da9-10c2-43af-ae23-552acc5e445b', + covid19PositiveClients: '1523b1e5-b6d0-44fb-bd9e-c91bfefb4d1c', + // COVID Concepts + dateSpecimenCollected: '159951AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + covidTestType: '069f6dfe-88c1-4a45-a894-0d99549c8718', + covidOutcome: 'a845f3e6-4432-4de4-9fff-37fa270b1a06', + rapidAntigenResultDate: 'af159c77-bc5d-46dd-90d9-bcbffb22267f', + pcrTestResultDate: '4a77ab44-0323-490e-96be-e168c0e5c9de', + finalCovid19Result: '5da5c21b-969f-41bd-9091-e40d4c707544', + covidOutcomesCohortUUID: 'afb0d950-48fd-44d7-ae2c-79615cd125f0', + // Service Enrollment Concepts + dateOfServiceEnrollmentConcept: '160555AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + patientTypeEnrollmentConcept: '83e40f2c-c316-43e6-a12e-20a338100281', + studyPopulationTypeConcept: 'd3d4ae96-8c8a-43db-a9dc-dac951f5dcb3', + dateOfHIVDiagnosisConcept: '160554AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + entryPointConcept: '160540AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + re_enrolmentDateConcept: '20efadf9-86d3-4498-b3ab-7da4dad9c429', + otherEntryPoint: '161011AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + // Clinical visit + dateOfEncounterConcept: '163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + visitTypeConcept: '8a9809e9-8a0b-4e0e-b1f6-80b0cbbe361b', + regimenConcept: 'dfbe256e-30ba-4033-837a-2e8477f2e7cd', + expressCareProgramStatusConcept: '159832AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', // differentiated Care Services + returnVisitDateConcept: '5096AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', // Next Appointment Date + tbScreeningOutcome: 'c0661c0f-348b-4941-812b-c531a0a67f2e', + // HTS Retrospective + htsRetrospectiveType: '79c1f50f-f77d-42e2-ad2a-d29304dde2fe', + // Covid Case Report + covidReasonsForTestingConcep_UUID: 'ae46f4b1-c15d-4bba-ab41-b9157b82b0ce', // Reasons for testing + covidTestTypeUUID: '069f6dfe-88c1-4a45-a894-0d99549c8718', // SARS2-Cov2 Test Type + covidTestResultUUID: '3f4ee14b-b4ab-4597-9fe9-406883b63d76', // Diagnostic PCR Result + covidOutcomeUUID: 'a845f3e6-4432-4de4-9fff-37fa270b1a06', + covidSpecimenCollectiDate_UUID: '159951AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', // Date specimen collected + covidPatientStatusUUID: 'de3bc9b7-05b5-41b6-a38d-8d2eec646c4f', // Client Health Status + covidTreatementOutConcept_UUID: 'a845f3e6-4432-4de4-9fff-37fa270b1a06', + covidSARS_TestResultConcept_UUID: '89feed9c-1dd9-477a-ab1c-86f5f75f6762', + // Covid Assessment + covidSARS_TestResult_Name_UUID: '0961651c-d52e-41dd-957a-94b9ce08e4eb', + covidReasonsForTestingUUID: '5793ad0f-d726-4918-a1b5-f25f4fb2b857', + covidTreatmenOutConceptName_UUID: '28d43e48-3673-4671-a6b1-3ed45fdfcba6', + covidSpecimentTestDate_UUID: '499df97a-2a34-4562-946a-3c4d5608b67f', + covidTypeofTestConcept_UUID: '069f6dfe-88c1-4a45-a894-0d99549c8718', + covidSymptosConcept_UUID: '', + covidPresentSymptonsConcept_UUID: '244b0dc0-eb1b-46ae-b62a-f580345d4f46', + covidComorbidityPresentConcept_UUID: '166020AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + covidUnderComorbidityConcept_UUID: '0651869c-6e90-48d6-b25c-406270c76bee', + covidPresentSymptonsName_UUID: '12568215-ae1c-42ec-b7e8-8818d2761f46', + covidPatientStatusConcept_UUID: 'de3bc9b7-05b5-41b6-a38d-8d2eec646c4f', + covidEncounterDateTime_UUID: '160753AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + covidSymptomsPresentation: 'de3bc9b7-05b5-41b6-a38d-8d2eec646c4f', + // Covid Lab Order + covidLabOrderDate_UUID: '162078AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + covidLabOrderEncounterType_UUID: 'a77d3e7f-5c8f-4074-a207-77a70e197b0c', + pcrTestResult: '3f4ee14b-b4ab-4597-9fe9-406883b63d76', + rapidTestResult: 'cbcbb029-f11f-4437-9d53-1d0f0a170433', + // Covid Lab Results + covidSpecimenCollectionDate_UUID: '159951AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + covidSpecimentTypeConcept_UUID: 'ae127f82-1861-4165-ac81-8554e5a3aac4', + covidTestResultConcept_UUID: '161934AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + covidRapidTestResultDate_UUID: 'af159c77-bc5d-46dd-90d9-bcbffb22267f', + covidDiagnosticPcrResult_UUID: '3f4ee14b-b4ab-4597-9fe9-406883b63d76', + covidDiagnorticPcrResultDate_UUID: '4a77ab44-0323-490e-96be-e168c0e5c9de', + covidTestStatusConcept_UUID: '6681366c-2174-489a-b951-13a1404935bf', + covidTestResultDate_UUID: '163724AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + // Covid Vaccination + covidVaccinationStatusUUID: '40cb816f-797b-4cb4-a9fb-2727b2373623', // Has the patient been vaccinated + covidVaccinationStatusConcept_UUID: 'de3bc9b7-05b5-41b6-a38d-8d2eec646c4f', // What is the patient status with regard to COVID-19? + covidVaccination1stDoseDateConcept_UUID: 'c297e939-736d-4c37-b3e5-e2da1f3afc1a', // Date of the first dose + covidVaccination1stDoseConcept_UUID: '22f1a70d-e7b7-403b-9a34-f267dace3dc8', // First dose + covidVaccination2ndDoseConcept_UUID: 'ff0f23f6-1104-4e11-bdb8-9bdca74f7889', // Second dose + covidVaccination3rdDoseConcept_UUID: 'de8f8b0e-b11e-4a26-bd3e-bec75f335208', // Third dose + covidVaccination3rdDoseDateConcept_UUID: 'c5f9024e-230f-4e09-8da8-6f4945d6e337', // Date of the third dose + covidVaccinationFinalDoseConcept_UUID: '22f1a70d-e7b7-403b-9a34-f267dace3dc8', + covidVaccinationFinalDoseDateConcept_UUID: 'c5f9024e-230f-4e09-8da8-6f4945d6e337', + }, + }, + cohortTypes: { + _type: Type.Object, + _description: 'Cohort UUIDs for various linelists.', + _default: { + preTestCounsellingCohort: 'e4d801f0-e2fd-11eb-8212-7d7156e00a1f', + waitingForHIVTestCohort: 'cdee0abe-e471-11eb-8212-7d7156e00a1f', + postTestCounsellingCohort: '01af2130-e472-11eb-8212-7d7156e00a1f', + clientsEnrolledToCare: '51bec6f7-df43-426e-a83e-c1ae5501372f', + todayzAppointmentsCT: 'ccbcf6d8-77b7-44a5-bb43-d352478ea4e9', + }, + }, + careSetting: { + _type: Type.String, + _description: 'The care setting uuid', + _default: '6f0c9a92-6f24-11e3-af88-005056821db0', + }, +}; + +export interface ConfigObject { + encounterTypes: Object; + obsConcepts: Object; + cohortTypes: Object; + careSetting: string; +} diff --git a/packages/esm-commons-lib/src/constants.ts b/packages/esm-commons-lib/src/constants.ts index e872b1ff8..e0f2fee43 100644 --- a/packages/esm-commons-lib/src/constants.ts +++ b/packages/esm-commons-lib/src/constants.ts @@ -1,5 +1,3 @@ -export const careSetting = '6f0c9a92-6f24-11e3-af88-005056821db0'; - export const daysDurationUnit = { uuid: '1072AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', display: 'Days', @@ -11,201 +9,3 @@ export const encounterRepresentation = 'patient:(uuid,display,age,identifiers,person),encounterProviders:(uuid,provider:(uuid,name)),' + 'obs:(uuid,obsDatetime,voided,groupMembers,concept:(uuid,name:(uuid,name)),value:(uuid,name:(uuid,name),' + 'names:(uuid,conceptNameType,name))),form:(uuid,name))'; - -// Final HIV Test Result Concepts -export const finalHIVCodeConcept = 'e16b0068-b6a2-46b7-aba9-e3be00a7b4ab'; -export const finalPositiveHIVValueConcept = '703AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const computedHIV_StatusConcept = 'a5261998-c635-4e27-870c-e837faf6cf9a'; - -// Linked to Care Concepts -export const linkedToCareCodeConcept = 'e8e8fe71-adbb-48e7-b531-589985094d30'; -export const linkedToCareYesValueConcept = '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; - -// Cohorts -export const preTestCounsellingCohort = 'e4d801f0-e2fd-11eb-8212-7d7156e00a1f'; -export const waitingForHIVTestCohort = 'cdee0abe-e471-11eb-8212-7d7156e00a1f'; -export const postTestCounsellingCohort = '01af2130-e472-11eb-8212-7d7156e00a1f'; -export const clientsEnrolledToCare = '51bec6f7-df43-426e-a83e-c1ae5501372f'; -export const todayzAppointmentsCT = 'ccbcf6d8-77b7-44a5-bb43-d352478ea4e9'; - -// COVID Cohorts -export const clientsAssessedForCovid = 'ec373b01-4ba3-488e-a322-9dd6a50cfdf7'; -export const covidClientsWithPendingLabResults = '166aa2b1-ce55-4d16-9643-ca9d2e2694ea'; -export const clientsWithoutCovidOutcomes = 'db6c4a18-28c6-423c-9da0-58d19e364a7f'; -export const allCovidAssessments = 'ec373b01-4ba3-488e-a322-9dd6a50cfdf7'; -export const covidVaccinatedClients = 'b5d52da9-10c2-43af-ae23-552acc5e445b'; -export const covid19PositiveClients = '1523b1e5-b6d0-44fb-bd9e-c91bfefb4d1c'; - -// COVID Concepts -export const dateSpecimenCollected = '159951AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const covidTestType = '069f6dfe-88c1-4a45-a894-0d99549c8718'; -export const covidOutcome = 'a845f3e6-4432-4de4-9fff-37fa270b1a06'; -export const rapidAntigenResultDate = 'af159c77-bc5d-46dd-90d9-bcbffb22267f'; -export const pcrTestResultDate = '4a77ab44-0323-490e-96be-e168c0e5c9de'; -export const finalCovid19Result = '5da5c21b-969f-41bd-9091-e40d4c707544'; -export const covidOutcomesCohortUUID = 'afb0d950-48fd-44d7-ae2c-79615cd125f0'; - -// Service Enrollment Concepts -export const careAndTreatmentEncounterType = '7e54cd64-f9c3-11eb-8e6a-57478ce139b0'; -export const dateOfServiceEnrollmentConcept = '160555AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const patientTypeEnrollmentConcept = '83e40f2c-c316-43e6-a12e-20a338100281'; -export const studyPopulationTypeConcept = 'd3d4ae96-8c8a-43db-a9dc-dac951f5dcb3'; -export const dateOfHIVDiagnosisConcept = '160554AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const entryPointConcept = '160540AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const re_enrolmentDateConcept = '20efadf9-86d3-4498-b3ab-7da4dad9c429'; -export const otherEntryPoint = '161011AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; - -// Clinical visit -export const clinicalVisitEncounterType = 'cb0a65a7-0587-477e-89b9-cf2fd144f1d4'; -export const dateOfEncounterConcept = '163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const visitTypeConcept = '8a9809e9-8a0b-4e0e-b1f6-80b0cbbe361b'; -export const regimenConcept = 'dfbe256e-30ba-4033-837a-2e8477f2e7cd'; -export const expressCareProgramStatusConcept = '159832AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; // differentiated Care Services -export const returnVisitDateConcept = '5096AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; // Next Appointment Date -export const tbScreeningOutcome = 'c0661c0f-348b-4941-812b-c531a0a67f2e'; - -// Encounter types -export const htsRetrospectiveEncounterType = '79c1f50f-f77d-42e2-ad2a-d29304dde2fe'; -export const covidCaseAssessmentEncType = '253a43d3-c99e-415c-8b78-ee7d4d3c1d54'; -export const covidVaccinationEncType = '5b37ce7a-c55e-4226-bdc8-5af04025a6de'; -export const covidLabTestEncType = 'a77d3e7f-5c8f-4074-a207-77a70e197b0c'; - -// HTS Retrospective -export const htsRetrospectiveType = '79c1f50f-f77d-42e2-ad2a-d29304dde2fe'; - -// Covid Restrospective -// const covidEncounterUUID = '902839fa-f58c-44a1-95a4-dba62d7263f8'; // Covid Case Report -export const covid_Assessment_EncounterUUID = '253a43d3-c99e-415c-8b78-ee7d4d3c1d54'; -export const covidReasonsForTestingConcep_UUID = 'ae46f4b1-c15d-4bba-ab41-b9157b82b0ce'; // Reasons for testing -export const covidTestTypeUUID = '069f6dfe-88c1-4a45-a894-0d99549c8718'; // SARS2-Cov2 Test Type -export const covidTestResultUUID = '3f4ee14b-b4ab-4597-9fe9-406883b63d76'; // Diagnostic PCR Result -export const covidOutcomeUUID = 'a845f3e6-4432-4de4-9fff-37fa270b1a06'; - -export const covidSpecimenCollectiDate_UUID = '159951AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; // Date specimen collected -export const covidPatientStatusUUID = 'de3bc9b7-05b5-41b6-a38d-8d2eec646c4f'; // Client Health Status - -export const covidTreatementOutConcept_UUID = 'a845f3e6-4432-4de4-9fff-37fa270b1a06'; -export const covidSARS_TestResultConcept_UUID = '89feed9c-1dd9-477a-ab1c-86f5f75f6762'; - -// Covid Assessment -export const covidSARS_TestResult_Name_UUID = '0961651c-d52e-41dd-957a-94b9ce08e4eb'; -export const covidReasonsForTestingUUID = '5793ad0f-d726-4918-a1b5-f25f4fb2b857'; -export const covidTreatmenOutConceptName_UUID = '28d43e48-3673-4671-a6b1-3ed45fdfcba6'; -export const covidSpecimentTestDate_UUID = '499df97a-2a34-4562-946a-3c4d5608b67f'; -export const covidTypeofTestConcept_UUID = '069f6dfe-88c1-4a45-a894-0d99549c8718'; -export const covidSymptosConcept_UUID = ''; -export const covidPresentSymptonsConcept_UUID = '244b0dc0-eb1b-46ae-b62a-f580345d4f46'; -export const covidComorbidityPresentConcept_UUID = '166020AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const covidUnderComorbidityConcept_UUID = '0651869c-6e90-48d6-b25c-406270c76bee'; -export const covidPresentSymptonsName_UUID = '12568215-ae1c-42ec-b7e8-8818d2761f46'; -export const covidPatientStatusConcept_UUID = 'de3bc9b7-05b5-41b6-a38d-8d2eec646c4f'; -export const covidEncounterDateTime_UUID = '160753AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const covidSymptomsPresentation = 'de3bc9b7-05b5-41b6-a38d-8d2eec646c4f'; - -//Covid Lab Order -export const covidLabOrderDate_UUID = '162078AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const covidLabOrderEncounterType_UUID = 'a77d3e7f-5c8f-4074-a207-77a70e197b0c'; -export const pcrTestResult = '3f4ee14b-b4ab-4597-9fe9-406883b63d76'; -export const rapidTestResult = 'cbcbb029-f11f-4437-9d53-1d0f0a170433'; - -//Covid Lab Results -export const covidSpecimenCollectionDate_UUID = '159951AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const covidLabResultsEncounterType_UUID = '253a43d3-c99e-415c-8b78-ee7d4d3c1d54'; -export const covidSpecimentTypeConcept_UUID = 'ae127f82-1861-4165-ac81-8554e5a3aac4'; -export const covidTestResultConcept_UUID = '161934AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const covidRapidTestResultDate_UUID = 'af159c77-bc5d-46dd-90d9-bcbffb22267f'; -export const covidDiagnosticPcrResult_UUID = '3f4ee14b-b4ab-4597-9fe9-406883b63d76'; -export const covidDiagnorticPcrResultDate_UUID = '4a77ab44-0323-490e-96be-e168c0e5c9de'; -export const covidTestStatusConcept_UUID = '6681366c-2174-489a-b951-13a1404935bf'; -export const covidTestResultDate_UUID = '163724AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; - -// Covid Vaccination -export const covidVaccinationEncounterUUID = '5b37ce7a-c55e-4226-bdc8-5af04025a6de'; -export const covidVaccinationStatusUUID = '40cb816f-797b-4cb4-a9fb-2727b2373623'; // Has the patient been vaccinated -export const covidVaccinationStatusConcept_UUID = 'de3bc9b7-05b5-41b6-a38d-8d2eec646c4f'; // What is the patient status with regard to COVID-19? -export const covidVaccination1stDoseDateConcept_UUID = 'c85eb064-5ef7-4ac6-8e56-4749bd58df44'; // What is COVID-19 vaccination date (1st dose)? -export const covidVaccination2ndDoseDateConcept_UUID = '42ee7f5c-fdd3-48c1-8d3a-5c6e248e6cb9'; // What is COVID-19 vaccination date (2nd dose)? -export const covidVaccinationTypeConcept_UUID = 'a31d1148-bbcc-4ad6-a015-8359d66bcfdc'; // What COVID-19 vaccine was administered? -export const covidVaccinationAdministeredConcept_UUID = '1410AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; // Which date COVID-19 vaccine was administered? -export const covidVaccinationNextVacinationDateConcept_UUID = '5096AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const covidVaccinationDose_UUID = '6ec64cb3-e710-4d3e-9db4-38c135966a45'; -export const covidVaccineConcept_UUID = '0cc868bd-e9dd-4b59-b278-f923afe22d82'; - -// HTS HIV -export const hivTestResultConceptUUID = 'e16b0068-b6a2-46b7-aba9-e3be00a7b4ab'; -export const hivTestDateConceptUUID = '140414BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'; -export const htsStrategyUUID = 'f0d85da0-c235-4540-a0d1-63640594f98b'; - -//HIV Art Therapy -export const art_Therapy_EncounterUUID = '74bf4fe6-8fdb-4228-be39-680a93a9cf6d'; -export const artTherapyDateTime_UUID = '159599AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const regimenLine_UUID = '164515AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const refusedTreatment_UUID = 'ac4f3fd1-8a2a-4c5e-a335-3f675b82dd78'; -export const therapyPlanConcept = '7557d77c-172b-4673-9335-67a38657dd01'; -export const artStopDateUUID = '162572AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const switchDateUUID = '164516AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const substitutionDateUUID = '164431AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const dateRestartedUUID = '160738AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const switchReasonUUID = '160568AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const substituteReasonUUID = '160562AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const stopReasonUUID = '163513AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const restartReasonUUID = '161011AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; - -// HIV Lab Results -export const hivLabResultsEncounterType_UUID = ' 15272be5-ae9c-4278-a303-4b8907eae73b'; -export const hivLabTestResultConcept_UUID = ''; -export const hivReasonViralLoadRequest_UUID = '86cc0cfe-bace-4969-94b6-d139f4971d13'; -export const hivReasonCD4Request_UUID = '759e89a6-3260-4aee-9922-86a6301bcff3'; -export const hivDateViralLoadResult_UUID = '163281AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const hivDateViralLoadInterpretation_UUID = '686dc1b2-68b5-4024-b311-bd2f5e3ce394'; -export const hivDateCD4Result_UUID = '159376AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const hivCD4Result_UUID = '657AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const hivCD4Count_UUID = '5497AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; - -//HIV Death -export const hivDeathDate_UUID = '1543AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const causeOFDeath_UUID = 'ef973f1f-557f-4620-acf5-9c4c18bf1eda'; -export const deathSpecific_UUID = 'e329cdf4-4eeb-4821-85ec-80ec4b503de0'; -export const deathFormEncounterType_UUID = '111c2104-991d-4b58-a30e-ce84bb275534'; - -//Transfer Out -export const transferOutEncounterType_UUID = '3044916a-7e5f-478b-9091-803233f27f91'; -export const visitDate_UUID = '163137AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const receivingFacility_UUID = '162724AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const TransferOutDate_UUID = '160649AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const verified_UUID = '797e0073-1f3f-46b1-8b1a-8cdad134d2b3'; - -//Patient Tracing -export const ContactDate_UUID = '160753AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const ContactMethod_UUID = '59c023dd-eed2-4b11-8c34-b88e9439db3c'; -export const ContactOutcome_UUID = 'bc45edbd-11e7-4888-ad7d-4ec3dd8cdcf6'; -export const PatientTracingEncounterType_UUID = '0cd5d4cb-204e-419a-9dd7-1e18e939ce4c'; - -//Intimate Partner -export const IntimatePartnerEncounterType_UUID = '881fff34-b4a9-4d11-b2f5-a8a23a9f402b'; -export const ThreatenedToHurt_UUID = 'bd86f7ee-1d5f-4f5d-aa0f-4680aa6e65cb'; -export const SexuallyMolested_UUID = '1246AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const howOftenThreatened_UUID = '953f6271-57ef-414e-bdba-fe9e0246db58'; -export const howOftenSexuallyMolested_UUID = '1dd53a22-2e8f-425b-8ba4-59172ed3fafe'; - -//Contact Tracing -export const ContactTracingEncounterType_UUID = '570e9e42-4306-41dc-9bf8-634bbc70a524'; -export const ContactTracingDate_UUID = '160753AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const ContactTracingMethod_UUID = '59c023dd-eed2-4b11-8c34-b88e9439db3c'; -export const ContactTracingOutcome_UUID = '36a3e671-9d60-4109-b41f-046f44f4b389'; - -//Service Delivery -export const ServiceDeliveryEncounterType_UUID = '62ee5922-a229-48d3-a1da-875c1ffa9436'; -export const CommunityDSDModel_UUID = '52824cbe-0e4d-4c18-8179-80b5799f34ed'; - -//Peads Disclosure -export const PeadsDisclosureEncounterType_UUID = '390c2f21-c1c4-4246-94ca-a026157cd1db'; -export const DisclosureDate_UUID = '85fbdcc8-8dbc-40a9-b85f-5d1bfe1ab63d'; -export const DisclosureStage_UUID = '573f93e2-12f6-483e-aa6e-14e9b76b311a'; - -//Patner Notification -export const PatnerNotificationEncounterType_UUID = '4dd0ee63-805f-43e9-833c-6386ba97fdc1'; -export const IndexHIVStatus_UUID = '1436AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const PatnerNotificationContactDate_UUID = '160753AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const FirstName_UUID = '166102AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; -export const Relationship_UUID = '85d3b4fe-c1a9-4e27-a86b-dcc1e30c8a93'; diff --git a/packages/esm-commons-lib/src/hooks/useEncounterRows.ts b/packages/esm-commons-lib/src/hooks/useEncounterRows.ts index 15576d277..6dfbcf4e1 100644 --- a/packages/esm-commons-lib/src/hooks/useEncounterRows.ts +++ b/packages/esm-commons-lib/src/hooks/useEncounterRows.ts @@ -1,7 +1,7 @@ import useSWR from 'swr'; import { useCallback, useEffect, useMemo, useState } from 'react'; -import { openmrsFetch } from '@openmrs/esm-framework'; +import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; import { encounterRepresentation } from '../constants'; import { type OpenmrsEncounter } from '../types'; @@ -12,7 +12,7 @@ export function useEncounterRows( afterFormSaveAction: () => void, ) { const [encounters, setEncounters] = useState([]); - const url = `/ws/rest/v1/encounter?encounterType=${encounterType}&patient=${patientUuid}&v=${encounterRepresentation}`; + const url = `${restBaseUrl}/encounter?encounterType=${encounterType}&patient=${patientUuid}&v=${encounterRepresentation}`; const { data: response, diff --git a/packages/esm-commons-lib/src/hooks/useLastEncounter.ts b/packages/esm-commons-lib/src/hooks/useLastEncounter.ts index da6fbf63e..fe8f817a5 100644 --- a/packages/esm-commons-lib/src/hooks/useLastEncounter.ts +++ b/packages/esm-commons-lib/src/hooks/useLastEncounter.ts @@ -1,11 +1,11 @@ -import { openmrsFetch } from '@openmrs/esm-framework'; +import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; import { type OpenmrsEncounter } from '../types'; import { encounterRepresentation } from '../constants'; import useSWR from 'swr'; export function useLastEncounter(patientUuid: string, encounterType: string) { const query = `encounterType=${encounterType}&patient=${patientUuid}&limit=1&order=desc&startIndex=0`; - const endpointUrl = `/ws/rest/v1/encounter?${query}&v=${encounterRepresentation}`; + const endpointUrl = `${restBaseUrl}/encounter?${query}&v=${encounterRepresentation}`; const { data, error, isValidating } = useSWR<{ data: { results: Array } }, Error>( endpointUrl, diff --git a/packages/esm-commons-lib/src/hooks/useLastEncounter.tsx b/packages/esm-commons-lib/src/hooks/useLastEncounter.tsx index da6fbf63e..fe8f817a5 100644 --- a/packages/esm-commons-lib/src/hooks/useLastEncounter.tsx +++ b/packages/esm-commons-lib/src/hooks/useLastEncounter.tsx @@ -1,11 +1,11 @@ -import { openmrsFetch } from '@openmrs/esm-framework'; +import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; import { type OpenmrsEncounter } from '../types'; import { encounterRepresentation } from '../constants'; import useSWR from 'swr'; export function useLastEncounter(patientUuid: string, encounterType: string) { const query = `encounterType=${encounterType}&patient=${patientUuid}&limit=1&order=desc&startIndex=0`; - const endpointUrl = `/ws/rest/v1/encounter?${query}&v=${encounterRepresentation}`; + const endpointUrl = `${restBaseUrl}/encounter?${query}&v=${encounterRepresentation}`; const { data, error, isValidating } = useSWR<{ data: { results: Array } }, Error>( endpointUrl, diff --git a/packages/esm-commons-lib/src/hooks/usePatientDeathStatus.ts b/packages/esm-commons-lib/src/hooks/usePatientDeathStatus.ts index f51385c48..787939c56 100644 --- a/packages/esm-commons-lib/src/hooks/usePatientDeathStatus.ts +++ b/packages/esm-commons-lib/src/hooks/usePatientDeathStatus.ts @@ -1,4 +1,4 @@ -import { openmrsFetch } from '@openmrs/esm-framework'; +import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; import useSWRImmutable from 'swr'; export function usePatientDeathStatus(patientUuid: string) { @@ -6,7 +6,7 @@ export function usePatientDeathStatus(patientUuid: string) { data: response, isLoading, error, - } = useSWRImmutable(`/ws/rest/v1/person/${patientUuid}?v=custom:(dead)`, openmrsFetch); + } = useSWRImmutable(`${restBaseUrl}/person/${patientUuid}?v=custom:(dead)`, openmrsFetch); return { isDead: !isLoading && !error && response ? response?.data?.dead : false, diff --git a/packages/esm-commons-lib/src/hooks/usePatientList.tsx b/packages/esm-commons-lib/src/hooks/usePatientList.tsx index 66bac6d7e..bc3ac3a0c 100644 --- a/packages/esm-commons-lib/src/hooks/usePatientList.tsx +++ b/packages/esm-commons-lib/src/hooks/usePatientList.tsx @@ -1,14 +1,14 @@ import React, { useEffect, useState } from 'react'; import useSWRImmutable from 'swr'; import { type FhirPatientResponse } from '../types'; -import { ConfigurableLink, openmrsFetch } from '@openmrs/esm-framework'; +import { ConfigurableLink, fhirBaseUrl, openmrsFetch } from '@openmrs/esm-framework'; import dayjs from 'dayjs'; import capitalize from 'lodash/capitalize'; import { OverflowMenu } from '@carbon/react'; import { AddPatientToListOverflowMenuItem } from '../components/modals/add-patient-to-list-modal.component'; export function usePatientList(offSet: number, pageSize: number, searchTerm?: string) { - const url = `/ws/fhir2/R4/Patient?_getpagesoffset=${offSet}&_count=${pageSize}${ + const url = `${fhirBaseUrl}/Patient?_getpagesoffset=${offSet}&_count=${pageSize}${ searchTerm ? `&name=${searchTerm}` : '' }&_summary=data`; const [paginatedPatientRows, setPaginatedPatientRows] = useState([]); diff --git a/packages/esm-commons-lib/src/index.ts b/packages/esm-commons-lib/src/index.ts index f4982ca46..b788a8bba 100644 --- a/packages/esm-commons-lib/src/index.ts +++ b/packages/esm-commons-lib/src/index.ts @@ -5,7 +5,7 @@ export * from './constants'; export * from './api.resource'; export * from './types'; export * from './components/banner-tags/patient-status-tag.component'; -export * from './components/banner-tags/patientHivStatus'; +export * from './components/banner-tags/usePatientHivStatus'; export * from './components/data-table/o-table.component'; export * from './components/empty-state/empty-data-illustration.component'; export * from './components/empty-state/empty-state-comingsoon.component'; diff --git a/packages/esm-commons-lib/src/tests/mambaReports.test.ts b/packages/esm-commons-lib/src/tests/mambaReports.test.ts deleted file mode 100644 index e6d0173c3..000000000 --- a/packages/esm-commons-lib/src/tests/mambaReports.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { fetchMambaReportData } from '../api.resource'; -import { openmrsFetch } from '@openmrs/esm-framework'; -import '@testing-library/jest-dom'; - -jest.mock('@openmrs/esm-framework'); - -describe('fetchMambaReportData', () => { - afterEach(() => { - jest.clearAllMocks(); - }); - - test('fetches report data successfully and parses result', async () => { - const reportId = 'test-report-id'; - - const mockResponse: any = { - data: { - results: [ - { - record: [{ value: '0' }], - }, - ], - }, - json: jest.fn().mockResolvedValue({}), - }; - - (openmrsFetch as jest.Mock).mockResolvedValueOnce(mockResponse); - - const result = await fetchMambaReportData(reportId); - - expect(openmrsFetch).toHaveBeenCalledWith(`ws/rest/v1/mamba/report?report_id=${reportId}`); - expect(mockResponse.json).toHaveBeenCalled(); - expect(result).toEqual(0); - }); -}); diff --git a/packages/esm-commons-lib/src/types/index.ts b/packages/esm-commons-lib/src/types/index.ts index a727244ac..89d219fc4 100644 --- a/packages/esm-commons-lib/src/types/index.ts +++ b/packages/esm-commons-lib/src/types/index.ts @@ -238,3 +238,15 @@ export interface PatientListRow { lastVisit?: string; actions?: React.ReactNode; } + +interface RecordItem { + column: string; + value: number; +} + +interface DataObject { + serialId: number; + record: RecordItem[]; +} + +export type ReportDataArray = DataObject[]; diff --git a/packages/esm-ohri-pmtct-app/src/api.resource.ts b/packages/esm-ohri-pmtct-app/src/api.resource.ts index 59c237780..49dacb89e 100644 --- a/packages/esm-ohri-pmtct-app/src/api.resource.ts +++ b/packages/esm-ohri-pmtct-app/src/api.resource.ts @@ -1,12 +1,11 @@ -import { openmrsFetch, getConfig } from '@openmrs/esm-framework'; +import { openmrsFetch, getConfig, restBaseUrl, fhirBaseUrl } from '@openmrs/esm-framework'; import { fetchPatientRelationships } from '@ohri/openmrs-esm-ohri-commons-lib'; import { type Patient, type PatientIdentifier, type Relationship } from './types'; -const BASE_WS_API_URL = '/ws/rest/v1/'; const config = await getConfig('@ohri/openmrs-esm-ohri-pmtct-app'); export function generateIdentifier(source: string) { - return openmrsFetch(`/ws/rest/v1/idgen/identifiersource/${source}/identifier`, { + return openmrsFetch(`${restBaseUrl}/idgen/identifiersource/${source}/identifier`, { headers: { 'Content-Type': 'application/json', }, @@ -16,7 +15,7 @@ export function generateIdentifier(source: string) { } export function savePatient(patient: Patient) { - return openmrsFetch(`/ws/rest/v1/patient`, { + return openmrsFetch(`${restBaseUrl}/patient`, { headers: { 'Content-Type': 'application/json', }, @@ -30,7 +29,7 @@ export function savePatients(patients: Array) { } export function saveRelationship(relationship: Relationship) { - return openmrsFetch('/ws/rest/v1/relationship', { + return openmrsFetch(`${restBaseUrl}/relationship`, { headers: { 'Content-Type': 'application/json', }, @@ -42,7 +41,7 @@ export function saveRelationship(relationship: Relationship) { // Get ANC visits report count with pTrackerID and patientUuid export function getAncVisitCount(pTrackerID: string, patientUuid: string) { return openmrsFetch( - `${BASE_WS_API_URL}reportingrest/dataSet/${config.obsConcepts.ancVisitsReport}?ptracker_id=${pTrackerID}&patient_uuid=${patientUuid}`, + `${restBaseUrl}/reportingrest/dataSet/${config.obsConcepts.ancVisitsReport}?ptracker_id=${pTrackerID}&patient_uuid=${patientUuid}`, ).then(({ data }) => { if (data) { return data; @@ -52,7 +51,7 @@ export function getAncVisitCount(pTrackerID: string, patientUuid: string) { } export function fetchPatientIdentifiers(patientUuid: string) { - return openmrsFetch(`${BASE_WS_API_URL}/patient/${patientUuid}/identifier`).then(({ data }) => { + return openmrsFetch(`${restBaseUrl}/patient/${patientUuid}/identifier`).then(({ data }) => { if (data.results.length) { return data.results; } @@ -61,7 +60,7 @@ export function fetchPatientIdentifiers(patientUuid: string) { } export function saveIdentifier(identifier: PatientIdentifier, patientUuid: string) { - return openmrsFetch(`${BASE_WS_API_URL}patient/${patientUuid}/identifier`, { + return openmrsFetch(`${restBaseUrl}/patient/${patientUuid}/identifier`, { headers: { 'Content-Type': 'application/json', }, @@ -72,7 +71,7 @@ export function saveIdentifier(identifier: PatientIdentifier, patientUuid: strin export function getEstimatedDeliveryDate(patientUuid: string, pTrackerId: string) { return openmrsFetch( - `${BASE_WS_API_URL}reportingrest/dataSet/${config.obsConcepts.eddReport}?ptracker_id=${pTrackerId}&patient_uuid=${patientUuid}`, + `${restBaseUrl}/reportingrest/dataSet/${config.obsConcepts.eddReport}?ptracker_id=${pTrackerId}&patient_uuid=${patientUuid}`, ).then(({ data }) => { if (data) { return data; @@ -83,7 +82,7 @@ export function getEstimatedDeliveryDate(patientUuid: string, pTrackerId: string export function getIdentifierInfo(identifier: string) { return openmrsFetch( - `${BASE_WS_API_URL}patient?identifier=${identifier}&v=custom:(identifiers:(identifier,identifierType:(uuid,display)),person:(uuid,display))`, + `${restBaseUrl}/patient?identifier=${identifier}&v=custom:(identifiers:(identifier,identifierType:(uuid,display)),person:(uuid,display))`, ).then(({ data }) => { if (data) { return data; @@ -94,7 +93,7 @@ export function getIdentifierInfo(identifier: string) { export function fetchMotherHIVStatus(patientUuid: string, pTrackerId: string) { return openmrsFetch( - `${BASE_WS_API_URL}reportingrest/dataSet/${config.obsConcepts.motherHivStatusReport}?person_uuid=${patientUuid}&ptracker_id=${pTrackerId}`, + `${restBaseUrl}/reportingrest/dataSet/${config.obsConcepts.motherHivStatusReport}?person_uuid=${patientUuid}&ptracker_id=${pTrackerId}`, ).then(({ data }) => { if (data) { return data; @@ -109,7 +108,7 @@ export function fetchChildLatestFinalOutcome(childUuid: string, conceptUuid: str }`; // the latest obs params += '&_sort=-_lastUpdated&_count=1'; - return openmrsFetch(`/ws/fhir2/R4/Observation?${params}`).then(({ data }) => { + return openmrsFetch(`${fhirBaseUrl}/Observation?${params}`).then(({ data }) => { return data.entry?.length ? data.entry[0].resource.valueCodeableConcept.coding[0]?.display : null; }); } diff --git a/packages/esm-ohri-pmtct-app/src/pmtct/home-dashboard/maternal-child-summary-tiles.component.tsx b/packages/esm-ohri-pmtct-app/src/pmtct/home-dashboard/maternal-child-summary-tiles.component.tsx index fe330eebb..2359e4272 100644 --- a/packages/esm-ohri-pmtct-app/src/pmtct/home-dashboard/maternal-child-summary-tiles.component.tsx +++ b/packages/esm-ohri-pmtct-app/src/pmtct/home-dashboard/maternal-child-summary-tiles.component.tsx @@ -1,34 +1,13 @@ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { OHRIProgrammeSummaryTiles, fetchMambaReportData } from '@ohri/openmrs-esm-ohri-commons-lib'; +import { OHRIProgrammeSummaryTiles, useMambaReportData } from '@ohri/openmrs-esm-ohri-commons-lib'; function MaternalChildSummaryTiles() { const { t } = useTranslation(); - const [totalPregnantWomen, setTotalPregnantWomen] = useState(null); - const [totalDeliveries, setTotalDeliveries] = useState(null); - const [hivExposedInfants, setHivExposedInfants] = useState(null); - - useEffect(() => { - const fetchData = async () => { - try { - const [totalPregnantWomenCount, totalDeliveriesCount, hivExposedInfantsCount] = await Promise.all([ - fetchMambaReportData('total_pregnant_women'), - fetchMambaReportData('total_deliveries'), - fetchMambaReportData('total_hiv_exposed_infants'), - ]); - - setTotalPregnantWomen(totalPregnantWomenCount); - setTotalDeliveries(totalDeliveriesCount); - setHivExposedInfants(hivExposedInfantsCount); - } catch (error) { - console.error('Error fetching data:', error); - throw new Error('Error fetching data. Please try again.'); - } - }; - - fetchData(); - }, []); + const { data: pregnant_women, isLoading: loadingPregnancies } = useMambaReportData('total_pregnant_women'); + const { data: deliveries, isLoading: loadingDeliveries } = useMambaReportData('total_deliveries'); + const { data: hiv_exposed_infants, isLoading: loadingInfants } = useMambaReportData('total_hiv_exposed_infants'); const tiles = useMemo( () => [ @@ -36,22 +15,22 @@ function MaternalChildSummaryTiles() { title: t('anc', 'ANC'), linkAddress: '#', subTitle: t('pregnantWomenAttendingFirstANC', '# Pregnant women attending first ANC'), - value: totalPregnantWomen, + value: loadingPregnancies ? '--' : pregnant_women, }, { title: t('labourDelivery', 'Labour & Delivery'), linkAddress: '#', subTitle: t('totalDeliveries', '# Total deliveries'), - value: totalDeliveries, + value: loadingDeliveries ? '--' : deliveries, }, { title: t('children', 'Children'), linkAddress: '#', subTitle: t('hivExposedChildrenEnrolledInFollowUpCare', '# HIV Exposed children enrolled in follow up care'), - value: hivExposedInfants, + value: loadingInfants ? '--' : hiv_exposed_infants, }, ], - [t, totalPregnantWomen, totalDeliveries, hivExposedInfants], + [t, loadingPregnancies, pregnant_women, loadingDeliveries, deliveries, loadingInfants, hiv_exposed_infants], ); return ; } diff --git a/packages/esm-tb-app/src/tb/dashboard/summary-tiles/tb-summary-tiles.component.tsx b/packages/esm-tb-app/src/tb/dashboard/summary-tiles/tb-summary-tiles.component.tsx index 6a44985da..46b4dc63e 100644 --- a/packages/esm-tb-app/src/tb/dashboard/summary-tiles/tb-summary-tiles.component.tsx +++ b/packages/esm-tb-app/src/tb/dashboard/summary-tiles/tb-summary-tiles.component.tsx @@ -1,30 +1,17 @@ -import React, { useEffect, useMemo, useState } from 'react'; -import { OHRIProgrammeSummaryTiles, fetchMambaReportData } from '@ohri/openmrs-esm-ohri-commons-lib'; +import React, { useMemo } from 'react'; +import { OHRIProgrammeSummaryTiles, useMambaReportData } from '@ohri/openmrs-esm-ohri-commons-lib'; import { useTranslation } from 'react-i18next'; +interface ReportData { + total_active_ds_cases: number; + total_active_dr_cases: number; +} + function TbSummaryTiles() { const { t } = useTranslation(); - const [activeDSClientsCount, setActiveDSClientsCount] = useState(null); - const [activeDRClientsCount, setActiveDRClientsCount] = useState(null); - - useEffect(() => { - const fetchData = async () => { - try { - const [dsCount, drCount] = await Promise.all([ - fetchMambaReportData('total_active_ds_cases'), - fetchMambaReportData('total_active_dr_cases'), - ]); - - setActiveDSClientsCount(dsCount); - setActiveDRClientsCount(drCount); - } catch (error) { - console.error('Error fetching data:', error); - throw new Error('Error fetching data. Please try again.'); - } - }; - fetchData(); - }, []); + const { data: active_ds_cases, isLoading: loadingDsCases } = useMambaReportData('total_active_ds_cases'); + const { data: active_dr_cases, isLoading: loadingDrCases } = useMambaReportData('total_active_dr_cases'); const tiles = useMemo( () => [ @@ -32,16 +19,16 @@ function TbSummaryTiles() { title: t('activeDsCases', 'Active DS Cases'), linkAddress: '#', subTitle: t('drugSensitive', 'Cases with drug sesnsitive TB'), - value: activeDSClientsCount, + value: loadingDsCases ? '--' : active_ds_cases, }, { title: t('activeDrCases', 'Active DR Cases'), linkAddress: '#', subTitle: t('drugResistant', 'Cases with drug resistant TB'), - value: activeDRClientsCount, + value: loadingDrCases ? '--' : active_dr_cases, }, ], - [t, activeDSClientsCount, activeDRClientsCount], + [t, active_dr_cases, active_ds_cases, loadingDsCases, loadingDrCases], ); return ;