-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from PIH/SL-833
(feat) SL-833 add triage actions to queue entries in triage queue table
- Loading branch information
Showing
10 changed files
with
444 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { restBaseUrl, useOpenmrsFetchAll } from '@openmrs/esm-framework'; | ||
import { type Encounter } from '../service-queues-app/types'; | ||
|
||
interface EncounterSearchParams { | ||
patient: string; | ||
visit?: string; | ||
encounterType?: string; | ||
} | ||
|
||
export function useEncounters(params: EncounterSearchParams) { | ||
const url = `${restBaseUrl}/encounter?`; | ||
const searchParams = new URLSearchParams(); | ||
searchParams.append('patient', params.patient); | ||
if (params.visit) { | ||
searchParams.append('visit', params.visit); | ||
} | ||
if (params.encounterType) { | ||
searchParams.append('encounterType', params.encounterType); | ||
} | ||
|
||
return useOpenmrsFetchAll<Encounter>(url + searchParams.toString()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
packages/esm-commons-app/src/service-queues-app/maternal-triage-form.workspace.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { type DefaultWorkspaceProps, type Patient, showSnackbar } from '@openmrs/esm-framework'; | ||
import React, { useEffect } from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import O2IFrame from '../ward-app/o2-iframe.component'; | ||
import { updateQueueEntry, useMutateQueueEntries } from './maternal-triage-queue-actions.resource'; | ||
import { type QueueEntry } from './types'; | ||
import { useEncounters } from '../hooks/useEncounters'; | ||
import { Loading } from '@carbon/react'; | ||
import { InlineNotification } from '@carbon/react'; | ||
|
||
interface MaternalTriageFormWorkspaceProps extends DefaultWorkspaceProps { | ||
queueEntry: QueueEntry; | ||
patient: Patient; | ||
} | ||
|
||
const MATERNAL_TRIAGE_FORM_ENCOUNTER_TYPE = '41911448-71a1-43d7-bba8-dc86339850da'; | ||
|
||
/** | ||
* Workspace to display the Maternal Triage HTML Form, rendered in a iframe | ||
*/ | ||
const MaternalTriageFormWorkspace: React.FC<MaternalTriageFormWorkspaceProps> = ({ | ||
queueEntry, | ||
patient, | ||
closeWorkspace, | ||
}) => { | ||
const { t } = useTranslation(); | ||
const { mutateQueueEntries } = useMutateQueueEntries(); | ||
const { | ||
data: filledOutTriageForms, | ||
isLoading, | ||
error, | ||
} = useEncounters({ | ||
patient: patient.uuid, | ||
visit: queueEntry.visit.uuid, | ||
encounterType: MATERNAL_TRIAGE_FORM_ENCOUNTER_TYPE, | ||
}); | ||
|
||
useEffect(() => { | ||
const onMessage = async (event: MessageEvent) => { | ||
if (event.data == 'triageFormSubmitted') { | ||
const endQueueEntry = () => { | ||
return updateQueueEntry(queueEntry.uuid, { | ||
endedAt: new Date().toISOString(), | ||
}); | ||
}; | ||
|
||
await endQueueEntry(); | ||
await mutateQueueEntries(); | ||
closeWorkspace(); | ||
showSnackbar({ | ||
isLowContrast: true, | ||
kind: 'success', | ||
title: t('triageFormSubmitted', 'Triage form successfully submitted for {{patient}}.', { | ||
patient: patient.person.display, | ||
}), | ||
}); | ||
} | ||
}; | ||
|
||
window.addEventListener('message', onMessage); | ||
return () => window.removeEventListener('message', onMessage); | ||
}, []); | ||
|
||
const patientUuid = patient.uuid; | ||
const visitUuid = queueEntry.visit.id; | ||
|
||
const elementsToHide = [ | ||
'header', | ||
'#breadcrumbs', | ||
|
||
// prevent O2 success toast from showing; After submitting form for a patient, | ||
// the success toast for that patient shows when opening form for another patient | ||
'.toast-type-success', | ||
]; | ||
|
||
const customJavaScript = ` | ||
htmlForm.setSuccessFunction(() => window.top.postMessage('triageFormSubmitted')) | ||
`; | ||
|
||
if (isLoading) { | ||
return <Loading withOverlay={false} small />; | ||
} else if (error) { | ||
return ( | ||
<InlineNotification | ||
kind="error" | ||
lowContrast={true} | ||
hideCloseButton={true} | ||
title={t('errorLoadingPatientForm', 'Error loading patient form')} | ||
/> | ||
); | ||
} else { | ||
// If patient does not have triage form filled out already, we load a new one, | ||
// else, we load the last filled out form to edit | ||
const src = | ||
filledOutTriageForms.length == 0 | ||
? `${window.openmrsBase}/htmlformentryui/htmlform/enterHtmlFormWithStandardUi.page?patientId=${patientUuid}&visitId=${visitUuid}&definitionUiResource=file:configuration/pih/htmlforms/triage.xml&returnUrl=%2Fopenmrs%2Fcoreapps%2Fclinicianfacing%2Fpatient.page%3FpatientId%3D${patientUuid}%26` | ||
: `${window.openmrsBase}/htmlformentryui/htmlform/editHtmlFormWithStandardUi.page?patientId=${patientUuid}&encounterId=${filledOutTriageForms[filledOutTriageForms.length - 1].uuid}`; | ||
|
||
return <O2IFrame key={patientUuid} src={src} elementsToHide={elementsToHide} customJavaScript={customJavaScript} />; | ||
} | ||
}; | ||
|
||
export default MaternalTriageFormWorkspace; |
131 changes: 131 additions & 0 deletions
131
packages/esm-commons-app/src/service-queues-app/maternal-triage-queue-actions.extension.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import { Button, OverflowMenu, OverflowMenuItem } from '@carbon/react'; | ||
import { isDesktop, launchWorkspace, showModal, useConfig, useLayoutType } from '@openmrs/esm-framework'; | ||
import React from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import styles from './maternal-trial-queue-actions.scss'; | ||
import { type QueueEntry } from './types'; | ||
import { transitionQueueEntry, useMutateQueueEntries } from './maternal-triage-queue-actions.resource'; | ||
|
||
// types taken from esm-service-queues-app | ||
interface QueueTableCellComponentProps { | ||
queueEntry: QueueEntry; | ||
} | ||
|
||
interface ConfigObject { | ||
concepts: { | ||
defaultTransitionStatus: string; | ||
}; | ||
// other fields not shown | ||
} | ||
|
||
/** | ||
* This extension provides an extra "Triage" action, along with the other standard actions for | ||
* queue entries in the queues table. The Triage action opens the maternal triage form, and also | ||
* has the side effect of putting the patient's queue entry into the "in service" status, if they have | ||
* not yet already | ||
* @param param0 | ||
* @returns | ||
*/ | ||
const MaternalTriageQueueActions: React.FC<QueueTableCellComponentProps> = ({ queueEntry }) => { | ||
const { t } = useTranslation(); | ||
const layout = useLayoutType(); | ||
|
||
const { mutateQueueEntries } = useMutateQueueEntries(); | ||
const { concepts } = useConfig<ConfigObject>({ externalModuleName: '@openmrs/esm-service-queues-app' }); | ||
const inServiceStatus = concepts.defaultTransitionStatus; | ||
|
||
const { patient } = queueEntry; | ||
|
||
return ( | ||
<div className={styles.actionsCell}> | ||
<Button | ||
kind="ghost" | ||
aria-label={t('triage', 'Triage')} | ||
onClick={async () => { | ||
if (queueEntry.status.uuid !== inServiceStatus) { | ||
const res = await transitionQueueEntry({ | ||
queueEntryToTransition: queueEntry.uuid, | ||
newStatus: inServiceStatus, | ||
}); | ||
mutateQueueEntries(); | ||
launchWorkspace('maternal-triage-form-workspace', { queueEntry: res.data, patient }); | ||
} else { | ||
launchWorkspace('maternal-triage-form-workspace', { queueEntry, patient }); | ||
} | ||
}} | ||
size={isDesktop(layout) ? 'sm' : 'lg'}> | ||
{t('triage', 'Triage')} | ||
</Button> | ||
|
||
<OverflowMenu aria-label="Actions menu" size={isDesktop(layout) ? 'sm' : 'lg'} align="left" flipped> | ||
<OverflowMenuItem | ||
className={styles.menuItem} | ||
aria-label={t('transition', 'Transition')} | ||
hasDivider | ||
onClick={() => { | ||
const dispose = showModal('transition-queue-entry-modal', { | ||
closeModal: () => dispose(), | ||
queueEntry, | ||
}); | ||
}} | ||
itemText={t('transition', 'Transition')} | ||
/> | ||
<OverflowMenuItem | ||
className={styles.menuItem} | ||
aria-label={t('edit', 'Edit')} | ||
hasDivider | ||
onClick={() => { | ||
const dispose = showModal('edit-queue-entry-modal', { | ||
closeModal: () => dispose(), | ||
queueEntry, | ||
}); | ||
}} | ||
itemText={t('edit', 'Edit')} | ||
/> | ||
<OverflowMenuItem | ||
className={styles.menuItem} | ||
aria-label={t('removePatient', 'Remove patient')} | ||
hasDivider | ||
onClick={() => { | ||
const dispose = showModal('end-queue-entry-modal', { | ||
closeModal: () => dispose(), | ||
queueEntry, | ||
}); | ||
}} | ||
itemText={t('removePatient', 'Remove patient')} | ||
/> | ||
{queueEntry.previousQueueEntry == null ? ( | ||
<OverflowMenuItem | ||
className={styles.menuItem} | ||
aria-label={t('delete', 'Delete')} | ||
hasDivider | ||
isDelete | ||
onClick={() => { | ||
const dispose = showModal('void-queue-entry-modal', { | ||
closeModal: () => dispose(), | ||
queueEntry, | ||
}); | ||
}} | ||
itemText={t('delete', 'Delete')} | ||
/> | ||
) : ( | ||
<OverflowMenuItem | ||
className={styles.menuItem} | ||
aria-label={t('undoTransition', 'Undo transition')} | ||
hasDivider | ||
isDelete | ||
onClick={() => { | ||
const dispose = showModal('undo-transition-queue-entry-modal', { | ||
closeModal: () => dispose(), | ||
queueEntry, | ||
}); | ||
}} | ||
itemText={t('undoTransition', 'Undo transition')} | ||
/> | ||
)} | ||
</OverflowMenu> | ||
</div> | ||
); | ||
}; | ||
|
||
export default MaternalTriageQueueActions; |
Oops, something went wrong.