diff --git a/packages/esm-patient-chart-app/src/clinical-views/components/encounter-list-tabs.component.tsx b/packages/esm-patient-chart-app/src/encounter-list/components/encounter-list-tabs.component.tsx similarity index 82% rename from packages/esm-patient-chart-app/src/clinical-views/components/encounter-list-tabs.component.tsx rename to packages/esm-patient-chart-app/src/encounter-list/components/encounter-list-tabs.component.tsx index 0d2184cbe1..a7eb9370a5 100644 --- a/packages/esm-patient-chart-app/src/clinical-views/components/encounter-list-tabs.component.tsx +++ b/packages/esm-patient-chart-app/src/encounter-list/components/encounter-list-tabs.component.tsx @@ -1,8 +1,8 @@ import React from 'react'; -import { useConfig } from '@openmrs/esm-framework'; +import { useConfig, usePatient, useVisit } from '@openmrs/esm-framework'; import { useTranslation } from 'react-i18next'; import { Tabs, Tab, TabList, TabPanels, TabPanel } from '@carbon/react'; -import { EncounterList } from '../../encounter-list/components/encounter-list.component'; +import { EncounterList } from './encounter-list.component'; import { getMenuItemTabsConfiguration } from '../utils/encounter-list-config-builder'; import styles from './encounter-list-tabs.scss'; import { filter } from '../utils/helpers'; @@ -16,6 +16,8 @@ const EncounterListTabsComponent: React.FC = ({ const { tabDefinitions = [] } = config; const { t } = useTranslation(); const tabsConfig = getMenuItemTabsConfiguration(tabDefinitions); + const patient = usePatient(patientUuid); + const { currentVisit } = useVisit(patientUuid); return (
@@ -37,6 +39,8 @@ const EncounterListTabsComponent: React.FC = ({ launchOptions={tab.launchOptions} headerTitle={tab.headerTitle} description={tab.description} + currentVisit={currentVisit} + deathStatus={patient?.patient?.deceasedBoolean} /> ))} diff --git a/packages/esm-patient-chart-app/src/clinical-views/components/encounter-list-tabs.scss b/packages/esm-patient-chart-app/src/encounter-list/components/encounter-list-tabs.scss similarity index 100% rename from packages/esm-patient-chart-app/src/clinical-views/components/encounter-list-tabs.scss rename to packages/esm-patient-chart-app/src/encounter-list/components/encounter-list-tabs.scss diff --git a/packages/esm-patient-chart-app/src/encounter-list/components/encounter-list.component.tsx b/packages/esm-patient-chart-app/src/encounter-list/components/encounter-list.component.tsx index 69eafecbc7..fdf014a400 100644 --- a/packages/esm-patient-chart-app/src/encounter-list/components/encounter-list.component.tsx +++ b/packages/esm-patient-chart-app/src/encounter-list/components/encounter-list.component.tsx @@ -1,22 +1,13 @@ import React, { useCallback, useMemo, useState } from 'react'; -import { navigate, showModal, showSnackbar } from '@openmrs/esm-framework'; +import { navigate, showModal, showSnackbar, Visit } from '@openmrs/esm-framework'; import { EmptyState } from '@openmrs/esm-patient-common-lib'; import { useTranslation } from 'react-i18next'; import { EncounterListDataTable } from './table.component'; -import { - Button, - Link, - OverflowMenu, - OverflowMenuItem, - DataTableSkeleton, - MenuButton, - MenuItem, - Pagination, -} from '@carbon/react'; +import { Button, Link, OverflowMenu, OverflowMenuItem, DataTableSkeleton, Pagination } from '@carbon/react'; import { Add } from '@carbon/react/icons'; -import { launchEncounterForm } from '../../clinical-views/utils/helpers'; +import { launchEncounterForm } from '../utils/helpers'; import { deleteEncounter } from '../encounter-list.resource'; -import { useEncounterRows, useFormsJson, usePatientDeathStatus } from '../hooks'; +import { useEncounterRows, useFormsJson } from '../hooks'; import styles from './encounter-list.scss'; import { type TableRow, type Encounter, type Mode } from '../types'; @@ -24,7 +15,7 @@ import { type TableRow, type Encounter, type Mode } from '../types'; export interface EncounterListColumn { key: string; header: string; - getValue: (encounter: any) => string; + getValue: (encounter: Encounter) => string; link?: any; } @@ -46,8 +37,10 @@ export interface EncounterListProps { displayText?: string; workspaceWindowSize?: 'minimized' | 'maximized'; }; - filter?: (encounter: any) => boolean; + filter?: (encounter: Encounter) => boolean; afterFormSaveAction?: () => void; + deathStatus?: boolean; + currentVisit: Visit; } export const EncounterList: React.FC = ({ @@ -60,16 +53,15 @@ export const EncounterList: React.FC = ({ filter, launchOptions, afterFormSaveAction, + currentVisit, + deathStatus, }) => { const { t } = useTranslation(); - const { isDead } = usePatientDeathStatus(patientUuid); - const formUuids = useMemo(() => formList.map((form) => form.uuid), [formList]); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); - const { formsJson, isLoading: isLoadingFormsJson } = useFormsJson(formUuids); - + const { formsJson, isLoading: isLoadingFormsJson, error: errorFormJson } = useFormsJson(formList[0].uuid); const { encounters, total, isLoading, onFormSave, mutate } = useEncounterRows( patientUuid, encounterType, @@ -86,7 +78,7 @@ export const EncounterList: React.FC = ({ { label: t('viewEncounter', 'View'), form: { - name: formsJson[0]?.name, + name: formsJson?.name, }, mode: 'view', intent: '*', @@ -94,7 +86,7 @@ export const EncounterList: React.FC = ({ { label: t('editEncounter', 'Edit'), form: { - name: formsJson[0]?.name, + name: formsJson?.name, }, mode: 'edit', intent: '*', @@ -102,7 +94,7 @@ export const EncounterList: React.FC = ({ { label: t('deleteEncounter', 'Delete'), form: { - name: formsJson[0]?.name, + name: formsJson?.name, }, mode: 'delete', intent: '*', @@ -113,9 +105,9 @@ export const EncounterList: React.FC = ({ const createLaunchFormAction = useCallback( (encounter: Encounter, mode: Mode) => () => { - launchEncounterForm(formsJson[0], mode, onFormSave, null, encounter.uuid, null, workspaceWindowSize, patientUuid); + launchEncounterForm(formsJson, currentVisit, mode, onFormSave, encounter.uuid, null, patientUuid); }, - [formsJson, onFormSave, patientUuid, workspaceWindowSize], + [formsJson, onFormSave, patientUuid, currentVisit], ); const handleDeleteEncounter = useCallback( @@ -189,10 +181,7 @@ export const EncounterList: React.FC = ({ tableRow['actions'] = ( {actions.map((actionItem, index) => { - const form = - formsJson.length && actionItem?.form?.name - ? formsJson.find((form) => form.name === actionItem.form.name) - : null; + const form = formsJson && actionItem?.form?.name ? formsJson.name === actionItem.form.name : null; return ( form && ( @@ -205,13 +194,12 @@ export const EncounterList: React.FC = ({ actionItem.mode === 'delete' ? handleDeleteEncounter(encounter.uuid, encounter.encounterType.name) : launchEncounterForm( - form, + formsJson, + currentVisit, actionItem.mode === 'enter' ? 'add' : actionItem.mode, onFormSave, - null, encounter.uuid, actionItem.intent, - workspaceWindowSize, patientUuid, ); }} @@ -233,8 +221,8 @@ export const EncounterList: React.FC = ({ t, handleDeleteEncounter, onFormSave, - workspaceWindowSize, patientUuid, + currentVisit, ]); const headers = useMemo(() => { @@ -247,7 +235,7 @@ export const EncounterList: React.FC = ({ }, [columns, t]); const formLauncher = useMemo(() => { - if (formsJson.length == 1 && !formsJson[0]['availableIntents']?.length) { + if (formsJson && !formsJson['availableIntents']?.length) { return ( ); - } else if (formsJson.length && !(hideFormLauncher ?? isDead)) { - return ( - - {formsJson.map((form, index) => ( - - launchEncounterForm(form, 'add', onFormSave, null, '', '*', workspaceWindowSize, patientUuid) - } - /> - ))} - - ); } return null; - }, [formsJson, hideFormLauncher, isDead, displayText, onFormSave, workspaceWindowSize, patientUuid, t]); + }, [formsJson, displayText, onFormSave, patientUuid, t, currentVisit]); if (isLoading === true || isLoadingFormsJson === true) { return ; @@ -291,7 +265,7 @@ export const EncounterList: React.FC = ({

{t(headerTitle)}

{/* @ts-ignore */} - {!(hideFormLauncher ?? isDead) &&
{formLauncher}
} + {!(hideFormLauncher ?? deathStatus) &&
{formLauncher}
}
= ({ displayText={description} headerTitle={t(headerTitle)} launchForm={ - hideFormLauncher || isDead + hideFormLauncher || deathStatus ? null - : () => - launchEncounterForm(formsJson[0], 'add', onFormSave, null, '', '*', workspaceWindowSize, patientUuid) + : () => launchEncounterForm(formsJson, currentVisit, 'add', onFormSave, '', '*', patientUuid) } /> )} diff --git a/packages/esm-patient-chart-app/src/encounter-list/components/tag.component.tsx b/packages/esm-patient-chart-app/src/encounter-list/components/tag.component.tsx index 335013f43e..bcb69e6dfa 100644 --- a/packages/esm-patient-chart-app/src/encounter-list/components/tag.component.tsx +++ b/packages/esm-patient-chart-app/src/encounter-list/components/tag.component.tsx @@ -1,8 +1,9 @@ import React from 'react'; import { Tag } from '@carbon/react'; -import { getObsFromEncounter, findObs } from '../../clinical-views/utils/helpers'; +import { getObsFromEncounter, findObs } from '../utils/helpers'; +import { Encounter } from '../types'; -export const renderTag = (encounter, concept, statusColorMappings) => { +export const renderTag = (encounter: Encounter, concept: string, statusColorMappings: Record) => { const columnStatus = getObsFromEncounter(encounter, concept); const columnStatusObs = findObs(encounter, concept); diff --git a/packages/esm-patient-chart-app/src/encounter-list/encounter-list.resource.ts b/packages/esm-patient-chart-app/src/encounter-list/encounter-list.resource.ts index fd695b915e..3e9d3a6fa4 100644 --- a/packages/esm-patient-chart-app/src/encounter-list/encounter-list.resource.ts +++ b/packages/esm-patient-chart-app/src/encounter-list/encounter-list.resource.ts @@ -1,8 +1,12 @@ import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; -export function fetchOpenMRSForms(formUuids: string[]) { - const fetch = (uuid) => openmrsFetch(`${restBaseUrl}/form/${uuid}`); - return Promise.all(formUuids.map((uuid) => fetch(uuid))); +export function fetchOpenMRSForms(formUuid: string) { + return openmrsFetch(`${restBaseUrl}/form/${formUuid}`).then(({ data }) => { + if (data.results.length) { + return data.results; + } + return null; + }); } export function fetchPatientRelationships(patientUuid: string) { diff --git a/packages/esm-patient-chart-app/src/encounter-list/hooks/index.ts b/packages/esm-patient-chart-app/src/encounter-list/hooks/index.ts index e71315ff13..fd15cbc4d2 100644 --- a/packages/esm-patient-chart-app/src/encounter-list/hooks/index.ts +++ b/packages/esm-patient-chart-app/src/encounter-list/hooks/index.ts @@ -1,3 +1,2 @@ export * from './useEncounterRows'; export * from './useFormsJson'; -export * from './usePatientDeathStatus'; diff --git a/packages/esm-patient-chart-app/src/encounter-list/hooks/useFormsJson.ts b/packages/esm-patient-chart-app/src/encounter-list/hooks/useFormsJson.ts index cec00329b9..15a693c734 100644 --- a/packages/esm-patient-chart-app/src/encounter-list/hooks/useFormsJson.ts +++ b/packages/esm-patient-chart-app/src/encounter-list/hooks/useFormsJson.ts @@ -1,35 +1,15 @@ -import { useEffect, useState } from 'react'; -import useSWRImmutable from 'swr'; -import { fetchOpenMRSForms } from '../encounter-list.resource'; -import { type FormSchema } from '@openmrs/esm-form-engine-lib'; +import useSWR from 'swr'; -export function useFormsJson(formUuids: string[]) { - const [openmrsForms, setOpenmrsForms] = useState([]); - const { data: responses, isLoading: isLoadingOpenmrsForms } = useSWRImmutable( - formUuids, - fetchOpenMRSForms, - ); +import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; +import { Form } from '../types'; - useEffect(() => { - if (responses?.length) { - setOpenmrsForms( - responses - .map((response, index) => { - const match = - response?.data ?? response?.data?.find((result) => !result.retired && result.name === formUuids[index]); - if (!match) { - console.error('Form not found: ' + formUuids[index]); - return null; - } - return match; - }) - .filter(Boolean), - ); - } - }, [formUuids, responses]); +export function useFormsJson(formUuid: string) { + const url = `${restBaseUrl}/form/${formUuid}`; + const { data, isLoading, error } = useSWR<{ data: Form }, Error>(url, openmrsFetch); return { - formsJson: openmrsForms, - isLoading: isLoadingOpenmrsForms, + formsJson: data?.data ?? null, + isLoading, + error, }; } diff --git a/packages/esm-patient-chart-app/src/encounter-list/hooks/usePatientDeathStatus.ts b/packages/esm-patient-chart-app/src/encounter-list/hooks/usePatientDeathStatus.ts deleted file mode 100644 index 787939c56a..0000000000 --- a/packages/esm-patient-chart-app/src/encounter-list/hooks/usePatientDeathStatus.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework'; -import useSWRImmutable from 'swr'; - -export function usePatientDeathStatus(patientUuid: string) { - const { - data: response, - isLoading, - error, - } = useSWRImmutable(`${restBaseUrl}/person/${patientUuid}?v=custom:(dead)`, openmrsFetch); - - return { - isDead: !isLoading && !error && response ? response?.data?.dead : false, - }; -} diff --git a/packages/esm-patient-chart-app/src/clinical-views/utils/encounter-list-config-builder.ts b/packages/esm-patient-chart-app/src/encounter-list/utils/encounter-list-config-builder.ts similarity index 97% rename from packages/esm-patient-chart-app/src/clinical-views/utils/encounter-list-config-builder.ts rename to packages/esm-patient-chart-app/src/encounter-list/utils/encounter-list-config-builder.ts index fb022c84d3..b2b0947780 100644 --- a/packages/esm-patient-chart-app/src/clinical-views/utils/encounter-list-config-builder.ts +++ b/packages/esm-patient-chart-app/src/encounter-list/utils/encounter-list-config-builder.ts @@ -11,8 +11,8 @@ import { type TabSchema, type ActionProps, type ConditionalActionProps, -} from '../../encounter-list/types'; -import { renderTag } from '../../encounter-list/components/tag.component'; +} from '../types'; +import { renderTag } from '../components/tag.component'; interface FormattedColumn { key: string; diff --git a/packages/esm-patient-chart-app/src/clinical-views/utils/helpers.ts b/packages/esm-patient-chart-app/src/encounter-list/utils/helpers.ts similarity index 90% rename from packages/esm-patient-chart-app/src/clinical-views/utils/helpers.ts rename to packages/esm-patient-chart-app/src/encounter-list/utils/helpers.ts index 7893a82475..ca6766419e 100644 --- a/packages/esm-patient-chart-app/src/clinical-views/utils/helpers.ts +++ b/packages/esm-patient-chart-app/src/encounter-list/utils/helpers.ts @@ -1,33 +1,28 @@ import { launchPatientWorkspace } from '@openmrs/esm-patient-common-lib'; -import { type FormSchema } from '@openmrs/esm-form-engine-lib'; -import { formatDate, parseDate, formatDatetime, type Concept, age } from '@openmrs/esm-framework'; -import { type Observation, type Encounter } from '../../encounter-list/types'; +import { formatDate, parseDate, formatDatetime, type Concept, age, Visit } from '@openmrs/esm-framework'; +import { type Observation, type Encounter, Form } from '../types'; import { esmPatientChartSchema } from '../../config-schema'; import { type TFunction } from 'i18next'; type LaunchAction = 'add' | 'view' | 'edit' | 'embedded-view'; export function launchEncounterForm( - form: FormSchema, + form: Form, + visit: Visit, action: LaunchAction = 'add', onFormSave: () => void, - title?: string, encounterUuid?: string, intent: string = '*', - workspaceWindowSize?: 'minimized' | 'maximized', patientUuid?: string, ) { launchPatientWorkspace('patient-form-entry-workspace', { - workspaceTitle: form.name, + workspaceTitle: form?.name, mutateForm: onFormSave, formInfo: { encounterUuid, - formUuid: form.name, + formUuid: form?.uuid, patientUuid: patientUuid, - visitTypeUuid: '', - visitUuid: '', - visitStartDatetime: '', - visitStopDatetime: '', + visit: visit, additionalProps: { mode: action === 'add' ? 'enter' : action, formSessionIntent: intent, @@ -121,12 +116,13 @@ export function getObsFromEncounter( if (isTrueFalseConcept) { if (typeof obs?.value === 'object') { if ( - (obs?.value?.uuid != esmPatientChartSchema.trueConceptUuid._default && obs?.value?.name?.name !== 'Unknown') || - obs?.value?.name?.name === 'FALSE' + (obs?.value?.uuid != esmPatientChartSchema.trueConceptUuid._default && + obs?.value?.name?.name !== t('Unknown')) || + obs?.value?.name?.name === t('FALSE') ) { - return 'No'; + return t('No'); } else if (obs?.value?.uuid == esmPatientChartSchema.trueConceptUuid._default) { - return 'Yes'; + return t('Yes'); } else { return obs?.value?.name?.name; } diff --git a/packages/esm-patient-chart-app/src/index.ts b/packages/esm-patient-chart-app/src/index.ts index ad5ca42670..ff224919cf 100644 --- a/packages/esm-patient-chart-app/src/index.ts +++ b/packages/esm-patient-chart-app/src/index.ts @@ -27,7 +27,7 @@ import startVisitActionButtonOnPatientSearch from './visit/start-visit-button.co import startVisitFormComponent from './visit/visit-form/visit-form.component'; import stopVisitActionButtonComponent from './actions-buttons/stop-visit.component'; import visitAttributeTagsComponent from './patient-banner-tags/visit-attribute-tags.component'; -import encounterListTabsComponent from './clinical-views/components/encounter-list-tabs.component'; +import encounterListTabsComponent from './encounter-list/components/encounter-list-tabs.component'; // This allows @openmrs/esm-patient-common-lib to be accessed by modules that are not // using webpack. This is used for ngx-formentry. @@ -227,7 +227,7 @@ export const activeVisitActionsComponent = getAsyncLifecycle( { featureName: 'active-visit-actions', moduleName }, ); -export const encounterListTableTabs = getSyncLifecycle(encounterListTabsComponent, { - featureName: 'encounter-list-table-tabs', - moduleName, -}); +export const encounterListTableTabs = getAsyncLifecycle( + () => import('./encounter-list/components/encounter-list-tabs.component'), + { featureName: 'encounter-list-table-tabs', moduleName }, +); diff --git a/packages/esm-patient-chart-app/src/routes.json b/packages/esm-patient-chart-app/src/routes.json index 7baf8b02fa..a988f05e15 100644 --- a/packages/esm-patient-chart-app/src/routes.json +++ b/packages/esm-patient-chart-app/src/routes.json @@ -14,7 +14,7 @@ "offline": true }, { - "name": "encounter-list-table-tabs", + "name": "encounter-list", "component": "encounterListTableTabs", "online": true, "offline": true