@kenyaemr/esm-ward-app 8.1.1-pre.118 → 8.1.1-pre.121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +16 -20
- package/dist/124.js +1 -0
- package/dist/124.js.map +1 -0
- package/dist/125.js +1 -1
- package/dist/125.js.map +1 -1
- package/dist/130.js +1 -1
- package/dist/130.js.map +1 -1
- package/dist/153.js +1 -0
- package/dist/153.js.map +1 -0
- package/dist/372.js +1 -1
- package/dist/372.js.map +1 -1
- package/dist/471.js +1 -0
- package/dist/471.js.map +1 -0
- package/dist/481.js +1 -0
- package/dist/481.js.map +1 -0
- package/dist/53.js +1 -1
- package/dist/53.js.map +1 -1
- package/dist/559.js +1 -1
- package/dist/559.js.map +1 -1
- package/dist/574.js +1 -1
- package/dist/{500.js → 576.js} +1 -1
- package/dist/576.js.map +1 -0
- package/dist/577.js +1 -1
- package/dist/577.js.map +1 -1
- package/dist/649.js +2 -0
- package/dist/{161.js.LICENSE.txt → 649.js.LICENSE.txt} +0 -6
- package/dist/649.js.map +1 -0
- package/dist/{659.js → 662.js} +1 -1
- package/dist/662.js.map +1 -0
- package/dist/67.js +2 -0
- package/dist/67.js.LICENSE.txt +5 -0
- package/dist/67.js.map +1 -0
- package/dist/920.js +1 -0
- package/dist/920.js.map +1 -0
- package/dist/921.js +1 -0
- package/dist/921.js.map +1 -0
- package/dist/922.js +1 -1
- package/dist/922.js.map +1 -1
- package/dist/kenyaemr-esm-ward-app.js +1 -1
- package/dist/kenyaemr-esm-ward-app.js.buildmanifest.json +148 -165
- package/dist/kenyaemr-esm-ward-app.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.LICENSE.txt +0 -10
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/mock.tsx +8 -0
- package/package.json +1 -1
- package/src/beds/empty-bed-skeleton.tsx +3 -3
- package/src/beds/empty-bed.component.tsx +3 -3
- package/src/beds/ward-bed.component.tsx +41 -0
- package/src/beds/ward-bed.scss +45 -0
- package/src/beds/{occupied-bed.test.tsx → ward-bed.test.tsx} +27 -16
- package/src/config-schema.ts +196 -75
- package/src/hooks/useAssignedBedByPatient.ts +9 -0
- package/src/hooks/useInpatientAdmission.ts +1 -1
- package/src/hooks/useMotherAndChildren.ts +2 -2
- package/src/hooks/useObs.ts +2 -2
- package/src/hooks/useWardPatientGrouping.ts +2 -0
- package/src/index.ts +10 -29
- package/src/root.component.tsx +3 -0
- package/src/routes.json +6 -11
- package/src/types/index.ts +29 -14
- package/src/ward-patient-card/card-rows/admission-request-note-row.component.tsx +38 -0
- package/src/ward-patient-card/card-rows/coded-obs-tags-row.component.tsx +108 -0
- package/src/ward-patient-card/card-rows/mother-child-row.component.tsx +84 -0
- package/src/ward-patient-card/card-rows/{pending-items-car-row.extension.tsx → pending-items-row.component.tsx} +12 -8
- package/src/ward-patient-card/row-elements/ward-patient-coded-obs-tags.tsx +12 -7
- package/src/ward-patient-card/row-elements/ward-patient-header-address.tsx +5 -5
- package/src/ward-patient-card/row-elements/ward-patient-identifier.tsx +18 -40
- package/src/ward-patient-card/row-elements/ward-patient-obs.resource.ts +2 -2
- package/src/ward-patient-card/row-elements/ward-patient-obs.tsx +15 -8
- package/src/ward-patient-card/ward-patient-card.component.tsx +16 -54
- package/src/ward-patient-card/ward-patient-card.scss +7 -1
- package/src/ward-view/default-ward/default-ward-beds.component.tsx +42 -0
- package/src/ward-view/default-ward/default-ward-patient-card-header.component.tsx +32 -0
- package/src/ward-view/default-ward/default-ward-patient-card.component.tsx +31 -0
- package/src/ward-view/default-ward/default-ward-pending-patients.component.tsx +52 -0
- package/src/ward-view/default-ward/default-ward-unassigned-patients.component.tsx +32 -0
- package/src/ward-view/default-ward/default-ward-view.component.tsx +31 -0
- package/src/ward-view/materal-ward/maternal-ward-beds.component.tsx +65 -0
- package/src/ward-view/materal-ward/maternal-ward-patient-card-header.component.tsx +30 -0
- package/src/ward-view/materal-ward/maternal-ward-patient-card.component.tsx +93 -0
- package/src/{beds/occupied-bed.scss → ward-view/materal-ward/maternal-ward-patient-card.scss} +4 -10
- package/src/ward-view/materal-ward/maternal-ward-patient-card.test.tsx +47 -0
- package/src/ward-view/materal-ward/maternal-ward-pending-patients.component.tsx +48 -0
- package/src/ward-view/materal-ward/maternal-ward-unassigned-patients.component.tsx +33 -0
- package/src/ward-view/materal-ward/maternal-ward-view.component.tsx +38 -0
- package/src/ward-view/materal-ward/maternal-ward-view.resource.ts +89 -0
- package/src/ward-view/ward-view.component.tsx +11 -151
- package/src/ward-view/ward-view.resource.ts +78 -6
- package/src/ward-view/ward-view.scss +1 -0
- package/src/ward-view/ward-view.test.tsx +10 -8
- package/src/ward-view/ward.component.tsx +106 -0
- package/src/ward-view-header/admission-requests-bar.component.tsx +10 -6
- package/src/ward-view-header/admission-requests-bar.test.tsx +5 -4
- package/src/ward-view-header/ward-metrics.component.tsx +12 -11
- package/src/ward-view-header/ward-metrics.test.tsx +4 -58
- package/src/ward-view-header/ward-view-header.component.tsx +6 -4
- package/src/ward-workspace/admission-request-card/admission-request-card-actions.component.tsx +7 -4
- package/src/ward-workspace/admission-request-card/admission-request-card-header.component.tsx +9 -21
- package/src/ward-workspace/admission-request-card/admission-request-card.component.tsx +9 -3
- package/src/ward-workspace/admission-request-card/admission-request-card.scss +6 -1
- package/src/ward-workspace/admission-request-workspace/admission-requests-workspace.test.tsx +11 -38
- package/src/ward-workspace/admission-request-workspace/admission-requests.workspace.tsx +8 -38
- package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.test.tsx +80 -89
- package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.workspace.tsx +21 -13
- package/src/ward-workspace/patient-banner/patient-banner.component.tsx +5 -12
- package/src/ward-workspace/patient-details/ward-patient-action-button.extension.tsx +2 -2
- package/src/ward-workspace/patient-details/ward-patient.workspace.tsx +13 -6
- package/src/ward-workspace/patient-discharge/patient-discharge.workspace.tsx +6 -6
- package/src/ward-workspace/patient-transfer-bed-swap/patient-bed-swap-form.component.tsx +7 -7
- package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-request-form.component.tsx +6 -6
- package/translations/en.json +7 -1
- package/dist/126.js +0 -1
- package/dist/126.js.map +0 -1
- package/dist/161.js +0 -2
- package/dist/161.js.map +0 -1
- package/dist/2.js +0 -1
- package/dist/2.js.map +0 -1
- package/dist/269.js +0 -1
- package/dist/269.js.map +0 -1
- package/dist/466.js +0 -1
- package/dist/466.js.map +0 -1
- package/dist/500.js.map +0 -1
- package/dist/557.js +0 -1
- package/dist/557.js.map +0 -1
- package/dist/659.js.map +0 -1
- package/dist/701.js +0 -1
- package/dist/701.js.map +0 -1
- package/dist/749.js +0 -1
- package/dist/749.js.map +0 -1
- package/dist/908.js +0 -1
- package/dist/908.js.map +0 -1
- package/src/beds/empty-bed.scss +0 -24
- package/src/beds/occupied-bed.component.tsx +0 -35
- package/src/beds/unassigned-patient.component.tsx +0 -20
- package/src/beds/unassigned-patient.scss +0 -6
- package/src/config-schema-admission-request-note.ts +0 -9
- package/src/config-schema-extension-colored-obs-tags.ts +0 -91
- package/src/config-schema-mother-child-row.ts +0 -26
- package/src/config-schema-pending-items-extension.ts +0 -29
- package/src/hooks/useCurrentWardCardConfig.ts +0 -32
- package/src/ward-patient-card/card-rows/admission-request-note.extension.tsx +0 -32
- package/src/ward-patient-card/card-rows/colored-obs-tags-card-row.extension.tsx +0 -13
- package/src/ward-patient-card/card-rows/mother-child-row.extension.tsx +0 -110
- package/src/ward-patient-card/ward-patient-card-element.component.tsx +0 -69
- package/src/ward-patient-card/ward-patient-resource.ts +0 -15
- package/src/ward-view/ward-bed.component.tsx +0 -14
- /package/src/ward-patient-card/row-elements/{ward-pateint-skeleton-text.tsx → ward-patient-skeleton-text.tsx} +0 -0
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { Button, InlineNotification } from '@carbon/react';
|
|
2
2
|
import { Movement } from '@carbon/react/icons';
|
|
3
3
|
import { ArrowRightIcon, isDesktop, launchWorkspace, useAppContext, useLayoutType } from '@openmrs/esm-framework';
|
|
4
|
-
import React from 'react';
|
|
4
|
+
import React, { type ReactNode } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
|
-
import { type
|
|
6
|
+
import { type WardViewContext } from '../types';
|
|
7
7
|
import styles from './admission-requests.scss';
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
interface AdmissionRequestsBarProps {
|
|
10
|
+
wardPendingPatients: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const AdmissionRequestsBar: React.FC<AdmissionRequestsBarProps> = ({ wardPendingPatients }) => {
|
|
14
|
+
const {wardPatientGroupDetails} = useAppContext<WardViewContext>('ward-view-context') ?? {};
|
|
15
|
+
const { inpatientRequests, isLoading, error } = wardPatientGroupDetails?.inpatientRequestResponse ?? {};
|
|
12
16
|
const { t } = useTranslation();
|
|
13
17
|
const layout = useLayoutType();
|
|
14
18
|
|
|
@@ -35,7 +39,7 @@ const AdmissionRequestsBar = () => {
|
|
|
35
39
|
})}
|
|
36
40
|
</span>
|
|
37
41
|
<Button
|
|
38
|
-
onClick={() => launchWorkspace('admission-requests-workspace')}
|
|
42
|
+
onClick={() => launchWorkspace('admission-requests-workspace', { wardPendingPatients })}
|
|
39
43
|
renderIcon={ArrowRightIcon}
|
|
40
44
|
kind="ghost"
|
|
41
45
|
size={isDesktop(layout) ? 'sm' : 'lg'}>
|
|
@@ -3,22 +3,23 @@ import { screen } from '@testing-library/react';
|
|
|
3
3
|
import userEvent from '@testing-library/user-event';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { renderWithSwr } from 'tools';
|
|
6
|
-
import {
|
|
6
|
+
import { mockWardViewContext } from '../../mock';
|
|
7
|
+
import { type WardViewContext } from '../types';
|
|
7
8
|
import AdmissionRequestsBar from './admission-requests-bar.component';
|
|
8
9
|
|
|
9
|
-
jest.mocked(useAppContext).mockReturnValue(
|
|
10
|
+
jest.mocked(useAppContext<WardViewContext>).mockReturnValue(mockWardViewContext);
|
|
10
11
|
|
|
11
12
|
describe('Admission Requests Button', () => {
|
|
12
13
|
it('should launch workspace when clicked on manage button', async () => {
|
|
13
14
|
const user = userEvent.setup();
|
|
14
|
-
renderWithSwr(<AdmissionRequestsBar />);
|
|
15
|
+
renderWithSwr(<AdmissionRequestsBar wardPendingPatients={[]} />);
|
|
15
16
|
|
|
16
17
|
await user.click(screen.getByRole('button', { name: /manage/i }));
|
|
17
18
|
expect(launchWorkspace).toHaveBeenCalled();
|
|
18
19
|
});
|
|
19
20
|
|
|
20
21
|
it('should have one admission request', () => {
|
|
21
|
-
renderWithSwr(<AdmissionRequestsBar />);
|
|
22
|
+
renderWithSwr(<AdmissionRequestsBar wardPendingPatients={[<div>Dummy Patient</div>]} />);
|
|
22
23
|
|
|
23
24
|
expect(screen.getByText('1 admission request')).toBeInTheDocument();
|
|
24
25
|
});
|
|
@@ -1,32 +1,29 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import styles from './ward-metrics.scss';
|
|
3
|
-
import { useBeds } from '../hooks/useBeds';
|
|
4
1
|
import { showNotification, useAppContext, useFeatureFlag } from '@openmrs/esm-framework';
|
|
2
|
+
import React from 'react';
|
|
5
3
|
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import type { WardViewContext } from '../types';
|
|
6
5
|
import {
|
|
7
6
|
getWardMetricNameTranslation,
|
|
8
7
|
getWardMetrics,
|
|
9
8
|
getWardMetricValueTranslation,
|
|
10
9
|
} from '../ward-view/ward-view.resource';
|
|
11
10
|
import WardMetric from './ward-metric.component';
|
|
12
|
-
import
|
|
13
|
-
import useWardLocation from '../hooks/useWardLocation';
|
|
11
|
+
import styles from './ward-metrics.scss';
|
|
14
12
|
|
|
15
13
|
const wardMetrics = [{ name: 'patients' }, { name: 'freeBeds' }, { name: 'capacity' }];
|
|
16
14
|
|
|
17
15
|
const WardMetrics = () => {
|
|
18
|
-
const { location } = useWardLocation();
|
|
19
16
|
const { t } = useTranslation();
|
|
20
17
|
const isBedManagementModuleInstalled = useFeatureFlag('bedmanagement-module');
|
|
21
|
-
const
|
|
18
|
+
const { wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
|
|
22
19
|
const { admissionLocationResponse, inpatientAdmissionResponse, inpatientRequestResponse, bedLayouts } =
|
|
23
|
-
|
|
20
|
+
wardPatientGroupDetails || {};
|
|
24
21
|
const { isLoading, error } = admissionLocationResponse ?? {};
|
|
25
22
|
const isDataLoading =
|
|
26
23
|
admissionLocationResponse?.isLoading ||
|
|
27
24
|
inpatientAdmissionResponse?.isLoading ||
|
|
28
25
|
inpatientRequestResponse?.isLoading;
|
|
29
|
-
if (!
|
|
26
|
+
if (!wardPatientGroupDetails) return <></>;
|
|
30
27
|
|
|
31
28
|
if (error) {
|
|
32
29
|
showNotification({
|
|
@@ -36,7 +33,7 @@ const WardMetrics = () => {
|
|
|
36
33
|
});
|
|
37
34
|
}
|
|
38
35
|
|
|
39
|
-
const wardMetricValues = getWardMetrics(bedLayouts,
|
|
36
|
+
const wardMetricValues = getWardMetrics(bedLayouts, wardPatientGroupDetails);
|
|
40
37
|
return (
|
|
41
38
|
<div className={styles.metricsContainer}>
|
|
42
39
|
{isBedManagementModuleInstalled ? (
|
|
@@ -64,7 +61,11 @@ const WardMetrics = () => {
|
|
|
64
61
|
metricValue={
|
|
65
62
|
error
|
|
66
63
|
? '--'
|
|
67
|
-
: getWardMetricValueTranslation(
|
|
64
|
+
: getWardMetricValueTranslation(
|
|
65
|
+
'pendingOut',
|
|
66
|
+
t,
|
|
67
|
+
wardPatientGroupDetails?.wardPatientPendingCount?.toString(),
|
|
68
|
+
)
|
|
68
69
|
}
|
|
69
70
|
isLoading={!!isDataLoading}
|
|
70
71
|
key="pending"
|
|
@@ -12,6 +12,8 @@ import { useInpatientAdmission } from '../hooks/useInpatientAdmission';
|
|
|
12
12
|
import useWardLocation from '../hooks/useWardLocation';
|
|
13
13
|
import { screen } from '@testing-library/react';
|
|
14
14
|
import { useAppContext } from '@openmrs/esm-framework';
|
|
15
|
+
import { type WardViewContext } from '../types';
|
|
16
|
+
import { mockWardViewContext } from '../../mock';
|
|
15
17
|
|
|
16
18
|
const wardMetrics = [
|
|
17
19
|
{ name: 'patients', key: 'patients', defaultTranslation: 'Patients' },
|
|
@@ -19,67 +21,11 @@ const wardMetrics = [
|
|
|
19
21
|
{ name: 'capacity', key: 'capacity', defaultTranslation: 'Capacity' },
|
|
20
22
|
];
|
|
21
23
|
|
|
22
|
-
jest.
|
|
23
|
-
...jest.requireActual('react-router-dom'),
|
|
24
|
-
useParams: jest.fn().mockReturnValue({}),
|
|
25
|
-
}));
|
|
24
|
+
jest.mocked(useAppContext<WardViewContext>).mockReturnValue(mockWardViewContext);
|
|
26
25
|
|
|
27
|
-
jest.mock('../hooks/useWardLocation', () =>
|
|
28
|
-
jest.fn().mockReturnValue({
|
|
29
|
-
location: { uuid: 'abcd', display: 'mock location' },
|
|
30
|
-
isLoadingLocation: false,
|
|
31
|
-
errorFetchingLocation: null,
|
|
32
|
-
invalidLocation: false,
|
|
33
|
-
}),
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
jest.mock('../hooks/useBeds', () => ({
|
|
37
|
-
useBeds: jest.fn(),
|
|
38
|
-
}));
|
|
39
|
-
|
|
40
|
-
jest.mock('../hooks/useAdmissionLocation', () => ({
|
|
41
|
-
useAdmissionLocation: jest.fn(),
|
|
42
|
-
}));
|
|
43
|
-
jest.mock('../hooks/useInpatientAdmission', () => ({
|
|
44
|
-
useInpatientAdmission: jest.fn(),
|
|
45
|
-
}));
|
|
46
|
-
|
|
47
|
-
jest.mock('../hooks/useInpatientRequest', () => ({
|
|
48
|
-
useInpatientRequest: jest.fn(),
|
|
49
|
-
}));
|
|
50
|
-
|
|
51
|
-
const mockUseWardLocation = jest.mocked(useWardLocation);
|
|
52
|
-
|
|
53
|
-
const mockAdmissionLocationResponse = jest.mocked(useAdmissionLocation).mockReturnValue({
|
|
54
|
-
error: undefined,
|
|
55
|
-
mutate: jest.fn(),
|
|
56
|
-
isValidating: false,
|
|
57
|
-
isLoading: false,
|
|
58
|
-
admissionLocation: mockAdmissionLocation,
|
|
59
|
-
});
|
|
60
|
-
const mockInpatientAdmissionResponse = jest.mocked(useInpatientAdmission).mockReturnValue({
|
|
61
|
-
error: undefined,
|
|
62
|
-
mutate: jest.fn(),
|
|
63
|
-
isValidating: false,
|
|
64
|
-
isLoading: false,
|
|
65
|
-
inpatientAdmissions: mockInpatientAdmissions,
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const inpatientAdmissionsUuidMap = getInpatientAdmissionsUuidMap(mockInpatientAdmissions);
|
|
69
|
-
const mockWardPatientGroupDetails = {
|
|
70
|
-
admissionLocationResponse: mockAdmissionLocationResponse(),
|
|
71
|
-
inpatientAdmissionResponse: mockInpatientAdmissionResponse(),
|
|
72
|
-
...createAndGetWardPatientGrouping(mockInpatientAdmissions, mockAdmissionLocation, mockInpatientRequest),
|
|
73
|
-
};
|
|
74
|
-
jest.mocked(useAppContext).mockReturnValue(mockWardPatientGroupDetails);
|
|
75
26
|
describe('Ward Metrics', () => {
|
|
76
27
|
it('Should display metrics of in the ward ', () => {
|
|
77
|
-
|
|
78
|
-
location: null,
|
|
79
|
-
isLoadingLocation: false,
|
|
80
|
-
errorFetchingLocation: null,
|
|
81
|
-
invalidLocation: true,
|
|
82
|
-
});
|
|
28
|
+
const mockWardPatientGroupDetails = mockWardViewContext.wardPatientGroupDetails;
|
|
83
29
|
const { bedLayouts } = mockWardPatientGroupDetails;
|
|
84
30
|
const bedMetrics = getWardMetrics(bedLayouts, mockWardPatientGroupDetails);
|
|
85
31
|
renderWithSwr(<WardMetrics />);
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { type ReactNode } from 'react';
|
|
2
2
|
import styles from './ward-view-header.scss';
|
|
3
3
|
import AdmissionRequestsBar from './admission-requests-bar.component';
|
|
4
4
|
import useWardLocation from '../hooks/useWardLocation';
|
|
5
5
|
import WardMetrics from './ward-metrics.component';
|
|
6
6
|
|
|
7
|
-
interface WardViewHeaderProps {
|
|
7
|
+
interface WardViewHeaderProps {
|
|
8
|
+
wardPendingPatients: ReactNode;
|
|
9
|
+
}
|
|
8
10
|
|
|
9
|
-
const WardViewHeader: React.FC<WardViewHeaderProps> = () => {
|
|
11
|
+
const WardViewHeader: React.FC<WardViewHeaderProps> = ({ wardPendingPatients }) => {
|
|
10
12
|
const { location } = useWardLocation();
|
|
11
13
|
|
|
12
14
|
return (
|
|
13
15
|
<div className={styles.wardViewHeader}>
|
|
14
16
|
<h4>{location?.display}</h4>
|
|
15
17
|
<WardMetrics />
|
|
16
|
-
<AdmissionRequestsBar />
|
|
18
|
+
<AdmissionRequestsBar {...{ wardPendingPatients }} />
|
|
17
19
|
</div>
|
|
18
20
|
);
|
|
19
21
|
};
|
package/src/ward-workspace/admission-request-card/admission-request-card-actions.component.tsx
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { Button } from '@carbon/react';
|
|
2
|
-
import { ArrowRightIcon, launchWorkspace, useLayoutType } from '@openmrs/esm-framework';
|
|
2
|
+
import { ArrowRightIcon, launchWorkspace, useAppContext, useLayoutType } from '@openmrs/esm-framework';
|
|
3
3
|
import React, { useCallback } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
|
-
import type { WardPatientWorkspaceProps,
|
|
5
|
+
import type { WardPatientWorkspaceProps, WardPatientCardType, WardViewContext } from '../../types';
|
|
6
6
|
import type { AdmitPatientFormWorkspaceProps } from '../admit-patient-form-workspace/types';
|
|
7
7
|
import styles from './admission-request-card.scss';
|
|
8
8
|
|
|
9
|
-
const AdmissionRequestCardActions:
|
|
9
|
+
const AdmissionRequestCardActions: WardPatientCardType = (wardPatient) => {
|
|
10
10
|
const { patient, inpatientRequest } = wardPatient;
|
|
11
11
|
const { dispositionType } = inpatientRequest;
|
|
12
12
|
const { t } = useTranslation();
|
|
13
13
|
const responsiveSize = useLayoutType() === 'tablet' ? 'lg' : 'md';
|
|
14
|
+
const {WardPatientHeader} = useAppContext<WardViewContext>('ward-view-context') ?? {};
|
|
15
|
+
|
|
14
16
|
const launchPatientAdmissionForm = useCallback(
|
|
15
17
|
() => launchWorkspace<AdmitPatientFormWorkspaceProps>('admit-patient-form-workspace', { patient, dispositionType }),
|
|
16
18
|
[],
|
|
@@ -19,8 +21,9 @@ const AdmissionRequestCardActions: WardPatientCard = (wardPatient) => {
|
|
|
19
21
|
const launchPatientTransferForm = useCallback(() => {
|
|
20
22
|
launchWorkspace<WardPatientWorkspaceProps>('patient-transfer-request-workspace', {
|
|
21
23
|
wardPatient,
|
|
24
|
+
WardPatientHeader
|
|
22
25
|
});
|
|
23
|
-
}, [wardPatient]);
|
|
26
|
+
}, [wardPatient, WardPatientHeader]);
|
|
24
27
|
|
|
25
28
|
return (
|
|
26
29
|
<div className={styles.admissionRequestActionBar}>
|
package/src/ward-workspace/admission-request-card/admission-request-card-header.component.tsx
CHANGED
|
@@ -1,32 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { formatDatetime, getLocale } from '@openmrs/esm-framework';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { type WardPatientCardType } from '../../types';
|
|
5
|
+
import WardPatientAge from '../../ward-patient-card/row-elements/ward-patient-age';
|
|
6
|
+
import WardPatientGender from '../../ward-patient-card/row-elements/ward-patient-gender.component';
|
|
7
|
+
import WardPatientIdentifier from '../../ward-patient-card/row-elements/ward-patient-identifier';
|
|
5
8
|
import WardPatientName from '../../ward-patient-card/row-elements/ward-patient-name';
|
|
6
|
-
import { WardPatientCardElement } from '../../ward-patient-card/ward-patient-card-element.component';
|
|
7
|
-
import type WardPatientCard from '../../ward-patient-card/ward-patient-card.component';
|
|
8
9
|
import styles from './admission-request-card.scss';
|
|
9
10
|
|
|
10
|
-
const AdmissionRequestCardHeader:
|
|
11
|
+
const AdmissionRequestCardHeader: WardPatientCardType = (wardPatient) => {
|
|
11
12
|
const { inpatientRequest } = wardPatient;
|
|
12
13
|
const { dispositionEncounter } = inpatientRequest;
|
|
13
|
-
const { id, headerRowElements } = useCurrentWardCardConfig();
|
|
14
14
|
const { patient } = wardPatient;
|
|
15
|
-
const extensionSlotState = wardPatient;
|
|
16
|
-
|
|
17
|
-
const rowsExtensionSlotName = id == 'default' ? 'ward-patient-card-slot' : `ward-patient-card-${id}-slot`;
|
|
18
15
|
|
|
19
16
|
return (
|
|
20
17
|
<div className={styles.admissionRequestCardHeaderContainer}>
|
|
21
18
|
<div className={styles.admissionRequestCardHeader}>
|
|
22
19
|
<WardPatientName patient={patient} />
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
elementId={elementId}
|
|
27
|
-
{...wardPatient}
|
|
28
|
-
/>
|
|
29
|
-
))}
|
|
20
|
+
<WardPatientIdentifier id="patient-identifier" patient={patient} />
|
|
21
|
+
<WardPatientGender patient={patient} />
|
|
22
|
+
<WardPatientAge patient={patient} />
|
|
30
23
|
</div>
|
|
31
24
|
<div className={classNames(styles.admissionRequestCardHeader, styles.admissionEncounterDetails)}>
|
|
32
25
|
<div>
|
|
@@ -38,11 +31,6 @@ const AdmissionRequestCardHeader: WardPatientCard = (wardPatient) => {
|
|
|
38
31
|
<div>{dispositionEncounter?.encounterProviders?.map((provider) => provider?.provider?.display).join(',')}</div>
|
|
39
32
|
<div>{dispositionEncounter?.location?.display}</div>
|
|
40
33
|
</div>
|
|
41
|
-
<ExtensionSlot
|
|
42
|
-
name={rowsExtensionSlotName}
|
|
43
|
-
state={extensionSlotState}
|
|
44
|
-
className={styles.admissionRequestCardExtensionSlot}
|
|
45
|
-
/>
|
|
46
34
|
</div>
|
|
47
35
|
);
|
|
48
36
|
};
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type {
|
|
1
|
+
import React, { type ReactNode } from 'react';
|
|
2
|
+
import type { WardPatient, WardPatientCardType } from '../../types';
|
|
3
3
|
import AdmissionRequestCardActions from './admission-request-card-actions.component';
|
|
4
4
|
import AdmissionRequestCardHeader from './admission-request-card-header.component';
|
|
5
5
|
import styles from './admission-request-card.scss';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
interface AdmissionRequestCardProps {
|
|
8
|
+
wardPatient: WardPatient;
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const AdmissionRequestCard: React.FC<AdmissionRequestCardProps> = ({ wardPatient, children }) => {
|
|
8
13
|
return (
|
|
9
14
|
<div className={styles.admissionRequestCard}>
|
|
10
15
|
<AdmissionRequestCardHeader {...wardPatient} />
|
|
16
|
+
{children}
|
|
11
17
|
<AdmissionRequestCardActions {...wardPatient} />
|
|
12
18
|
</div>
|
|
13
19
|
);
|
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
height: fit-content;
|
|
9
9
|
color: $color-gray-70;
|
|
10
10
|
margin-bottom: layout.$spacing-05;
|
|
11
|
+
|
|
12
|
+
> div {
|
|
13
|
+
margin: layout.$spacing-04;
|
|
14
|
+
width: unset;
|
|
15
|
+
}
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
.admissionRequestCardHeaderContainer {
|
|
@@ -29,7 +34,7 @@
|
|
|
29
34
|
display: none;
|
|
30
35
|
|
|
31
36
|
&:has(div:not(:empty)) {
|
|
32
|
-
display: block;
|
|
37
|
+
display: block;
|
|
33
38
|
margin: layout.$spacing-03 0;
|
|
34
39
|
background-color: white;
|
|
35
40
|
}
|
package/src/ward-workspace/admission-request-workspace/admission-requests-workspace.test.tsx
CHANGED
|
@@ -1,53 +1,26 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useAppContext } from '@openmrs/esm-framework';
|
|
2
2
|
import { screen } from '@testing-library/react';
|
|
3
|
-
import
|
|
4
|
-
import { useInpatientRequest } from '../../hooks/useInpatientRequest';
|
|
5
|
-
import { configSchema } from '../../config-schema';
|
|
6
|
-
import useWardLocation from '../../hooks/useWardLocation';
|
|
7
|
-
import AdmissionRequestsWorkspace from './admission-requests.workspace';
|
|
8
|
-
import { mockInpatientRequest, mockLocationInpatientWard } from '../../../../../__mocks__';
|
|
3
|
+
import React from 'react';
|
|
9
4
|
import { renderWithSwr } from '../../../../../tools';
|
|
5
|
+
import { mockWardViewContext } from '../../../mock';
|
|
6
|
+
import { type WardViewContext } from '../../types';
|
|
7
|
+
import DefaultWardPendingPatients from '../../ward-view/default-ward/default-ward-pending-patients.component';
|
|
8
|
+
import AdmissionRequestsWorkspace, { type AdmissionRequestsWorkspaceProps } from './admission-requests.workspace';
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
jest.mock('../../hooks/useInpatientRequest', () => ({
|
|
14
|
-
useInpatientRequest: jest.fn(),
|
|
15
|
-
}));
|
|
16
|
-
jest.mock('../../hooks/useWardLocation', () => jest.fn());
|
|
17
|
-
|
|
18
|
-
const mockUseWardLocation = useWardLocation as jest.Mock;
|
|
19
|
-
mockUseWardLocation.mockReturnValue({
|
|
20
|
-
location: mockLocationInpatientWard,
|
|
21
|
-
isLoadingLocation: false,
|
|
22
|
-
errorFetchingLocation: null,
|
|
23
|
-
invalidLocation: false,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const mockInpatientRequestResponse: ReturnType<typeof useInpatientRequest> = {
|
|
27
|
-
error: undefined,
|
|
28
|
-
mutate: jest.fn(),
|
|
29
|
-
isValidating: false,
|
|
30
|
-
isLoading: false,
|
|
31
|
-
inpatientRequests: mockInpatientRequest,
|
|
32
|
-
totalCount: 1,
|
|
33
|
-
hasMore: false,
|
|
34
|
-
loadMore: jest.fn(),
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
jest.mocked(useInpatientRequest).mockReturnValue(mockInpatientRequestResponse);
|
|
10
|
+
jest.mocked(useAppContext<WardViewContext>).mockReturnValue(mockWardViewContext);
|
|
38
11
|
|
|
39
|
-
const workspaceProps = {
|
|
12
|
+
const workspaceProps: AdmissionRequestsWorkspaceProps = {
|
|
40
13
|
closeWorkspace: jest.fn(),
|
|
41
14
|
promptBeforeClosing: jest.fn(),
|
|
42
15
|
closeWorkspaceWithSavedChanges: jest.fn(),
|
|
43
16
|
setTitle: jest.fn(),
|
|
17
|
+
wardPendingPatients: <DefaultWardPendingPatients />,
|
|
44
18
|
};
|
|
45
19
|
|
|
46
20
|
describe('Admission Requests Workspace', () => {
|
|
47
21
|
it('should render a admission request card', () => {
|
|
48
22
|
renderWithSwr(<AdmissionRequestsWorkspace {...workspaceProps} />);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
).toBeInTheDocument();
|
|
23
|
+
const alice = mockWardViewContext.wardPatientGroupDetails.inpatientRequestResponse.inpatientRequests[0].patient;
|
|
24
|
+
expect(screen.getByText(alice.person?.preferredName?.display as string)).toBeInTheDocument();
|
|
52
25
|
});
|
|
53
26
|
});
|
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import styles from './admission-requests-workspace.scss';
|
|
3
|
-
import AdmissionRequestCard from '../admission-request-card/admission-request-card.component';
|
|
4
1
|
import { Search } from '@carbon/react';
|
|
5
|
-
import {
|
|
2
|
+
import { type DefaultWorkspaceProps } from '@openmrs/esm-framework';
|
|
3
|
+
import React, { type ReactNode } from 'react';
|
|
6
4
|
import { useTranslation } from 'react-i18next';
|
|
7
|
-
import
|
|
8
|
-
import { type InpatientRequest } from '../../types';
|
|
5
|
+
import styles from './admission-requests-workspace.scss';
|
|
9
6
|
|
|
10
|
-
interface AdmissionRequestsWorkspaceProps {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const {
|
|
15
|
-
inpatientRequests,
|
|
16
|
-
isLoading: isLoadingInpatientRequests,
|
|
17
|
-
error: errorFetchingInpatientRequests,
|
|
18
|
-
} = useInpatientRequest(['ADMIT', 'TRANSFER']);
|
|
7
|
+
export interface AdmissionRequestsWorkspaceProps extends DefaultWorkspaceProps {
|
|
8
|
+
wardPendingPatients: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
const AdmissionRequestsWorkspace: React.FC<AdmissionRequestsWorkspaceProps> = ({ wardPendingPatients }) => {
|
|
19
11
|
const { t } = useTranslation();
|
|
20
12
|
const [searchTerm, setSearchTerm] = React.useState('');
|
|
21
13
|
const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
@@ -33,29 +25,7 @@ const AdmissionRequestsWorkspace: React.FC<AdmissionRequestsWorkspaceProps> = ()
|
|
|
33
25
|
disabled
|
|
34
26
|
/>
|
|
35
27
|
|
|
36
|
-
<div className={styles.content}>
|
|
37
|
-
{isLoadingInpatientRequests ? (
|
|
38
|
-
<>Loading</>
|
|
39
|
-
) : errorFetchingInpatientRequests ? (
|
|
40
|
-
<ErrorState
|
|
41
|
-
headerTitle={t('admissionRequests', 'Admission requests')}
|
|
42
|
-
error={errorFetchingInpatientRequests}
|
|
43
|
-
/>
|
|
44
|
-
) : (
|
|
45
|
-
<>
|
|
46
|
-
{inpatientRequests.map((request: InpatientRequest, i) => (
|
|
47
|
-
<AdmissionRequestCard
|
|
48
|
-
key={`admission-request-card-${i}`}
|
|
49
|
-
patient={request.patient}
|
|
50
|
-
visit={request.visit}
|
|
51
|
-
bed={null}
|
|
52
|
-
inpatientRequest={request}
|
|
53
|
-
inpatientAdmission={null}
|
|
54
|
-
/>
|
|
55
|
-
))}
|
|
56
|
-
</>
|
|
57
|
-
)}
|
|
58
|
-
</div>
|
|
28
|
+
<div className={styles.content}>{wardPendingPatients}</div>
|
|
59
29
|
</div>
|
|
60
30
|
);
|
|
61
31
|
};
|