@kenyaemr/esm-ward-app 8.1.2-pre.214 → 8.5.1-pre.18
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 +25 -35
- package/README.md +38 -0
- package/dist/1119.js +1 -0
- package/dist/1197.js +1 -0
- package/dist/1663.js +1 -0
- package/dist/1663.js.map +1 -0
- package/dist/1741.js +1 -0
- package/dist/1741.js.map +1 -0
- package/dist/1776.js +1 -0
- package/dist/1776.js.map +1 -0
- package/dist/1879.js +1 -0
- package/dist/1879.js.map +1 -0
- package/dist/1899.js +1 -0
- package/dist/1899.js.map +1 -0
- package/dist/1917.js +1 -0
- package/dist/1917.js.map +1 -0
- package/dist/2146.js +1 -0
- package/dist/2372.js +1 -0
- package/dist/2372.js.map +1 -0
- package/dist/2470.js +1 -0
- package/dist/2470.js.map +1 -0
- package/dist/2537.js +1 -0
- package/dist/2537.js.map +1 -0
- package/dist/2557.js +1 -0
- package/dist/2557.js.map +1 -0
- package/dist/2690.js +1 -0
- package/dist/2728.js +2 -0
- package/dist/{372.js.LICENSE.txt → 2728.js.LICENSE.txt} +2 -2
- package/dist/2728.js.map +1 -0
- package/dist/2775.js +2 -0
- package/dist/2775.js.LICENSE.txt +59 -0
- package/dist/2775.js.map +1 -0
- package/dist/2913.js +2 -0
- package/dist/2913.js.map +1 -0
- package/dist/2932.js +1 -0
- package/dist/2932.js.map +1 -0
- package/dist/2948.js +1 -0
- package/dist/2948.js.map +1 -0
- package/dist/3099.js +1 -0
- package/dist/3161.js +2 -0
- package/dist/{649.js.LICENSE.txt → 3161.js.LICENSE.txt} +2 -2
- package/dist/3161.js.map +1 -0
- package/dist/3365.js +1 -0
- package/dist/3365.js.map +1 -0
- package/dist/3373.js +2 -0
- package/dist/3373.js.LICENSE.txt +5 -0
- package/dist/3373.js.map +1 -0
- package/dist/3399.js +1 -0
- package/dist/3399.js.map +1 -0
- package/dist/3413.js +1 -0
- package/dist/3413.js.map +1 -0
- package/dist/3423.js +1 -0
- package/dist/3423.js.map +1 -0
- package/dist/3584.js +1 -0
- package/dist/3737.js +1 -0
- package/dist/3737.js.map +1 -0
- package/dist/3982.js +1 -0
- package/dist/3982.js.map +1 -0
- package/dist/4041.js +2 -0
- package/dist/4041.js.map +1 -0
- package/dist/4055.js +1 -0
- package/dist/4132.js +1 -0
- package/dist/4300.js +1 -0
- package/dist/4335.js +1 -0
- package/dist/4430.js +2 -0
- package/dist/4430.js.LICENSE.txt +29 -0
- package/dist/4430.js.map +1 -0
- package/dist/4618.js +1 -0
- package/dist/465.js +1 -0
- package/dist/465.js.map +1 -0
- package/dist/4652.js +1 -0
- package/dist/4701.js +2 -0
- package/dist/4701.js.LICENSE.txt +9 -0
- package/dist/4701.js.map +1 -0
- package/dist/4743.js +2 -0
- package/dist/4743.js.LICENSE.txt +9 -0
- package/dist/4743.js.map +1 -0
- package/dist/4944.js +1 -0
- package/dist/5173.js +1 -0
- package/dist/5241.js +1 -0
- package/dist/5442.js +1 -0
- package/dist/5661.js +1 -0
- package/dist/6012.js +2 -0
- package/dist/6012.js.LICENSE.txt +5 -0
- package/dist/6012.js.map +1 -0
- package/dist/6022.js +1 -0
- package/dist/6468.js +1 -0
- package/dist/6679.js +1 -0
- package/dist/6840.js +1 -0
- package/dist/6859.js +1 -0
- package/dist/7097.js +1 -0
- package/dist/7159.js +1 -0
- package/dist/7179.js +2 -0
- package/dist/7179.js.LICENSE.txt +9 -0
- package/dist/7179.js.map +1 -0
- package/dist/723.js +1 -0
- package/dist/7232.js +2 -0
- package/dist/7232.js.LICENSE.txt +9 -0
- package/dist/7232.js.map +1 -0
- package/dist/7524.js +1 -0
- package/dist/7524.js.map +1 -0
- package/dist/7617.js +1 -0
- package/dist/7661.js +1 -0
- package/dist/7661.js.map +1 -0
- package/dist/7886.js +1 -0
- package/dist/7886.js.map +1 -0
- package/dist/795.js +1 -0
- package/dist/8163.js +1 -0
- package/dist/8205.js +1 -0
- package/dist/8205.js.map +1 -0
- package/dist/8317.js +2 -0
- package/dist/8317.js.LICENSE.txt +15 -0
- package/dist/8317.js.map +1 -0
- package/dist/8349.js +1 -0
- package/dist/8501.js +1 -0
- package/dist/8501.js.map +1 -0
- package/dist/8522.js +1 -0
- package/dist/8522.js.map +1 -0
- package/dist/8618.js +1 -0
- package/dist/8622.js +1 -0
- package/dist/8622.js.map +1 -0
- package/dist/89.js +1 -0
- package/dist/89.js.map +1 -0
- package/dist/890.js +1 -0
- package/dist/9045.js +1 -0
- package/dist/9045.js.map +1 -0
- package/dist/9117.js +1 -0
- package/dist/9117.js.map +1 -0
- package/dist/9214.js +1 -0
- package/dist/9538.js +1 -0
- package/dist/9569.js +1 -0
- package/dist/986.js +1 -0
- package/dist/9876.js +2 -0
- package/dist/9876.js.LICENSE.txt +9 -0
- package/dist/9876.js.map +1 -0
- package/dist/9879.js +1 -0
- package/dist/9880.js +1 -0
- package/dist/9880.js.map +1 -0
- package/dist/9895.js +1 -0
- package/dist/9900.js +1 -0
- package/dist/9913.js +1 -0
- package/dist/kenyaemr-esm-ward-app.js +1 -1
- package/dist/kenyaemr-esm-ward-app.js.buildmanifest.json +1479 -235
- package/dist/kenyaemr-esm-ward-app.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.LICENSE.txt +0 -35
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/mock.tsx +15 -2
- package/package.json +10 -5
- package/src/beds/{empty-bed-skeleton.tsx → empty-bed-skeleton.component.tsx} +2 -2
- package/src/config-schema.ts +48 -0
- package/src/declarations.d.ts +8 -0
- package/src/hooks/useAdmissionLocation.ts +24 -4
- package/src/hooks/useInpatientAdmission.ts +14 -10
- package/src/hooks/useInpatientAdmissionByPatients.ts +29 -0
- package/src/hooks/useInpatientRequest.ts +5 -1
- package/src/hooks/useInpatientRequestByPatients.ts +34 -0
- package/src/hooks/useIpdDischargeEncounter.ts +137 -0
- package/src/hooks/usePatientPendingOrders.ts +1 -1
- package/src/hooks/useRestPatient.ts +11 -3
- package/src/hooks/useSummaryMetrics.ts +103 -0
- package/src/hooks/useWardLocation.test.ts +1 -1
- package/src/hooks/useWardLocation.ts +18 -5
- package/src/hooks/useWardPatientGrouping.ts +63 -10
- package/src/index.ts +24 -4
- package/src/location-selector/location-selector.component.tsx +38 -5
- package/src/root.component.tsx +2 -2
- package/src/routes.json +60 -26
- package/src/types/index.ts +17 -6
- package/src/ward-patient-card/card-rows/admission-request-note-row.component.tsx +1 -1
- package/src/ward-patient-card/card-rows/coded-obs-tags-row.component.tsx +4 -4
- package/src/ward-patient-card/card-rows/mother-child-row.component.tsx +6 -6
- package/src/ward-patient-card/card-rows/pending-items-row.component.tsx +2 -3
- package/src/ward-patient-card/row-elements/{ward-patient-coded-obs-tags.tsx → ward-patient-coded-obs-tags.component.tsx} +5 -5
- package/src/ward-patient-card/row-elements/{ward-patient-header-address.tsx → ward-patient-header-address.component.tsx} +2 -2
- package/src/ward-patient-card/row-elements/{ward-patient-identifier.tsx → ward-patient-identifier.component.tsx} +7 -1
- package/src/ward-patient-card/row-elements/ward-patient-identifier.scss +3 -0
- package/src/ward-patient-card/row-elements/{ward-patient-obs.tsx → ward-patient-obs.component.tsx} +5 -5
- package/src/ward-patient-card/row-elements/{ward-patient-pending-transfer.tsx → ward-patient-pending-transfer.component.tsx} +3 -5
- package/src/ward-patient-card/row-elements/ward-patient-time-on-ward.component.tsx +73 -0
- package/src/ward-patient-card/row-elements/ward-patient-time-since-admission.component.tsx +29 -0
- package/src/ward-patient-card/ward-patient-card.component.tsx +5 -5
- package/src/ward-patient-card/ward-patient-card.scss +2 -6
- package/src/ward-patients/admitted-patients.tsx +218 -0
- package/src/ward-patients/awaiting-admission-patients.tsx +158 -0
- package/src/ward-patients/discharge-in-patients.tsx +183 -0
- package/src/ward-patients/discharge-patients.tsx +129 -0
- package/src/ward-patients/patient-cells.tsx +75 -0
- package/src/ward-patients/table-state-components.tsx +40 -0
- package/src/ward-patients/ward-patient.scss +24 -0
- package/src/ward-patients/ward-patients-table.tsx +38 -0
- package/src/ward-view/default-ward/default-ward-patient-card-header.component.tsx +8 -8
- package/src/ward-view/default-ward/default-ward-pending-patients.component.tsx +3 -3
- package/src/ward-view/default-ward/default-ward-view.component.tsx +33 -6
- package/src/ward-view/linelist-wards/Filters.tsx +25 -0
- package/src/ward-view/linelist-wards/Header.tsx +27 -0
- package/src/ward-view/linelist-wards/LineListTable.tsx +145 -0
- package/src/ward-view/linelist-wards/Metrics.tsx +21 -0
- package/src/ward-view/linelist-wards/WardPendingOutCell.tsx +15 -0
- package/src/ward-view/linelist-wards/WardsLineList.tsx +30 -0
- package/src/ward-view/linelist-wards/linelist-wards.scss +100 -0
- package/src/ward-view/materal-ward/maternal-ward-patient-card-header.component.tsx +8 -8
- package/src/ward-view/materal-ward/maternal-ward-patient-card.component.tsx +2 -2
- package/src/ward-view/materal-ward/maternal-ward-patient-card.test.tsx +1 -1
- package/src/ward-view/materal-ward/maternal-ward-pending-patients.component.tsx +1 -1
- package/src/ward-view/materal-ward/maternal-ward-view.component.tsx +4 -4
- package/src/ward-view/ward-view-content-wrapper.tsx +36 -0
- package/src/ward-view/ward-view.resource.ts +26 -8
- package/src/ward-view/ward-view.scss +15 -8
- package/src/ward-view/ward-view.test.tsx +8 -8
- package/src/ward-view/ward.component.tsx +2 -2
- package/src/ward-view-header/admission-requests-bar.component.tsx +18 -8
- package/src/ward-view-header/admission-requests-bar.test.tsx +3 -3
- package/src/ward-view-header/ward-metric.component.tsx +2 -3
- package/src/ward-workspace/admission-request-card/admission-request-card-actions.component.tsx +12 -14
- package/src/ward-workspace/admission-request-card/admission-request-card-header.component.tsx +5 -5
- package/src/ward-workspace/admission-request-card/admission-request-card.component.tsx +1 -1
- package/src/ward-workspace/admission-request-workspace/admission-requests-action-button.extension.tsx +18 -0
- package/src/ward-workspace/admission-request-workspace/admission-requests-context.ts +20 -0
- package/src/ward-workspace/admission-request-workspace/admission-requests-workspace.test.tsx +7 -6
- package/src/ward-workspace/admission-request-workspace/admission-requests.workspace.tsx +15 -25
- package/src/ward-workspace/admit-patient-button.component.tsx +41 -18
- package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.test.tsx +14 -16
- package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.workspace.tsx +2 -2
- package/src/ward-workspace/bed-selector.component.tsx +1 -1
- package/src/ward-workspace/cancel-admission-request-workspace/cancel-admission-request.test.tsx +1 -1
- package/src/ward-workspace/cancel-admission-request-workspace/cancel-admission-request.workspace.tsx +4 -6
- package/src/ward-workspace/create-admission-encounter/create-admission-encounter-action-button.extension.tsx +46 -0
- package/src/ward-workspace/create-admission-encounter/create-admission-encounter.test.tsx +241 -0
- package/src/ward-workspace/create-admission-encounter/create-admission-encounter.workspace.tsx +152 -0
- package/src/ward-workspace/kenya-emr-patient-discharge/discharge-workspace-siderail.component.tsx +23 -0
- package/src/ward-workspace/kenya-emr-patient-discharge/patient-discharge.resource.tsx +123 -0
- package/src/ward-workspace/kenya-emr-patient-discharge/patient-discharge.workspace.tsx +101 -0
- package/src/ward-workspace/patient-discharge/patient-discharge.workspace.tsx +6 -15
- package/src/ward-workspace/patient-transfer-bed-swap/{patient-transfer-request-form.component.tsx → patient-admit-or-transfer-request-form.component.tsx} +56 -37
- package/src/ward-workspace/patient-transfer-bed-swap/patient-bed-swap-form.component.tsx +13 -3
- package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-swap.workspace.tsx +11 -5
- package/src/ward-workspace/patient-transfer-request-workspace/patient-transfer-request.scss +5 -0
- package/src/ward-workspace/patient-transfer-request-workspace/patient-transfer-request.workspace.tsx +20 -6
- package/src/ward-workspace/ward-patient-notes/form/notes-form.component.tsx +2 -1
- package/src/ward-workspace/ward-patient-notes/history/note.component.tsx +3 -3
- package/src/ward.resource.ts +9 -3
- package/translations/am.json +123 -0
- package/translations/ar.json +123 -0
- package/translations/ar_SY.json +123 -0
- package/translations/bn.json +123 -0
- package/translations/de.json +123 -0
- package/translations/en.json +31 -3
- package/translations/en_US.json +123 -0
- package/translations/es.json +123 -0
- package/translations/es_MX.json +123 -0
- package/translations/fr.json +123 -0
- package/translations/he.json +123 -0
- package/translations/hi.json +123 -0
- package/translations/hi_IN.json +123 -0
- package/translations/id.json +123 -0
- package/translations/it.json +123 -0
- package/translations/ka.json +123 -0
- package/translations/km.json +123 -0
- package/translations/ku.json +123 -0
- package/translations/ky.json +123 -0
- package/translations/lg.json +123 -0
- package/translations/ne.json +123 -0
- package/translations/pl.json +123 -0
- package/translations/pt.json +123 -0
- package/translations/pt_BR.json +123 -0
- package/translations/qu.json +123 -0
- package/translations/ro_RO.json +123 -0
- package/translations/ru_RU.json +123 -0
- package/translations/si.json +123 -0
- package/translations/sw.json +123 -0
- package/translations/sw_KE.json +123 -0
- package/translations/tr.json +123 -0
- package/translations/tr_TR.json +123 -0
- package/translations/uk.json +123 -0
- package/translations/uz.json +123 -0
- package/translations/uz@Latn.json +123 -0
- package/translations/uz_UZ.json +123 -0
- package/translations/vi.json +123 -0
- package/translations/zh.json +123 -0
- package/translations/zh_CN.json +123 -0
- package/dist/109.js +0 -1
- package/dist/109.js.map +0 -1
- package/dist/124.js +0 -1
- package/dist/124.js.map +0 -1
- package/dist/125.js +0 -1
- package/dist/125.js.map +0 -1
- package/dist/126.js +0 -1
- package/dist/126.js.map +0 -1
- package/dist/130.js +0 -2
- package/dist/130.js.LICENSE.txt +0 -5
- package/dist/130.js.map +0 -1
- package/dist/146.js +0 -1
- package/dist/146.js.map +0 -1
- package/dist/15.js +0 -1
- package/dist/15.js.map +0 -1
- package/dist/325.js +0 -1
- package/dist/325.js.map +0 -1
- package/dist/348.js +0 -1
- package/dist/348.js.map +0 -1
- package/dist/362.js +0 -1
- package/dist/362.js.map +0 -1
- package/dist/372.js +0 -2
- package/dist/372.js.map +0 -1
- package/dist/443.js +0 -1
- package/dist/443.js.map +0 -1
- package/dist/471.js +0 -1
- package/dist/471.js.map +0 -1
- package/dist/481.js +0 -1
- package/dist/481.js.map +0 -1
- package/dist/53.js +0 -1
- package/dist/53.js.map +0 -1
- package/dist/559.js +0 -1
- package/dist/559.js.map +0 -1
- package/dist/574.js +0 -1
- package/dist/576.js +0 -1
- package/dist/576.js.map +0 -1
- package/dist/577.js +0 -1
- package/dist/577.js.map +0 -1
- package/dist/591.js +0 -2
- package/dist/591.js.map +0 -1
- package/dist/598.js +0 -1
- package/dist/598.js.map +0 -1
- package/dist/649.js +0 -2
- package/dist/649.js.map +0 -1
- package/dist/662.js +0 -1
- package/dist/662.js.map +0 -1
- package/dist/767.js +0 -1
- package/dist/767.js.map +0 -1
- package/dist/784.js +0 -2
- package/dist/784.js.map +0 -1
- package/dist/921.js +0 -1
- package/dist/921.js.map +0 -1
- package/dist/922.js +0 -1
- package/dist/922.js.map +0 -1
- package/dist/925.js +0 -2
- package/dist/925.js.LICENSE.txt +0 -40
- package/dist/925.js.map +0 -1
- package/dist/940.js +0 -1
- package/dist/940.js.map +0 -1
- package/dist/969.js +0 -1
- package/dist/969.js.map +0 -1
- package/dist/983.js +0 -1
- package/dist/983.js.map +0 -1
- package/package-lock.json +0 -5001
- package/src/ward-patient-card/row-elements/ward-patient-time-on-ward.tsx +0 -22
- package/src/ward-patient-card/row-elements/ward-patient-time-since-admission.tsx +0 -22
- /package/dist/{591.js.LICENSE.txt → 2913.js.LICENSE.txt} +0 -0
- /package/dist/{784.js.LICENSE.txt → 4041.js.LICENSE.txt} +0 -0
- /package/src/ward-patient-card/row-elements/{ward-patient-age.tsx → ward-patient-age.component.tsx} +0 -0
- /package/src/ward-patient-card/row-elements/{ward-patient-bed-number.tsx → ward-patient-bed-number.component.tsx} +0 -0
- /package/src/ward-patient-card/row-elements/{ward-patient-location.tsx → ward-patient-location.component.tsx} +0 -0
- /package/src/ward-patient-card/row-elements/{ward-patient-name.tsx → ward-patient-name.component.tsx} +0 -0
- /package/src/ward-patient-card/row-elements/{ward-patient-responsive-tooltip.tsx → ward-patient-responsive-tooltip.component.tsx} +0 -0
- /package/src/ward-patient-card/row-elements/{ward-patient-skeleton-text.tsx → ward-patient-skeleton-text.component.tsx} +0 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OverflowMenu,
|
|
3
|
+
OverflowMenuItem,
|
|
4
|
+
DataTable,
|
|
5
|
+
TableContainer,
|
|
6
|
+
Table,
|
|
7
|
+
TableHead,
|
|
8
|
+
TableRow,
|
|
9
|
+
TableHeader,
|
|
10
|
+
TableBody,
|
|
11
|
+
TableCell,
|
|
12
|
+
Pagination,
|
|
13
|
+
} from '@carbon/react';
|
|
14
|
+
import React, { useMemo, useState } from 'react';
|
|
15
|
+
import { useTranslation } from 'react-i18next';
|
|
16
|
+
import { EmptyState } from './table-state-components';
|
|
17
|
+
import {
|
|
18
|
+
formatDatetime,
|
|
19
|
+
launchWorkspace,
|
|
20
|
+
type OpenmrsResource,
|
|
21
|
+
parseDate,
|
|
22
|
+
useAppContext,
|
|
23
|
+
useConfig,
|
|
24
|
+
usePagination,
|
|
25
|
+
} from '@openmrs/esm-framework';
|
|
26
|
+
import { type WardPatient, type WardViewContext } from '../types';
|
|
27
|
+
import { bedLayoutToBed, getOpenmrsId } from '../ward-view/ward-view.resource';
|
|
28
|
+
import dayjs from 'dayjs';
|
|
29
|
+
import { usePaginationInfo } from '@openmrs/esm-patient-common-lib';
|
|
30
|
+
import { type WardConfigObject } from '../config-schema';
|
|
31
|
+
|
|
32
|
+
const DischargeInPatients = () => {
|
|
33
|
+
const { t } = useTranslation();
|
|
34
|
+
const { wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
|
|
35
|
+
const { bedLayouts, wardAdmittedPatientsWithBed, isLoading } = wardPatientGroupDetails ?? {};
|
|
36
|
+
const config = useConfig<WardConfigObject>();
|
|
37
|
+
const headers = [
|
|
38
|
+
{ key: 'admissionDate', header: t('admissionDate', 'Admission Date') },
|
|
39
|
+
{ key: 'idNumber', header: t('idNumber', 'ID Number') },
|
|
40
|
+
{ key: 'name', header: t('name', 'Name') },
|
|
41
|
+
{ key: 'gender', header: t('gender', 'Gender') },
|
|
42
|
+
{ key: 'age', header: t('age', 'Age') },
|
|
43
|
+
{ key: 'bedNumber', header: t('bedNumber', 'Bed Number') },
|
|
44
|
+
{ key: 'daysAdmitted', header: t('durationOnWard', 'Duration on Ward') },
|
|
45
|
+
{ key: 'action', header: t('action', 'Action') },
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const patients = useMemo(() => {
|
|
49
|
+
return (
|
|
50
|
+
bedLayouts
|
|
51
|
+
?.map((bedLayout) => {
|
|
52
|
+
const { patients } = bedLayout;
|
|
53
|
+
const bed = bedLayoutToBed(bedLayout);
|
|
54
|
+
const wardPatients: WardPatient[] = patients.map((patient): WardPatient => {
|
|
55
|
+
const inpatientAdmission = wardAdmittedPatientsWithBed?.get(patient.uuid);
|
|
56
|
+
if (inpatientAdmission) {
|
|
57
|
+
const { patient, visit, currentInpatientRequest } = inpatientAdmission;
|
|
58
|
+
return { patient, visit, bed, inpatientAdmission, inpatientRequest: currentInpatientRequest || null };
|
|
59
|
+
} else {
|
|
60
|
+
// for some reason this patient is in a bed but not in the list of admitted patients, so we need to use the patient data from the bed endpoint
|
|
61
|
+
return {
|
|
62
|
+
patient: patient,
|
|
63
|
+
visit: null,
|
|
64
|
+
bed,
|
|
65
|
+
inpatientAdmission: null, // populate after BED-13
|
|
66
|
+
inpatientRequest: null,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
return wardPatients;
|
|
71
|
+
})
|
|
72
|
+
?.flat() ?? []
|
|
73
|
+
).filter((pat) => {
|
|
74
|
+
const noteEncounter = pat?.visit?.encounters?.find(
|
|
75
|
+
(encounter) => encounter.encounterType?.uuid === config.doctorsnoteEncounterTypeUuid,
|
|
76
|
+
);
|
|
77
|
+
if (!noteEncounter) return false;
|
|
78
|
+
const obs = noteEncounter.obs.find((ob) => ob.concept.uuid === config.referralsConceptUuid);
|
|
79
|
+
if (!obs) return false;
|
|
80
|
+
const isDischargedIn = [config.referringToAnotherFacilityConceptUuid, config.dischargeHomeConceptUuid].includes(
|
|
81
|
+
(obs.value as OpenmrsResource).uuid,
|
|
82
|
+
);
|
|
83
|
+
return isDischargedIn === true;
|
|
84
|
+
});
|
|
85
|
+
}, [bedLayouts, wardAdmittedPatientsWithBed, config]);
|
|
86
|
+
|
|
87
|
+
const [pageSize, setPageSize] = useState(5);
|
|
88
|
+
const { paginated, results, totalPages, currentPage, goTo } = usePagination(patients, pageSize);
|
|
89
|
+
const { pageSizes } = usePaginationInfo(pageSize, totalPages, currentPage, results.length);
|
|
90
|
+
|
|
91
|
+
const tableRows = useMemo(() => {
|
|
92
|
+
return results.map((patient, index) => {
|
|
93
|
+
const { encounterAssigningToCurrentInpatientLocation } = patient.inpatientAdmission ?? {};
|
|
94
|
+
|
|
95
|
+
const admissionDate = encounterAssigningToCurrentInpatientLocation?.encounterDatetime
|
|
96
|
+
? formatDatetime(parseDate(encounterAssigningToCurrentInpatientLocation!.encounterDatetime!))
|
|
97
|
+
: '--';
|
|
98
|
+
const daysAdmitted = encounterAssigningToCurrentInpatientLocation?.encounterDatetime
|
|
99
|
+
? dayjs(encounterAssigningToCurrentInpatientLocation?.encounterDatetime).diff(dayjs(), 'days')
|
|
100
|
+
: '--';
|
|
101
|
+
return {
|
|
102
|
+
id: patient.patient?.uuid ?? index,
|
|
103
|
+
admissionDate,
|
|
104
|
+
idNumber: getOpenmrsId(patient.patient?.identifiers ?? []) ?? '--',
|
|
105
|
+
name: patient.patient?.person?.display ?? '--',
|
|
106
|
+
gender: patient.patient?.person?.gender ?? '--',
|
|
107
|
+
age: patient.patient?.person?.age ?? '--',
|
|
108
|
+
bedNumber: patient.bed?.bedNumber ?? '--',
|
|
109
|
+
daysAdmitted,
|
|
110
|
+
action: (
|
|
111
|
+
<OverflowMenu size={'sm'} flipped>
|
|
112
|
+
<OverflowMenuItem itemText={t('goToBilling', 'Go to Billing')} onClick={() => {}} />
|
|
113
|
+
<OverflowMenuItem itemText={t('waivePatient', 'Waive Patient')} onClick={() => {}} />
|
|
114
|
+
<OverflowMenuItem itemText={t('patientAbscondend', 'Patient Absconded')} onClick={() => {}} />
|
|
115
|
+
<OverflowMenuItem
|
|
116
|
+
itemText={t('discharge', 'Discharge')}
|
|
117
|
+
onClick={() => {
|
|
118
|
+
launchWorkspace('patient-discharge-workspace', {
|
|
119
|
+
wardPatient: patient,
|
|
120
|
+
patientUuid: patient.patient.uuid,
|
|
121
|
+
formUuid: config.inpatientDischargeFormUuid,
|
|
122
|
+
});
|
|
123
|
+
}}
|
|
124
|
+
/>
|
|
125
|
+
</OverflowMenu>
|
|
126
|
+
),
|
|
127
|
+
};
|
|
128
|
+
});
|
|
129
|
+
}, [results, config, t]);
|
|
130
|
+
|
|
131
|
+
if (!patients.length) return <EmptyState message={t('noDischargeInpatients', 'No Discharge in patients')} />;
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<DataTable rows={tableRows} headers={headers} isSortable useZebraStyles>
|
|
135
|
+
{({ rows, headers, getHeaderProps, getRowProps, getTableProps, getCellProps }) => (
|
|
136
|
+
<TableContainer>
|
|
137
|
+
<Table {...getTableProps()} aria-label="sample table">
|
|
138
|
+
<TableHead>
|
|
139
|
+
<TableRow>
|
|
140
|
+
{headers.map((header) => (
|
|
141
|
+
<TableHeader
|
|
142
|
+
key={header.key}
|
|
143
|
+
{...getHeaderProps({
|
|
144
|
+
header,
|
|
145
|
+
})}>
|
|
146
|
+
{header.header}
|
|
147
|
+
</TableHeader>
|
|
148
|
+
))}
|
|
149
|
+
</TableRow>
|
|
150
|
+
</TableHead>
|
|
151
|
+
<TableBody>
|
|
152
|
+
{rows.map((row) => {
|
|
153
|
+
return (
|
|
154
|
+
<TableRow key={row.id} {...getRowProps({ row })}>
|
|
155
|
+
{row.cells.map((cell) => (
|
|
156
|
+
<TableCell key={cell.id} {...getCellProps({ cell })}>
|
|
157
|
+
{cell.value}
|
|
158
|
+
</TableCell>
|
|
159
|
+
))}
|
|
160
|
+
</TableRow>
|
|
161
|
+
);
|
|
162
|
+
})}
|
|
163
|
+
</TableBody>
|
|
164
|
+
</Table>
|
|
165
|
+
{paginated && !isLoading && (
|
|
166
|
+
<Pagination
|
|
167
|
+
page={currentPage}
|
|
168
|
+
pageSize={pageSize}
|
|
169
|
+
pageSizes={pageSizes}
|
|
170
|
+
totalItems={(patients ?? []).length}
|
|
171
|
+
onChange={({ page, pageSize }) => {
|
|
172
|
+
goTo(page);
|
|
173
|
+
setPageSize(pageSize);
|
|
174
|
+
}}
|
|
175
|
+
/>
|
|
176
|
+
)}
|
|
177
|
+
</TableContainer>
|
|
178
|
+
)}
|
|
179
|
+
</DataTable>
|
|
180
|
+
);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export default DischargeInPatients;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataTable,
|
|
3
|
+
DataTableSkeleton,
|
|
4
|
+
OverflowMenu,
|
|
5
|
+
OverflowMenuItem,
|
|
6
|
+
Table,
|
|
7
|
+
TableBody,
|
|
8
|
+
TableCell,
|
|
9
|
+
TableContainer,
|
|
10
|
+
TableHead,
|
|
11
|
+
TableHeader,
|
|
12
|
+
TableRow,
|
|
13
|
+
Pagination,
|
|
14
|
+
} from '@carbon/react';
|
|
15
|
+
import React, { useMemo } from 'react';
|
|
16
|
+
import { useTranslation } from 'react-i18next';
|
|
17
|
+
import { EmptyState, ErrorState } from './table-state-components';
|
|
18
|
+
import { useIpdDischargeEncounter } from '../hooks/useIpdDischargeEncounter';
|
|
19
|
+
import { formatDatetime, parseDate } from '@openmrs/esm-framework';
|
|
20
|
+
import { PatientAdmissionDateCell, PatientAgeCell, PatientDayInWardCell, PatientGenderCell } from './patient-cells';
|
|
21
|
+
|
|
22
|
+
const DischargePatients = () => {
|
|
23
|
+
const { t } = useTranslation();
|
|
24
|
+
const {
|
|
25
|
+
encounters,
|
|
26
|
+
error,
|
|
27
|
+
isLoading,
|
|
28
|
+
paginated,
|
|
29
|
+
currentPage,
|
|
30
|
+
pageSizes,
|
|
31
|
+
goTo,
|
|
32
|
+
currPageSize,
|
|
33
|
+
setCurrPageSize,
|
|
34
|
+
totalCount,
|
|
35
|
+
} = useIpdDischargeEncounter();
|
|
36
|
+
const headers = [
|
|
37
|
+
{ key: 'admissionDate', header: t('admissionDate', 'Admission Date') },
|
|
38
|
+
{ key: 'dischargeDate', header: t('dischargeDate', 'Discharge Date') },
|
|
39
|
+
{ key: 'idNumber', header: t('idNumber', 'ID Number') },
|
|
40
|
+
{ key: 'name', header: t('name', 'Name') },
|
|
41
|
+
{ key: 'gender', header: t('gender', 'Gender') },
|
|
42
|
+
{ key: 'age', header: t('age', 'Age') },
|
|
43
|
+
{ key: 'bedNumber', header: t('bedNumber', 'Bed Number') },
|
|
44
|
+
{ key: 'daysAdmitted', header: t('durationOnWard', 'Duration on Ward') },
|
|
45
|
+
{ key: 'action', header: t('action', 'Action') },
|
|
46
|
+
];
|
|
47
|
+
const tableRows = useMemo(() => {
|
|
48
|
+
return encounters.map((encounter, index) => {
|
|
49
|
+
return {
|
|
50
|
+
id: encounter.uuid,
|
|
51
|
+
dischargeDate: encounter.encounterDateTime ? formatDatetime(parseDate(encounter.encounterDateTime)) : '--',
|
|
52
|
+
admissionDate: <PatientAdmissionDateCell patientUuid={encounter.patient.uuid} encounterUuid={encounter.uuid} />,
|
|
53
|
+
idNumber: encounter.patient.openmrsId,
|
|
54
|
+
name: encounter.patient.name,
|
|
55
|
+
gender: <PatientGenderCell patientUuid={encounter.patient.uuid} />,
|
|
56
|
+
age: <PatientAgeCell patientUuid={encounter.patient.uuid} />,
|
|
57
|
+
bedNumber: '--',
|
|
58
|
+
daysAdmitted: <PatientDayInWardCell patientUuid={encounter.patient.uuid} encounterUuid={encounter.uuid} />,
|
|
59
|
+
action: (
|
|
60
|
+
<OverflowMenu size={'sm'} flipped>
|
|
61
|
+
<OverflowMenuItem itemText={t('dischargeSummary', 'Discharge Summary')} onClick={() => {}} />
|
|
62
|
+
<OverflowMenuItem itemText={t('gatePass', 'Gate Pass')} onClick={() => {}} />
|
|
63
|
+
</OverflowMenu>
|
|
64
|
+
),
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
}, [encounters, t]);
|
|
68
|
+
|
|
69
|
+
if (isLoading) return <DataTableSkeleton />;
|
|
70
|
+
if (error) return <ErrorState error={error} />;
|
|
71
|
+
|
|
72
|
+
if (!encounters?.length) return <EmptyState message={t('noDischargepatients', 'No Discharge patients')} />;
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<DataTable rows={tableRows} headers={headers} isSortable useZebraStyles>
|
|
76
|
+
{({ rows, headers, getHeaderProps, getRowProps, getTableProps, getCellProps }) => (
|
|
77
|
+
<TableContainer>
|
|
78
|
+
<Table {...getTableProps()} aria-label="sample table">
|
|
79
|
+
<TableHead>
|
|
80
|
+
<TableRow>
|
|
81
|
+
{headers.map((header) => (
|
|
82
|
+
<TableHeader
|
|
83
|
+
key={header.key}
|
|
84
|
+
{...getHeaderProps({
|
|
85
|
+
header,
|
|
86
|
+
})}>
|
|
87
|
+
{header.header}
|
|
88
|
+
</TableHeader>
|
|
89
|
+
))}
|
|
90
|
+
</TableRow>
|
|
91
|
+
</TableHead>
|
|
92
|
+
<TableBody>
|
|
93
|
+
{rows.map((row) => {
|
|
94
|
+
return (
|
|
95
|
+
<TableRow key={row.id} {...getRowProps({ row })}>
|
|
96
|
+
{row.cells.map((cell) => (
|
|
97
|
+
<TableCell key={cell.id} {...getCellProps({ cell })}>
|
|
98
|
+
{cell.value}
|
|
99
|
+
</TableCell>
|
|
100
|
+
))}
|
|
101
|
+
</TableRow>
|
|
102
|
+
);
|
|
103
|
+
})}
|
|
104
|
+
</TableBody>
|
|
105
|
+
</Table>
|
|
106
|
+
{paginated && !isLoading && (
|
|
107
|
+
<Pagination
|
|
108
|
+
forwardText=""
|
|
109
|
+
backwardText=""
|
|
110
|
+
page={currentPage}
|
|
111
|
+
pageSize={currPageSize}
|
|
112
|
+
pageSizes={pageSizes}
|
|
113
|
+
totalItems={totalCount}
|
|
114
|
+
size={'sm'}
|
|
115
|
+
onChange={({ page: newPage, pageSize }) => {
|
|
116
|
+
if (newPage !== currentPage) {
|
|
117
|
+
goTo(newPage);
|
|
118
|
+
}
|
|
119
|
+
setCurrPageSize(pageSize);
|
|
120
|
+
}}
|
|
121
|
+
/>
|
|
122
|
+
)}
|
|
123
|
+
</TableContainer>
|
|
124
|
+
)}
|
|
125
|
+
</DataTable>
|
|
126
|
+
);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export default DischargePatients;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { InlineLoading } from '@carbon/react';
|
|
2
|
+
import { formatDatetime, parseDate, useConfig, usePatient } from '@openmrs/esm-framework';
|
|
3
|
+
import dayjs from 'dayjs';
|
|
4
|
+
import React, { type FC, useMemo } from 'react';
|
|
5
|
+
import { useEncounterDetails } from '../hooks/useIpdDischargeEncounter';
|
|
6
|
+
import { type WardConfigObject } from '../config-schema';
|
|
7
|
+
|
|
8
|
+
type CellProps = {
|
|
9
|
+
patientUuid: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const PatientAgeCell: FC<CellProps> = ({ patientUuid }) => {
|
|
13
|
+
const { isLoading, patient, error } = usePatient(patientUuid);
|
|
14
|
+
const age = useMemo(() => {
|
|
15
|
+
if (!patient?.birthDate) return '--';
|
|
16
|
+
return dayjs().diff(dayjs(patient.birthDate), 'years');
|
|
17
|
+
}, [patient?.birthDate]);
|
|
18
|
+
if (isLoading) return <InlineLoading />;
|
|
19
|
+
if (error) return <p>--</p>;
|
|
20
|
+
return <div>{age}</div>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const PatientGenderCell: FC<CellProps> = ({ patientUuid }) => {
|
|
24
|
+
const { isLoading, patient, error } = usePatient(patientUuid);
|
|
25
|
+
|
|
26
|
+
if (isLoading) return <InlineLoading />;
|
|
27
|
+
if (error) return <p>--</p>;
|
|
28
|
+
return <div>{patient.gender}</div>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
type PatientAdmissionCellProps = CellProps & {
|
|
32
|
+
encounterUuid: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const PatientAdmissionDateCell: FC<PatientAdmissionCellProps> = ({ encounterUuid }) => {
|
|
36
|
+
const { encounter, error, isLoading } = useEncounterDetails(encounterUuid);
|
|
37
|
+
const { admissionEncounterTypeUuid } = useConfig<WardConfigObject>();
|
|
38
|
+
|
|
39
|
+
const admissionDate = useMemo(() => {
|
|
40
|
+
const admisionEncounter = encounter?.visit?.encounters?.find(
|
|
41
|
+
(e) => e.encounterType.uuid === admissionEncounterTypeUuid,
|
|
42
|
+
);
|
|
43
|
+
if (!admisionEncounter || !admisionEncounter.encounterDatetime) return '--';
|
|
44
|
+
return formatDatetime(parseDate(admisionEncounter.encounterDatetime));
|
|
45
|
+
}, [encounter, admissionEncounterTypeUuid]);
|
|
46
|
+
if (isLoading) return <InlineLoading />;
|
|
47
|
+
if (error) return <p>--</p>;
|
|
48
|
+
|
|
49
|
+
return <p>{admissionDate}</p>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const PatientDayInWardCell: FC<PatientAdmissionCellProps> = ({ encounterUuid }) => {
|
|
53
|
+
const { encounter, error, isLoading } = useEncounterDetails(encounterUuid);
|
|
54
|
+
const { admissionEncounterTypeUuid } = useConfig<WardConfigObject>();
|
|
55
|
+
const daysInWard = useMemo(() => {
|
|
56
|
+
const admisionEncounter = encounter?.visit?.encounters?.find(
|
|
57
|
+
(e) => e.encounterType.uuid === admissionEncounterTypeUuid,
|
|
58
|
+
);
|
|
59
|
+
if (!admisionEncounter || !admisionEncounter.encounterDatetime) return '--';
|
|
60
|
+
const dischargeEncounter = encounter?.visit?.encounters?.find((e) => e.uuid === encounterUuid);
|
|
61
|
+
if (!dischargeEncounter || !dischargeEncounter.encounterDatetime) return '--';
|
|
62
|
+
|
|
63
|
+
const admissionDate = dayjs(admisionEncounter.encounterDatetime).startOf('day');
|
|
64
|
+
const dischargeDate = dischargeEncounter.encounterDatetime
|
|
65
|
+
? dayjs(dischargeEncounter.encounterDatetime).startOf('day')
|
|
66
|
+
: dayjs().startOf('day');
|
|
67
|
+
const daysAdmitted =
|
|
68
|
+
admissionDate.isValid() && dischargeDate.isValid() ? Math.abs(dischargeDate.diff(admissionDate, 'days')) : '--';
|
|
69
|
+
return daysAdmitted;
|
|
70
|
+
}, [encounter, encounterUuid, admissionEncounterTypeUuid]);
|
|
71
|
+
if (isLoading) return <InlineLoading />;
|
|
72
|
+
if (error) return <p>--</p>;
|
|
73
|
+
|
|
74
|
+
return <p>{daysInWard}</p>;
|
|
75
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Desclaimer: not using openmrs provided (EmptyState,ErrorState) to avoid repeated header titles and customize the message since provided ones are contexted to patient chart
|
|
2
|
+
|
|
3
|
+
import { Tile } from '@carbon/react';
|
|
4
|
+
import { EmptyDataIllustration } from '@openmrs/esm-patient-common-lib';
|
|
5
|
+
import React, { type FC } from 'react';
|
|
6
|
+
import styles from './ward-patient.scss';
|
|
7
|
+
import { useTranslation } from 'react-i18next';
|
|
8
|
+
type EmptyStateProps = {
|
|
9
|
+
message?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const EmptyState: FC<EmptyStateProps> = ({ message }) => {
|
|
13
|
+
return (
|
|
14
|
+
<Tile className={styles.empty}>
|
|
15
|
+
<EmptyDataIllustration />
|
|
16
|
+
<p>{message}</p>
|
|
17
|
+
</Tile>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
type ErrorStateProps = {
|
|
21
|
+
error?: Error;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const ErrorState: FC<ErrorStateProps> = ({ error }) => {
|
|
25
|
+
const { t } = useTranslation();
|
|
26
|
+
return (
|
|
27
|
+
<Tile className={styles.error}>
|
|
28
|
+
<strong>
|
|
29
|
+
{t('error', 'Error')} {`${(error as any)?.response?.status}: `}
|
|
30
|
+
{(error as any)?.response?.statusText}
|
|
31
|
+
</strong>
|
|
32
|
+
<p>
|
|
33
|
+
{t(
|
|
34
|
+
'errorCopy',
|
|
35
|
+
'Sorry, there was a problem displaying this information. You can try to reload this page, or contact the site administrator and quote the error code above.',
|
|
36
|
+
)}
|
|
37
|
+
</p>{' '}
|
|
38
|
+
</Tile>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
@use '@carbon/layout';
|
|
2
|
+
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
3
|
+
@use '@carbon/colors';
|
|
4
|
+
|
|
5
|
+
.empty {
|
|
6
|
+
justify-content: center;
|
|
7
|
+
align-items: center;
|
|
8
|
+
gap: layout.$spacing-03;
|
|
9
|
+
display: flex;
|
|
10
|
+
flex: 1;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
color: $text-02;
|
|
13
|
+
height: 200px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.error {
|
|
17
|
+
justify-content: center;
|
|
18
|
+
align-items: center;
|
|
19
|
+
gap: layout.$spacing-03;
|
|
20
|
+
display: flex;
|
|
21
|
+
flex: 1;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
height: 200px;
|
|
24
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@carbon/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import AdmittedPatients from './admitted-patients';
|
|
5
|
+
import AwaitingAdmissionPatients from './awaiting-admission-patients';
|
|
6
|
+
import DischargeInPatients from './discharge-in-patients';
|
|
7
|
+
import DischargePatients from './discharge-patients';
|
|
8
|
+
|
|
9
|
+
const WardPatientsTable = () => {
|
|
10
|
+
const { t } = useTranslation();
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<Tabs onTabCloseRequest={() => {}}>
|
|
14
|
+
<TabList scrollDebounceWait={200}>
|
|
15
|
+
<Tab>{t('awaitingAdmision', 'Awaiting Admission')}</Tab>
|
|
16
|
+
<Tab>{t('admitted', 'Admitted')}</Tab>
|
|
17
|
+
<Tab>{t('dischargeIn', 'Discharge In')}</Tab>
|
|
18
|
+
<Tab>{t('discharge', 'Discharge')}</Tab>
|
|
19
|
+
</TabList>
|
|
20
|
+
<TabPanels>
|
|
21
|
+
<TabPanel>
|
|
22
|
+
<AwaitingAdmissionPatients />
|
|
23
|
+
</TabPanel>
|
|
24
|
+
<TabPanel>
|
|
25
|
+
<AdmittedPatients />
|
|
26
|
+
</TabPanel>
|
|
27
|
+
<TabPanel>
|
|
28
|
+
<DischargeInPatients />
|
|
29
|
+
</TabPanel>
|
|
30
|
+
<TabPanel>
|
|
31
|
+
<DischargePatients />
|
|
32
|
+
</TabPanel>
|
|
33
|
+
</TabPanels>
|
|
34
|
+
</Tabs>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default WardPatientsTable;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import classNames from 'classnames';
|
|
2
1
|
import React from 'react';
|
|
3
|
-
import WardPatientAge from '../../ward-patient-card/row-elements/ward-patient-age';
|
|
4
|
-
import WardPatientBedNumber from '../../ward-patient-card/row-elements/ward-patient-bed-number';
|
|
5
|
-
import WardPatientIdentifier from '../../ward-patient-card/row-elements/ward-patient-identifier';
|
|
6
|
-
import WardPatientName from '../../ward-patient-card/row-elements/ward-patient-name';
|
|
7
|
-
import WardPatientTimeOnWard from '../../ward-patient-card/row-elements/ward-patient-time-on-ward';
|
|
8
|
-
import WardPatientTimeSinceAdmission from '../../ward-patient-card/row-elements/ward-patient-time-since-admission';
|
|
9
|
-
import styles from '../../ward-patient-card/ward-patient-card.scss';
|
|
10
2
|
import { type WardPatientCardType } from '../../types';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import WardPatientAge from '../../ward-patient-card/row-elements/ward-patient-age.component';
|
|
5
|
+
import WardPatientBedNumber from '../../ward-patient-card/row-elements/ward-patient-bed-number.component';
|
|
6
|
+
import WardPatientIdentifier from '../../ward-patient-card/row-elements/ward-patient-identifier.component';
|
|
7
|
+
import WardPatientName from '../../ward-patient-card/row-elements/ward-patient-name.component';
|
|
8
|
+
import WardPatientTimeOnWard from '../../ward-patient-card/row-elements/ward-patient-time-on-ward.component';
|
|
9
|
+
import WardPatientTimeSinceAdmission from '../../ward-patient-card/row-elements/ward-patient-time-since-admission.component';
|
|
11
10
|
import WardPatientGender from '../../ward-patient-card/row-elements/ward-patient-gender.component';
|
|
11
|
+
import styles from '../../ward-patient-card/ward-patient-card.scss';
|
|
12
12
|
|
|
13
13
|
const DefaultWardPatientCardHeader: WardPatientCardType = ({ wardPatient }) => {
|
|
14
14
|
const { patient, bed, inpatientAdmission } = wardPatient;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { ErrorState, useAppContext } from '@openmrs/esm-framework';
|
|
2
1
|
import React from 'react';
|
|
2
|
+
import { ErrorState, useAppContext } from '@openmrs/esm-framework';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
|
-
import { type
|
|
4
|
+
import { type InpatientRequest, type WardViewContext } from '../../types';
|
|
5
5
|
import AdmissionRequestCard from '../../ward-workspace/admission-request-card/admission-request-card.component';
|
|
6
|
-
import WardPatientSkeletonText from '../../ward-patient-card/row-elements/ward-patient-skeleton-text';
|
|
7
6
|
import AdmissionRequestNoteRow from '../../ward-patient-card/card-rows/admission-request-note-row.component';
|
|
7
|
+
import WardPatientSkeletonText from '../../ward-patient-card/row-elements/ward-patient-skeleton-text.component';
|
|
8
8
|
|
|
9
9
|
function DefaultWardPendingPatients() {
|
|
10
10
|
const { wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
|
|
@@ -1,20 +1,41 @@
|
|
|
1
1
|
import { useDefineAppContext } from '@openmrs/esm-framework';
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useMemo } from 'react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import { useWardSummaryMetrics } from '../../hooks/useSummaryMetrics';
|
|
5
|
+
import useWardLocation from '../../hooks/useWardLocation';
|
|
3
6
|
import { useWardPatientGrouping } from '../../hooks/useWardPatientGrouping';
|
|
4
7
|
import { type WardViewContext } from '../../types';
|
|
5
|
-
import
|
|
8
|
+
import WardPatientsTable from '../../ward-patients/ward-patients-table';
|
|
9
|
+
import Filters from '../linelist-wards/Filters';
|
|
10
|
+
import Header from '../linelist-wards/Header';
|
|
11
|
+
import Metrics from '../linelist-wards/Metrics';
|
|
12
|
+
import WardViewContentWrapper from '../ward-view-content-wrapper';
|
|
6
13
|
import Ward from '../ward.component';
|
|
7
14
|
import DefaultWardBeds from './default-ward-beds.component';
|
|
15
|
+
import DefaultWardPatientCardHeader from './default-ward-patient-card-header.component';
|
|
8
16
|
import DefaultWardPendingPatients from './default-ward-pending-patients.component';
|
|
9
17
|
import DefaultWardUnassignedPatients from './default-ward-unassigned-patients.component';
|
|
10
|
-
import DefaultWardPatientCardHeader from './default-ward-patient-card-header.component';
|
|
11
18
|
|
|
12
19
|
const DefaultWardView = () => {
|
|
20
|
+
const { location } = useWardLocation();
|
|
21
|
+
const { t } = useTranslation();
|
|
13
22
|
const wardPatientGroupDetails = useWardPatientGrouping();
|
|
23
|
+
const summary = useWardSummaryMetrics();
|
|
14
24
|
useDefineAppContext<WardViewContext>('ward-view-context', {
|
|
15
25
|
wardPatientGroupDetails,
|
|
16
|
-
WardPatientHeader: DefaultWardPatientCardHeader
|
|
26
|
+
WardPatientHeader: DefaultWardPatientCardHeader,
|
|
17
27
|
});
|
|
28
|
+
const cards = useMemo(() => {
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
label: t('awaitingAdmission', 'Awaiting Admission'),
|
|
32
|
+
value: `${summary.awaitingAdmissionPatient}`,
|
|
33
|
+
},
|
|
34
|
+
{ label: t('admitted', 'Admitted'), value: `${summary.admittedPatients}` },
|
|
35
|
+
{ label: t('dischargIn', 'Discaharg In'), value: `${summary.dischargeInPatients}` },
|
|
36
|
+
{ label: t('discharge', 'Discharge'), value: `${summary.dischargedPatients}` },
|
|
37
|
+
];
|
|
38
|
+
}, [t, summary]);
|
|
18
39
|
|
|
19
40
|
const wardBeds = <DefaultWardBeds />;
|
|
20
41
|
const wardUnassignedPatients = <DefaultWardUnassignedPatients />;
|
|
@@ -22,8 +43,14 @@ const DefaultWardView = () => {
|
|
|
22
43
|
|
|
23
44
|
return (
|
|
24
45
|
<>
|
|
25
|
-
<
|
|
26
|
-
<
|
|
46
|
+
<Header title={location.display} />
|
|
47
|
+
<Filters />
|
|
48
|
+
<Metrics metrics={cards} />
|
|
49
|
+
{/* <WardViewHeader {...{ wardPendingPatients }} /> */}
|
|
50
|
+
<WardViewContentWrapper
|
|
51
|
+
cardView={<Ward {...{ wardBeds, wardUnassignedPatients }} />}
|
|
52
|
+
tableView={<WardPatientsTable />}
|
|
53
|
+
/>
|
|
27
54
|
</>
|
|
28
55
|
);
|
|
29
56
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styles from './linelist-wards.scss';
|
|
3
|
+
import { DatePicker, DatePickerInput } from '@carbon/react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
const Filters = () => {
|
|
6
|
+
const { t } = useTranslation();
|
|
7
|
+
return (
|
|
8
|
+
<div className={styles.filtersContainer}>
|
|
9
|
+
<div>
|
|
10
|
+
<DatePicker datePickerType="single" onChange={() => {}} onClose={() => {}} onOpen={() => {}}>
|
|
11
|
+
<DatePickerInput
|
|
12
|
+
id="date-picker-single"
|
|
13
|
+
labelText={t('date', 'Date')}
|
|
14
|
+
onChange={() => {}}
|
|
15
|
+
onClose={() => {}}
|
|
16
|
+
onOpen={() => {}}
|
|
17
|
+
placeholder="mm/dd/yyyy"
|
|
18
|
+
/>
|
|
19
|
+
</DatePicker>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default Filters;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Calendar, Location, LocationCompany, UserFollow } from '@carbon/react/icons';
|
|
2
|
+
import { formatDate, HomePictogram, useSession } from '@openmrs/esm-framework';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import styles from './linelist-wards.scss';
|
|
6
|
+
|
|
7
|
+
interface HeaderProps {
|
|
8
|
+
title: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const Header: React.FC<HeaderProps> = ({ title }) => {
|
|
12
|
+
const { t } = useTranslation();
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div className={styles.header} id="admin-header">
|
|
16
|
+
<div className={styles.leftJustifiedItems}>
|
|
17
|
+
<HomePictogram className={styles.icon} />
|
|
18
|
+
<div className={styles.pageLabels}>
|
|
19
|
+
<p>{t('locations', 'Locations')}</p>
|
|
20
|
+
<p className={styles.pageName}>{title}</p>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default Header;
|