Skip to content

Commit

Permalink
(feat) O3-3737: Add configurable details about pending orders on the …
Browse files Browse the repository at this point in the history
…patient card (#1296)

* feat: configure pending orders

* chore: translations

* rename pending-orders to pending-items slot name
  • Loading branch information
usamaidrsk authored Sep 1, 2024
1 parent 4bff4b7 commit ba179e4
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Type } from '@openmrs/esm-framework';

export const pendingOrdersExtensionConfigSchema = {
orderTypes: {
_type: Type.Array,
_description: 'Defines order types displayed on the ward patient card pending items section.',
_default: [{ label: 'Labs', uuid: '52a447d3-a64a-11e3-9aeb-50e549534c5e' }],
_elements: {
uuid: {
_type: Type.UUID,
_description: 'Identifies the order type.',
},
label: {
_type: Type.String,
_description: "The label or i18n key to the translated label to display. If not provided, defaults to 'Orders'",
_default: null,
},
},
},
enabled: {
_type: Type.Boolean,
_description: 'Optional. Enable pending order visibility on ward card pending items',
_default: true,
},
};
9 changes: 9 additions & 0 deletions packages/esm-ward-app/src/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,20 @@ export interface WardConfigObject {

export interface WardPatientCardsConfig {
obsElementDefinitions: Array<ObsElementDefinition>;
pendingOrderTypesDefinitions: Array<PendingOrderTypesDefinition>;
identifierElementDefinitions: Array<IdentifierElementDefinition>;
addressElementDefinitions: Array<AddressElementDefinition>;
cardDefinitions: Array<WardPatientCardDefinition>;
}

export interface PendingOrderTypesDefinition {
enabled: boolean;
orderTypes: Array<{
label?: string;
uuid: string;
}>;
}

export interface ObsElementDefinition {
id: string;
conceptUuid: string;
Expand Down
16 changes: 16 additions & 0 deletions packages/esm-ward-app/src/hooks/usePatientPendingOrders.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { type FetchResponse, openmrsFetch, type OpenmrsResource, restBaseUrl } from '@openmrs/esm-framework';
import useSWR from 'swr';

export function usePatientPendingOrders(patientUuid: string, orderTypeUUid: string, visitStartDate: string) {
const apiUrl =
patientUuid && orderTypeUUid && visitStartDate
? `${restBaseUrl}/order?includeNullFulfillerStatus=true&patient=${patientUuid}&orderTypes=${orderTypeUUid}&activatedOnOrAfterDate=${visitStartDate}`
: null;
const { data, ...rest } = useSWR<FetchResponse<{ results: Array<OpenmrsResource> }>, Error>(apiUrl, openmrsFetch);

return {
orders: data?.data.results,
count: data?.data.results.length,
...rest,
};
}
7 changes: 7 additions & 0 deletions packages/esm-ward-app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { coloredObsTagsCardRowConfigSchema } from './config-schema-extension-col
import { moduleName } from './constant';
import { createDashboardLink } from './createDashboardLink.component';
import rootComponent from './root.component';
import { pendingOrdersExtensionConfigSchema } from './config-schema-pending-orders-extension';

export const importTranslation = require.context('../translations', false, /.json$/, 'lazy');

Expand Down Expand Up @@ -67,6 +68,11 @@ export const admissionRequestNoteRowExtension = getAsyncLifecycle(
options,
);

export const pendingOrdersExtension = getAsyncLifecycle(
() => import('./ward-patient-card/card-rows/pending-orders.extension'),
options,
);

// t('transfers', 'Transfers')
export const patientTransferAndSwapWorkspace = getAsyncLifecycle(
() => import('./ward-workspace/patient-transfer-bed-swap/patient-transfer-swap.workspace'),
Expand Down Expand Up @@ -100,6 +106,7 @@ export function startupApp() {
defineConfigSchema(moduleName, configSchema);
defineExtensionConfigSchema('colored-obs-tags-card-row', coloredObsTagsCardRowConfigSchema);
defineExtensionConfigSchema('admission-request-note-card-row', admissionRequestNoteRowConfigSchema);
defineExtensionConfigSchema('ward-patient-pending-orders', pendingOrdersExtensionConfigSchema);

registerFeatureFlag(
'bedmanagement-module',
Expand Down
5 changes: 5 additions & 0 deletions packages/esm-ward-app/src/routes.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
"component": "admissionRequestNoteRowExtension",
"name": "admission-request-note-card-row",
"slot": "ward-patient-card-slot"
},
{
"component": "pendingOrdersExtension",
"name": "ward-patient-pending-orders",
"slot": "ward-patient-card-pending-items-slot"
}
],
"workspaces": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import { type WardPatientCard } from '../../types';
import { useConfig } from '@openmrs/esm-framework';
import type { PendingOrderTypesDefinition } from '../../config-schema';
import { WardPatientPendingOrder } from '../row-elements/ward-patient-pending-order.component';

const PendingOrdersExtension: WardPatientCard = (wardPatient) => {
const { orderTypes, enabled } = useConfig<PendingOrderTypesDefinition>();

if (!enabled || !orderTypes) {
return <></>;
}

return (
<>
{orderTypes.map(({ uuid, label }) => (
<WardPatientPendingOrder
key={`pending-order-type-${uuid}`}
wardPatient={wardPatient}
orderUuid={uuid}
label={label}
/>
))}
</>
);
};

export default PendingOrdersExtension;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import { ChemistryReference } from '@carbon/react/icons';
import styles from '../ward-patient-card.scss';
import { useTranslation } from 'react-i18next';
import { type WardPatient } from '../../types';
import { usePatientPendingOrders } from '../../hooks/usePatientPendingOrders';

export interface WardPatientPendingOrderProps {
wardPatient: WardPatient;
orderUuid: string;
label: string;
}

export const WardPatientPendingOrder: React.FC<WardPatientPendingOrderProps> = ({ wardPatient, orderUuid, label }) => {
const { t } = useTranslation();
const { count, isLoading } = usePatientPendingOrders(
wardPatient?.patient?.uuid,
orderUuid,
wardPatient?.visit?.startDatetime.split('T')[0],
);

if (isLoading || !count || count == 0) {
return null;
}

const labelToDisplay = label ? t(label) : t('Orders', 'Orders');
return (
<div className={styles.wardPatientCardDispositionTypeContainer}>
<ChemistryReference className={styles.chemistryReferenceIcon} size="24" />
{count} {labelToDisplay}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExtensionSlot, getPatientName, launchWorkspace } from '@openmrs/esm-framework';
import { ExtensionSlot, getPatientName, launchWorkspace, useConfig } from '@openmrs/esm-framework';
import classNames from 'classnames';
import React from 'react';
import { Hourglass } from '@carbon/react/icons';
Expand All @@ -9,10 +9,12 @@ import WardPatientName from './row-elements/ward-patient-name';
import { WardPatientCardElement } from './ward-patient-card-element.component';
import styles from './ward-patient-card.scss';
import WardPatientPendingTransfer from './row-elements/ward-patient-pending-transfer';
import { type PendingOrderTypesDefinition } from '../config-schema';

const WardPatientCard: WardPatientCard = (wardPatient) => {
const { patient, bed } = wardPatient;
const { id, headerRowElements, footerRowElements } = useCurrentWardCardConfig();
const { enabled: showPendingOrders } = useConfig<PendingOrderTypesDefinition>();

const headerExtensionSlotName =
id == 'default' ? 'ward-patient-card-header-slot' : `ward-patient-card-header-${id}-slot`;
Expand All @@ -34,10 +36,15 @@ const WardPatientCard: WardPatientCard = (wardPatient) => {
))}
<ExtensionSlot name={headerExtensionSlotName} state={wardPatient} />
</div>
{wardPatient?.inpatientRequest ? (
{wardPatient?.inpatientRequest || showPendingOrders ? (
<div className={styles.wardPatientCardPendingItemsRow}>
<Hourglass className={styles.hourGlassIcon} size="16" />:
<WardPatientPendingTransfer wardPatient={wardPatient} />
<ExtensionSlot
name="ward-patient-card-pending-items-slot"
state={wardPatient}
className={classNames(styles.wardPatientPendingOrdersRow, styles.wardPatientCardExtensionSlot)}
/>
{wardPatient?.inpatientRequest ? <WardPatientPendingTransfer wardPatient={wardPatient} /> : null}
</div>
) : null}
<ExtensionSlot
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@
display: none;
}

.wardPatientPendingOrdersRow:empty {
display: none;
margin-left: layout.$spacing-04;
}

.wardPatientCardExtensionSlot {
display: none;

Expand All @@ -83,7 +88,7 @@
@extend .wardPatientCardRow;
display: flex;
align-items: center;
flex-flow: row;
flex-flow: row wrap;
color: $ui-02;
background-color: colors.$gray-80;
}
Expand Down Expand Up @@ -136,6 +141,15 @@
margin-right: layout.$spacing-02;
}

.chemistryReferenceIcon {
padding: layout.$spacing-02;
border-radius: 50%;
fill: $ui-03;
background-color: #a2191f;
margin-left: layout.$spacing-03;
margin-right: layout.$spacing-02;
}

.wardPatientAddress {
@extend .dotSeparatedChildren;
display: flex;
Expand Down
1 change: 1 addition & 0 deletions packages/esm-ward-app/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"noLocationsFound": "No locations found",
"note": "Note",
"notes": "Notes",
"Orders": "Orders",
"other": "Other",
"patientAdmittedButBedNotAssigned": "Patient admitted successfully but fail to assign bed to patient",
"patientAdmittedSuccessfully": "Patient admitted successfully",
Expand Down

0 comments on commit ba179e4

Please sign in to comment.