@kenyaemr/esm-express-workflow-app 5.4.3 → 5.4.4-pre.100
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 +7 -12
- package/dist/1074.js +1 -0
- package/dist/1074.js.map +1 -0
- package/dist/12.js +17 -0
- package/dist/12.js.map +1 -0
- package/dist/1311.js +1 -0
- package/dist/1311.js.map +1 -0
- package/dist/1323.js +1 -0
- package/dist/1323.js.map +1 -0
- package/dist/1469.js +1 -0
- package/dist/1469.js.map +1 -0
- package/dist/1506.js +13 -0
- package/dist/1506.js.map +1 -0
- package/dist/1562.js +1 -0
- package/dist/1562.js.map +1 -0
- package/dist/1760.js +1 -0
- package/dist/1760.js.map +1 -0
- package/dist/1780.js +1 -0
- package/dist/1780.js.map +1 -0
- package/dist/1804.js +1 -0
- package/dist/1804.js.map +1 -0
- package/dist/1884.js +1 -0
- package/dist/1884.js.map +1 -0
- package/dist/1972.js +1 -0
- package/dist/1972.js.map +1 -0
- package/dist/1990.js +1 -0
- package/dist/1990.js.map +1 -0
- package/dist/2016.js +1 -0
- package/dist/2016.js.map +1 -0
- package/dist/2024.js +1 -0
- package/dist/2024.js.map +1 -0
- package/dist/2153.js +1 -0
- package/dist/2153.js.map +1 -0
- package/dist/216.js +1 -0
- package/dist/216.js.map +1 -0
- package/dist/2225.js +1 -0
- package/dist/2225.js.map +1 -0
- package/dist/2294.js +1 -0
- package/dist/2294.js.map +1 -0
- package/dist/2345.js +1 -0
- package/dist/2345.js.map +1 -0
- package/dist/2499.js +1 -0
- package/dist/2499.js.map +1 -0
- package/dist/2500.js +1 -0
- package/dist/2500.js.map +1 -0
- package/dist/2586.js +1 -0
- package/dist/2586.js.map +1 -0
- package/dist/2625.js +1 -0
- package/dist/2625.js.map +1 -0
- package/dist/2685.js +1 -0
- package/dist/2685.js.map +1 -0
- package/dist/2809.js +1 -0
- package/dist/2809.js.map +1 -0
- package/dist/2851.js +1 -0
- package/dist/2851.js.map +1 -0
- package/dist/2881.js +1 -0
- package/dist/2881.js.map +1 -0
- package/dist/2948.js +1 -0
- package/dist/2948.js.map +1 -0
- package/dist/2968.js +1 -0
- package/dist/2968.js.map +1 -0
- package/dist/2978.js +1 -0
- package/dist/2978.js.map +1 -0
- package/dist/2998.js +1 -0
- package/dist/2998.js.map +1 -0
- package/dist/3089.js +1 -0
- package/dist/3089.js.map +1 -0
- package/dist/3548.js +1 -0
- package/dist/3548.js.map +1 -0
- package/dist/3567.js +1 -0
- package/dist/3567.js.map +1 -0
- package/dist/3569.js +1 -0
- package/dist/3569.js.map +1 -0
- package/dist/3571.js +1 -0
- package/dist/3571.js.map +1 -0
- package/dist/3691.js +1 -0
- package/dist/3691.js.map +1 -0
- package/dist/3730.js +1 -0
- package/dist/3730.js.map +1 -0
- package/dist/3923.js +1 -0
- package/dist/3923.js.map +1 -0
- package/dist/3963.js +1 -0
- package/dist/3963.js.map +1 -0
- package/dist/4024.js +1 -0
- package/dist/4024.js.map +1 -0
- package/dist/405.js +1 -0
- package/dist/405.js.map +1 -0
- package/dist/4071.js +1 -0
- package/dist/4071.js.map +1 -0
- package/dist/4271.js +1 -0
- package/dist/4271.js.map +1 -0
- package/dist/4296.js +1 -0
- package/dist/4296.js.map +1 -0
- package/dist/4337.js +1 -0
- package/dist/4337.js.map +1 -0
- package/dist/4432.js +1 -0
- package/dist/4432.js.map +1 -0
- package/dist/4581.js +1 -0
- package/dist/4581.js.map +1 -0
- package/dist/4637.js +11 -0
- package/dist/4637.js.map +1 -0
- package/dist/4666.js +1 -0
- package/dist/4666.js.map +1 -0
- package/dist/4680.js +1 -0
- package/dist/4680.js.map +1 -0
- package/dist/4735.js +1 -0
- package/dist/4735.js.map +1 -0
- package/dist/4737.js +1 -0
- package/dist/4737.js.map +1 -0
- package/dist/4744.js +1 -0
- package/dist/4744.js.map +1 -0
- package/dist/4795.js +1 -0
- package/dist/4795.js.map +1 -0
- package/dist/4813.js +2 -0
- package/dist/4813.js.map +1 -0
- package/dist/4818.js +1 -0
- package/dist/4818.js.map +1 -0
- package/dist/4858.js +1 -0
- package/dist/4858.js.map +1 -0
- package/dist/487.js +1 -0
- package/dist/487.js.map +1 -0
- package/dist/4970.js +1 -0
- package/dist/4970.js.map +1 -0
- package/dist/5038.js +1 -0
- package/dist/5038.js.map +1 -0
- package/dist/5202.js +1 -0
- package/dist/5202.js.map +1 -0
- package/dist/5491.js +1 -0
- package/dist/5491.js.map +1 -0
- package/dist/5592.js +1 -0
- package/dist/5592.js.map +1 -0
- package/dist/5669.js +1 -0
- package/dist/5669.js.map +1 -0
- package/dist/586.js +1 -0
- package/dist/586.js.map +1 -0
- package/dist/5932.js +1 -0
- package/dist/5932.js.map +1 -0
- package/dist/5995.js +1 -0
- package/dist/5995.js.map +1 -0
- package/dist/6258.js +1 -0
- package/dist/6258.js.map +1 -0
- package/dist/629.js +1 -0
- package/dist/629.js.map +1 -0
- package/dist/6328.js +1 -0
- package/dist/6328.js.map +1 -0
- package/dist/6355.js +1 -0
- package/dist/6355.js.map +1 -0
- package/dist/6419.js +1 -0
- package/dist/6419.js.map +1 -0
- package/dist/644.js +1 -0
- package/dist/644.js.map +1 -0
- package/dist/6456.js +1 -0
- package/dist/6466.js +3 -0
- package/dist/6466.js.map +1 -0
- package/dist/655.js +1 -0
- package/dist/655.js.map +1 -0
- package/dist/6798.js +66 -0
- package/dist/6798.js.map +1 -0
- package/dist/6910.js +1 -0
- package/dist/6910.js.map +1 -0
- package/dist/6925.js +1 -0
- package/dist/6925.js.map +1 -0
- package/dist/70.js +1 -0
- package/dist/70.js.map +1 -0
- package/dist/7201.js +1 -0
- package/dist/7201.js.map +1 -0
- package/dist/7234.js +1 -0
- package/dist/7234.js.map +1 -0
- package/dist/7261.js +1 -0
- package/dist/7261.js.map +1 -0
- package/dist/7326.js +1 -0
- package/dist/7359.js +1 -0
- package/dist/7487.js +1 -0
- package/dist/7487.js.map +1 -0
- package/dist/7591.js +1 -0
- package/dist/7591.js.map +1 -0
- package/dist/7607.js +1 -0
- package/dist/7701.js +1 -0
- package/dist/7701.js.map +1 -0
- package/dist/7717.js +1 -0
- package/dist/7717.js.map +1 -0
- package/dist/7739.js +1 -0
- package/dist/7739.js.map +1 -0
- package/dist/7788.js +1 -0
- package/dist/7788.js.map +1 -0
- package/dist/7819.js +1 -0
- package/dist/7819.js.map +1 -0
- package/dist/7971.js +1 -0
- package/dist/7971.js.map +1 -0
- package/dist/7983.js +1 -0
- package/dist/7983.js.map +1 -0
- package/dist/807.js +1 -0
- package/dist/807.js.map +1 -0
- package/dist/8159.js +7 -0
- package/dist/8159.js.map +1 -0
- package/dist/8338.js +1 -0
- package/dist/8338.js.map +1 -0
- package/dist/845.js +1 -0
- package/dist/845.js.map +1 -0
- package/dist/8570.js +1 -0
- package/dist/8570.js.map +1 -0
- package/dist/8661.js +1 -0
- package/dist/8661.js.map +1 -0
- package/dist/87.js +1 -0
- package/dist/87.js.map +1 -0
- package/dist/8727.js +1 -0
- package/dist/8766.js +1 -0
- package/dist/8766.js.map +1 -0
- package/dist/8828.js +1 -0
- package/dist/8828.js.map +1 -0
- package/dist/8860.js +1 -0
- package/dist/8860.js.map +1 -0
- package/dist/8911.js +1 -0
- package/dist/8911.js.map +1 -0
- package/dist/8930.js +1 -0
- package/dist/8930.js.map +1 -0
- package/dist/8971.js +1 -0
- package/dist/8971.js.map +1 -0
- package/dist/9124.js +1 -0
- package/dist/9124.js.map +1 -0
- package/dist/9157.js +1 -0
- package/dist/9157.js.map +1 -0
- package/dist/9182.js +1 -0
- package/dist/921.js +1 -0
- package/dist/921.js.map +1 -0
- package/dist/9212.js +1 -0
- package/dist/9212.js.map +1 -0
- package/dist/9255.js +1 -0
- package/dist/9255.js.map +1 -0
- package/dist/9257.js +1 -0
- package/dist/9257.js.map +1 -0
- package/dist/9316.js +1 -0
- package/dist/9316.js.map +1 -0
- package/dist/9333.js +1 -0
- package/dist/9333.js.map +1 -0
- package/dist/9404.js +1 -0
- package/dist/9404.js.map +1 -0
- package/dist/9446.js +1 -0
- package/dist/9446.js.map +1 -0
- package/dist/9447.js +1 -0
- package/dist/9447.js.map +1 -0
- package/dist/9449.js +1 -0
- package/dist/9449.js.map +1 -0
- package/dist/9535.js +1 -0
- package/dist/9535.js.map +1 -0
- package/dist/9606.js +1 -0
- package/dist/9606.js.map +1 -0
- package/dist/973.js +1 -0
- package/dist/973.js.map +1 -0
- package/dist/9845.js +1 -0
- package/dist/9845.js.map +1 -0
- package/dist/kenyaemr-esm-express-workflow-app.js +5 -5
- package/dist/kenyaemr-esm-express-workflow-app.js.buildmanifest.json +3004 -175
- package/dist/kenyaemr-esm-express-workflow-app.js.map +1 -1
- package/dist/main.js +5 -114
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +6 -7
- package/rspack.config.js +1 -1
- package/src/components/accounting/index.tsx +11 -10
- package/src/components/admissions/index.tsx +11 -10
- package/src/components/appointments/index.ts +10 -8
- package/src/components/consultation/clinical-encounter/encounter-details.component.tsx +9 -9
- package/src/components/consultation/clinical-encounter/encounter-details.test.tsx +19 -18
- package/src/components/consultation/consultation-context.tsx +19 -0
- package/src/components/consultation/consultation-summary-cards.component.tsx +124 -0
- package/src/components/consultation/consultation.component.tsx +41 -268
- package/src/components/consultation/consultation.resource.ts +67 -24
- package/src/components/consultation/consultation.scss +5 -0
- package/src/components/consultation/consultation.utils.tsx +222 -0
- package/src/components/consultation/dashboard.component.tsx +0 -2
- package/src/components/consultation/index.ts +27 -20
- package/src/components/facility-dashboard/index.tsx +10 -9
- package/src/components/laboratory/index.ts +11 -10
- package/src/components/laboratory/lab-table.component.tsx +22 -8
- package/src/components/laboratory/laboratory-tabs.component.tsx +2 -2
- package/src/components/mch/dashboard.component.tsx +0 -2
- package/src/components/mch/index.tsx +10 -9
- package/src/components/mch/mch.consultation.component.tsx +27 -15
- package/src/components/mch/mch.triage.component.tsx +42 -33
- package/src/components/pharmacy/index.ts +20 -18
- package/src/components/pharmacy/orders/pharmacy-orders.component.tsx +35 -13
- package/src/components/pharmacy/orders/pharmacy-orders.test.tsx +8 -7
- package/src/components/procedures/index.ts +11 -10
- package/src/components/procedures/procedures-table.component.tsx +44 -13
- package/src/components/procedures/procedures-tabs.component.tsx +2 -2
- package/src/components/radiology-and-imaging/index.ts +14 -10
- package/src/components/radiology-and-imaging/radiology-and-imaging-table.component.tsx +35 -15
- package/src/components/radiology-and-imaging/radiology-and-imaging.component.tsx +2 -2
- package/src/components/registration/card/HIE-card/hie-card.component.tsx +32 -44
- package/src/components/registration/card/Local-card/local-card.component.tsx +22 -24
- package/src/components/registration/dependants/dependants.component.tsx +32 -60
- package/src/components/registration/dependants/dependants.resource.ts +79 -50
- package/src/components/registration/helper/index.ts +4 -0
- package/src/components/registration/index.ts +10 -9
- package/src/components/registration/search-bar/search-bar.resource.ts +32 -93
- package/src/components/registration/start-visit-form/hooks/useDefaultFacilityLocation.tsx +15 -0
- package/src/components/registration/start-visit-form/hooks/useDefaultVisitLocation.tsx +24 -0
- package/src/components/registration/start-visit-form/hooks/useOfflineVisitType.tsx +18 -0
- package/src/components/registration/start-visit-form/hooks/useRecommendedVisitTypes.tsx +36 -0
- package/src/components/registration/start-visit-form/hooks/useVisitAttributeType.tsx +102 -0
- package/src/components/registration/start-visit-form/overflow-menu-extension/overflow-menu-item.extension.tsx +55 -0
- package/src/components/registration/start-visit-form/overflow-menu-extension/overflow-menu-item.scss +3 -0
- package/src/components/registration/start-visit-form/start-visit-workspace/base-visit-type.component.tsx +126 -0
- package/src/components/registration/start-visit-form/start-visit-workspace/base-visit-type.scss +75 -0
- package/src/components/registration/start-visit-form/start-visit-workspace/exported-visit-form.workspace.tsx +743 -0
- package/src/components/registration/start-visit-form/start-visit-workspace/location-selector.component.tsx +86 -0
- package/src/components/registration/start-visit-form/start-visit-workspace/recommended-visit-type.component.tsx +32 -0
- package/src/components/registration/start-visit-form/start-visit-workspace/visit-attribute-type.component.tsx +257 -0
- package/src/components/registration/start-visit-form/start-visit-workspace/visit-attribute-type.scss +5 -0
- package/src/components/registration/start-visit-form/start-visit-workspace/visit-date-time.component.tsx +193 -0
- package/src/components/registration/start-visit-form/start-visit-workspace/visit-form.resource.ts +383 -0
- package/src/components/registration/start-visit-form/start-visit-workspace/visit-form.scss +166 -0
- package/src/components/registration/start-visit-form/visit-form-workspace/visit-form.workspace.tsx +55 -0
- package/src/components/reports/index.ts +10 -9
- package/src/components/triage/dashboard.component.tsx +0 -2
- package/src/components/triage/index.ts +10 -9
- package/src/components/triage/triage.component.tsx +92 -42
- package/src/components/triage/triage.resource.ts +56 -50
- package/src/components/triage/triage.scss +6 -0
- package/src/config-schema.ts +91 -0
- package/src/hooks/useServiceQueues.tsx +95 -25
- package/src/index.ts +32 -13
- package/src/routes.json +53 -254
- package/src/shared/orders/OrdersTabs.tsx +8 -3
- package/src/shared/patient-chart/patient-chart.resources.ts +8 -12
- package/src/shared/patient-chart/patient-summary-dashboard/patient-summary-dashboard.component.tsx +1 -2
- package/src/shared/pin-put/pinput.component.test.tsx +7 -6
- package/src/shared/queue/queue-entry/queue-entry-table.component.tsx +99 -88
- package/src/shared/queue/queue-entry/queue-entry-table.scss +4 -0
- package/src/shared/queue/queue-summary-cards.component.tsx +32 -0
- package/src/shared/queue/queue-tab.component.tsx +182 -70
- package/src/shared/queue/queue-tab.scss +1 -0
- package/src/shared/queue/queue-workflow-context.tsx +90 -0
- package/src/shared/tabs/extension-tabs.component.tsx +9 -6
- package/src/shared/utils/index.ts +1 -2
- package/src/types/index.ts +17 -2
- package/translations/am.json +64 -13
- package/translations/en.json +59 -8
- package/translations/sw.json +58 -7
- package/dist/127.js +0 -1
- package/dist/200.js +0 -1
- package/dist/200.js.map +0 -1
- package/dist/24.js +0 -1
- package/dist/24.js.map +0 -1
- package/dist/267.js +0 -1
- package/dist/267.js.map +0 -1
- package/dist/285.js +0 -1
- package/dist/285.js.map +0 -1
- package/dist/329.js +0 -1
- package/dist/329.js.map +0 -1
- package/dist/40.js +0 -1
- package/dist/466.js +0 -1
- package/dist/466.js.map +0 -1
- package/dist/472.js +0 -66
- package/dist/472.js.map +0 -1
- package/dist/490.js +0 -1
- package/dist/490.js.map +0 -1
- package/dist/54.js +0 -1
- package/dist/54.js.map +0 -1
- package/dist/689.js +0 -1
- package/dist/689.js.map +0 -1
- package/dist/697.js +0 -1
- package/dist/697.js.map +0 -1
- package/dist/704.js +0 -1
- package/dist/704.js.map +0 -1
- package/dist/710.js +0 -1
- package/dist/710.js.map +0 -1
- package/dist/729.js +0 -17
- package/dist/729.js.map +0 -1
- package/dist/805.js +0 -37
- package/dist/805.js.map +0 -1
- package/dist/847.js +0 -1
- package/dist/847.js.map +0 -1
- package/dist/85.js +0 -1
- package/dist/85.js.map +0 -1
- package/dist/882.js +0 -1
- package/dist/91.js +0 -1
- package/dist/91.js.map +0 -1
- package/dist/916.js +0 -1
- package/dist/994.js +0 -1
- package/dist/994.js.map +0 -1
- package/dist/998.js +0 -1
- package/dist/998.js.map +0 -1
- package/jest.config.js +0 -3
- package/src/shared/patient-chart/patient-chart.component.tsx +0 -61
- package/src/shared/patient-chart/patient-chart.scss +0 -15
- package/src/shared/patient-chart/useInitialize.ts +0 -24
|
@@ -7,13 +7,21 @@ import styles from '../card.scss';
|
|
|
7
7
|
import DependentsComponent from '../../dependants/dependants.component';
|
|
8
8
|
import { LocalResponse, type HIEBundleResponse, type EligibilityResponse } from '../../type';
|
|
9
9
|
import { hasDependents } from '../../helper';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
launchWorkspace2,
|
|
12
|
+
launchWorkspaceGroup2,
|
|
13
|
+
PatientPhoto,
|
|
14
|
+
showModal,
|
|
15
|
+
navigate,
|
|
16
|
+
type Visit,
|
|
17
|
+
} from '@openmrs/esm-framework';
|
|
11
18
|
import { EnhancedPatientBannerPatientInfo } from '../../patient-banner/patient-banner.component';
|
|
12
19
|
import { findExistingLocalPatient, registerOrLaunchHIEPatient } from '../../search-bar/search-bar.resource';
|
|
13
20
|
import { launchOtpVerificationModal } from '../../../../shared/otp-verification';
|
|
14
21
|
import { otpManager, useOtpSource, cleanupAllOTPs } from './hie-card.resource';
|
|
15
22
|
import { useMultipleActiveVisits } from '../../dependants/dependants.resource';
|
|
16
23
|
import { sanitizePhoneNumber } from '../../../../shared/utils';
|
|
24
|
+
import { VisitFormProps } from '../../start-visit-form/visit-form-workspace/visit-form.workspace';
|
|
17
25
|
|
|
18
26
|
interface HIEDisplayCardProps {
|
|
19
27
|
bundle: HIEBundleResponse;
|
|
@@ -140,6 +148,25 @@ const HIEDisplayCard: React.FC<HIEDisplayCardProps> = ({
|
|
|
140
148
|
return '254700000000';
|
|
141
149
|
};
|
|
142
150
|
|
|
151
|
+
const launchCheckInWorkspace = async (patient: any, patientUuid: string) => {
|
|
152
|
+
await launchWorkspaceGroup2('ewf-patient-chart', {
|
|
153
|
+
patient,
|
|
154
|
+
patientUuid,
|
|
155
|
+
visitContext: null as unknown as Visit,
|
|
156
|
+
mutateVisitContext: () => {},
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
launchWorkspace2<VisitFormProps, {}, {}>(
|
|
160
|
+
'custom-start-visit-workspace-form',
|
|
161
|
+
{
|
|
162
|
+
openedFrom: 'registration-check-in',
|
|
163
|
+
showPatientHeader: false,
|
|
164
|
+
},
|
|
165
|
+
{},
|
|
166
|
+
null,
|
|
167
|
+
);
|
|
168
|
+
};
|
|
169
|
+
|
|
143
170
|
const handleOTPRequest = (patientUuid: string) => {
|
|
144
171
|
setOtpRequestedFor((prev) => new Set(prev).add(patientUuid));
|
|
145
172
|
};
|
|
@@ -170,9 +197,7 @@ const HIEDisplayCard: React.FC<HIEDisplayCardProps> = ({
|
|
|
170
197
|
if (!otpSource) {
|
|
171
198
|
throw new Error('OTP source not configured. Please contact your administrator.');
|
|
172
199
|
}
|
|
173
|
-
|
|
174
200
|
otpManager.setOtpSource(otpSource);
|
|
175
|
-
|
|
176
201
|
await otpManager.requestOTP(sanitizedPhone, patientName, otpExpiryMinutes, searchedNationalId, patientUuid);
|
|
177
202
|
} catch (error) {
|
|
178
203
|
throw error;
|
|
@@ -184,9 +209,7 @@ const HIEDisplayCard: React.FC<HIEDisplayCardProps> = ({
|
|
|
184
209
|
if (!otpSource) {
|
|
185
210
|
throw new Error('OTP source not configured. Please contact your administrator.');
|
|
186
211
|
}
|
|
187
|
-
|
|
188
212
|
otpManager.setOtpSource(otpSource);
|
|
189
|
-
|
|
190
213
|
const isValid = await otpManager.verifyOTP(sanitizedPhone, otp, patientUuid);
|
|
191
214
|
if (!isValid) {
|
|
192
215
|
throw new Error('OTP verification failed');
|
|
@@ -312,21 +335,7 @@ const HIEDisplayCard: React.FC<HIEDisplayCardProps> = ({
|
|
|
312
335
|
<Button
|
|
313
336
|
kind="secondary"
|
|
314
337
|
size="sm"
|
|
315
|
-
onClick={() =>
|
|
316
|
-
const localPatientName =
|
|
317
|
-
localPatient?.person?.personName?.display ||
|
|
318
|
-
`${localPatient?.person?.personName?.givenName || ''} ${
|
|
319
|
-
localPatient?.person?.personName?.middleName || ''
|
|
320
|
-
} ${localPatient?.person?.personName?.familyName || ''}`.trim() ||
|
|
321
|
-
patientName;
|
|
322
|
-
|
|
323
|
-
launchWorkspace('start-visit-workspace-form', {
|
|
324
|
-
patientUuid: localPatient.uuid,
|
|
325
|
-
workspaceTitle: t('startVisitWorkspaceTitle', 'Start Visit for {{patientName}}', {
|
|
326
|
-
patientName: localPatientName,
|
|
327
|
-
}),
|
|
328
|
-
});
|
|
329
|
-
}}>
|
|
338
|
+
onClick={() => launchCheckInWorkspace(localPatient, localPatient.uuid)}>
|
|
330
339
|
{t('checkIn', 'Check In')}
|
|
331
340
|
</Button>
|
|
332
341
|
)}
|
|
@@ -345,27 +354,8 @@ const HIEDisplayCard: React.FC<HIEDisplayCardProps> = ({
|
|
|
345
354
|
kind="secondary"
|
|
346
355
|
size="sm"
|
|
347
356
|
onClick={async () => {
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
patientUuid: localPatient.uuid,
|
|
351
|
-
workspaceTitle: t('checkInPatientWorkspaceTitle', 'Check in patient'),
|
|
352
|
-
closeWorkspace: () => {
|
|
353
|
-
closeWorkspace('start-visit-workspace-form', {
|
|
354
|
-
onWorkspaceClose: () => {
|
|
355
|
-
navigate({ to: `\${openmrsSpaBase}/patient/${localPatient.uuid}/chart` });
|
|
356
|
-
},
|
|
357
|
-
ignoreChanges: true,
|
|
358
|
-
});
|
|
359
|
-
},
|
|
360
|
-
closeWorkspaceWithSavedChanges: () => {
|
|
361
|
-
closeWorkspace('start-visit-workspace-form', {
|
|
362
|
-
onWorkspaceClose: () => {
|
|
363
|
-
navigate({ to: `\${openmrsSpaBase}/patient/${localPatient.uuid}/chart` });
|
|
364
|
-
},
|
|
365
|
-
ignoreChanges: true,
|
|
366
|
-
});
|
|
367
|
-
},
|
|
368
|
-
});
|
|
357
|
+
const registeredPatient = await registerOrLaunchHIEPatient(patient, t);
|
|
358
|
+
await launchCheckInWorkspace(registeredPatient, registeredPatient.uuid);
|
|
369
359
|
}}>
|
|
370
360
|
{t('checkIn', 'Check In')}
|
|
371
361
|
</Button>
|
|
@@ -376,9 +366,7 @@ const HIEDisplayCard: React.FC<HIEDisplayCardProps> = ({
|
|
|
376
366
|
iconDescription={showDependents ? 'Hide dependents' : 'Show dependents'}
|
|
377
367
|
kind="tertiary"
|
|
378
368
|
size="sm"
|
|
379
|
-
onClick={() =>
|
|
380
|
-
toggleDependentsVisibility(patientKey);
|
|
381
|
-
}}
|
|
369
|
+
onClick={() => toggleDependentsVisibility(patientKey)}
|
|
382
370
|
renderIcon={showDependents ? ChevronUp : ChevronDown}>
|
|
383
371
|
{showDependents
|
|
384
372
|
? t('hideDependents', 'Hide dependents')
|
|
@@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
5
5
|
import classNames from 'classnames';
|
|
6
6
|
import styles from '../card.scss';
|
|
7
7
|
import { LocalResponse, type HIEBundleResponse, type EligibilityResponse } from '../../type';
|
|
8
|
-
import {
|
|
8
|
+
import { launchWorkspace2, launchWorkspaceGroup2, PatientPhoto, showModal, type Visit } from '@openmrs/esm-framework';
|
|
9
9
|
import { EnhancedPatientBannerPatientInfo } from '../../patient-banner/patient-banner.component';
|
|
10
10
|
import { convertLocalPatientToFHIR, getNationalIdFromPatient, hasDependents } from '../../helper';
|
|
11
11
|
import { launchOtpVerificationModal } from '../../../../shared/otp-verification';
|
|
@@ -13,6 +13,7 @@ import DependentsComponent from '../../dependants/dependants.component';
|
|
|
13
13
|
import { useMultipleActiveVisits } from '../../dependants/dependants.resource';
|
|
14
14
|
import { otpManager, useOtpSource, cleanupAllOTPs } from '../HIE-card/hie-card.resource';
|
|
15
15
|
import { sanitizePhoneNumber } from '../../../../shared/utils';
|
|
16
|
+
import { VisitFormProps } from '../../start-visit-form/visit-form-workspace/visit-form.workspace';
|
|
16
17
|
|
|
17
18
|
interface LocalPatientCardProps {
|
|
18
19
|
localSearchResults: LocalResponse;
|
|
@@ -46,7 +47,6 @@ const LocalPatientCard: React.FC<LocalPatientCardProps> = ({
|
|
|
46
47
|
}
|
|
47
48
|
}, [otpSource]);
|
|
48
49
|
|
|
49
|
-
// Clean up OTPs when component unmounts
|
|
50
50
|
useEffect(() => {
|
|
51
51
|
return () => {
|
|
52
52
|
cleanupAllOTPs();
|
|
@@ -114,6 +114,25 @@ const LocalPatientCard: React.FC<LocalPatientCardProps> = ({
|
|
|
114
114
|
return '254700000000';
|
|
115
115
|
}, []);
|
|
116
116
|
|
|
117
|
+
const launchCheckInWorkspace = async (patient: any, patientUuid: string) => {
|
|
118
|
+
await launchWorkspaceGroup2('ewf-patient-chart', {
|
|
119
|
+
patient,
|
|
120
|
+
patientUuid,
|
|
121
|
+
visitContext: null as unknown as Visit,
|
|
122
|
+
mutateVisitContext: () => {},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
launchWorkspace2<VisitFormProps, {}, {}>(
|
|
126
|
+
'custom-start-visit-workspace-form',
|
|
127
|
+
{
|
|
128
|
+
openedFrom: 'registration-check-in',
|
|
129
|
+
showPatientHeader: false,
|
|
130
|
+
},
|
|
131
|
+
{},
|
|
132
|
+
null,
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
|
|
117
136
|
const handleOTPRequest = useCallback((patientUuid: string) => {
|
|
118
137
|
setOtpRequestedFor((prev) => new Set(prev).add(patientUuid));
|
|
119
138
|
}, []);
|
|
@@ -141,9 +160,7 @@ const LocalPatientCard: React.FC<LocalPatientCardProps> = ({
|
|
|
141
160
|
if (!otpSource) {
|
|
142
161
|
throw new Error('OTP source not configured. Please contact your administrator.');
|
|
143
162
|
}
|
|
144
|
-
|
|
145
163
|
otpManager.setOtpSource(otpSource);
|
|
146
|
-
|
|
147
164
|
await otpManager.requestOTP(sanitizedPhone, patientName, otpExpiryMinutes, searchedNationalId, patientUuid);
|
|
148
165
|
} catch (error) {
|
|
149
166
|
throw error;
|
|
@@ -155,9 +172,7 @@ const LocalPatientCard: React.FC<LocalPatientCardProps> = ({
|
|
|
155
172
|
if (!otpSource) {
|
|
156
173
|
throw new Error('OTP source not configured. Please contact your administrator.');
|
|
157
174
|
}
|
|
158
|
-
|
|
159
175
|
otpManager.setOtpSource(otpSource);
|
|
160
|
-
|
|
161
176
|
const isValid = await otpManager.verifyOTP(sanitizedPhone, otp, patientUuid);
|
|
162
177
|
if (!isValid) {
|
|
163
178
|
throw new Error('OTP verification failed');
|
|
@@ -207,7 +222,6 @@ const LocalPatientCard: React.FC<LocalPatientCardProps> = ({
|
|
|
207
222
|
const hasActiveVisit = !!activeVisit;
|
|
208
223
|
|
|
209
224
|
const hiePatientData: any = findHIEPatientData(localPatient);
|
|
210
|
-
|
|
211
225
|
const patientHasDependents: boolean = hiePatientData ? hasDependents(hiePatientData) : false;
|
|
212
226
|
const showDependents: boolean = showDependentsForPatient.has(patientUuid);
|
|
213
227
|
|
|
@@ -230,7 +244,6 @@ const LocalPatientCard: React.FC<LocalPatientCardProps> = ({
|
|
|
230
244
|
<div className={styles.patientAvatar} role="img">
|
|
231
245
|
<PatientPhoto patientUuid={patientUuid} patientName={patientName} />
|
|
232
246
|
</div>
|
|
233
|
-
|
|
234
247
|
<EnhancedPatientBannerPatientInfo
|
|
235
248
|
patient={fhirPatient}
|
|
236
249
|
renderedFrom="local-search"
|
|
@@ -291,22 +304,7 @@ const LocalPatientCard: React.FC<LocalPatientCardProps> = ({
|
|
|
291
304
|
<Button
|
|
292
305
|
kind="primary"
|
|
293
306
|
size="sm"
|
|
294
|
-
onClick={() =>
|
|
295
|
-
launchWorkspace('start-visit-workspace-form', {
|
|
296
|
-
patientUuid: patientUuid,
|
|
297
|
-
workspaceTitle: t('checkInPatientWorkspaceTitle', 'Check in patient'),
|
|
298
|
-
closeWorkspace: () => {
|
|
299
|
-
closeWorkspace('start-visit-workspace-form', {
|
|
300
|
-
ignoreChanges: true,
|
|
301
|
-
});
|
|
302
|
-
},
|
|
303
|
-
closeWorkspaceWithSavedChanges: () => {
|
|
304
|
-
closeWorkspace('start-visit-workspace-form', {
|
|
305
|
-
ignoreChanges: true,
|
|
306
|
-
});
|
|
307
|
-
},
|
|
308
|
-
});
|
|
309
|
-
}}>
|
|
307
|
+
onClick={() => launchCheckInWorkspace(localPatient, patientUuid)}>
|
|
310
308
|
{t('checkIn', 'Check In')}
|
|
311
309
|
</Button>
|
|
312
310
|
)}
|
|
@@ -2,16 +2,17 @@ import React, { useState, useEffect, useMemo, useCallback } from 'react';
|
|
|
2
2
|
import { DataTable, Table, TableHead, TableBody, TableRow, TableCell, TableHeader, Button, Tag } from '@carbon/react';
|
|
3
3
|
import { TwoFactorAuthentication } from '@carbon/react/icons';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
|
-
import {
|
|
5
|
+
import { launchWorkspace2, launchWorkspaceGroup2, showSnackbar, showModal, type Visit } from '@openmrs/esm-framework';
|
|
6
6
|
import capitalize from 'lodash/capitalize';
|
|
7
7
|
import styles from './dependants.scss';
|
|
8
8
|
import { maskName } from '../helper';
|
|
9
9
|
import { findExistingLocalPatient, registerOrLaunchDependent } from '../search-bar/search-bar.resource';
|
|
10
10
|
import { getDependentsFromContacts, useMultipleActiveVisits } from './dependants.resource';
|
|
11
|
-
import { DependentWithPhone,
|
|
11
|
+
import { DependentWithPhone, HIEPatient } from '../type';
|
|
12
12
|
import { otpManager, useOtpSource, cleanupAllOTPs } from '../card/HIE-card/hie-card.resource';
|
|
13
13
|
import { launchOtpVerificationModal } from '../../../shared/otp-verification';
|
|
14
14
|
import { sanitizePhoneNumber } from '../../../shared/utils';
|
|
15
|
+
import { VisitFormProps } from '../start-visit-form/visit-form-workspace/visit-form.workspace';
|
|
15
16
|
|
|
16
17
|
type DependentProps = {
|
|
17
18
|
patient: HIEPatient;
|
|
@@ -28,12 +29,11 @@ const DependentsComponent: React.FC<DependentProps> = ({
|
|
|
28
29
|
const [submittingStates, setSubmittingStates] = useState<Record<string, boolean>>({});
|
|
29
30
|
const [loadingStates, setLoadingStates] = useState<Record<string, boolean>>({});
|
|
30
31
|
const [localPatientCache, setLocalPatientCache] = useState<Map<string, any>>(new Map());
|
|
31
|
-
|
|
32
32
|
const [verifiedSpouses, setVerifiedSpouses] = useState<Set<string>>(new Set());
|
|
33
33
|
const [otpRequestedForSpouse, setOtpRequestedForSpouse] = useState<Set<string>>(new Set());
|
|
34
34
|
const [activePhoneNumbers, setActivePhoneNumbers] = useState<Map<string, string>>(new Map());
|
|
35
35
|
|
|
36
|
-
const { otpSource, isLoading: isLoadingOtpSource
|
|
36
|
+
const { otpSource, isLoading: isLoadingOtpSource } = useOtpSource();
|
|
37
37
|
|
|
38
38
|
useEffect(() => {
|
|
39
39
|
if (otpSource) {
|
|
@@ -74,7 +74,7 @@ const DependentsComponent: React.FC<DependentProps> = ({
|
|
|
74
74
|
}, []);
|
|
75
75
|
|
|
76
76
|
const getDependentPhoneNumber = useCallback(
|
|
77
|
-
(dependent: HIEPatient | DependentWithPhone): string
|
|
77
|
+
(dependent: HIEPatient | DependentWithPhone): string => {
|
|
78
78
|
if ('contact' in dependent && dependent.contact && Array.isArray(dependent.contact)) {
|
|
79
79
|
for (const contact of dependent.contact) {
|
|
80
80
|
if (contact.telecom && Array.isArray(contact.telecom)) {
|
|
@@ -82,7 +82,6 @@ const DependentsComponent: React.FC<DependentProps> = ({
|
|
|
82
82
|
(telecom) =>
|
|
83
83
|
telecom.system === 'phone' && telecom.value && telecom.value !== 'N/A' && telecom.value.trim() !== '',
|
|
84
84
|
);
|
|
85
|
-
|
|
86
85
|
if (phoneTelecom) {
|
|
87
86
|
return sanitizePhoneNumber(phoneTelecom.value);
|
|
88
87
|
}
|
|
@@ -99,7 +98,6 @@ const DependentsComponent: React.FC<DependentProps> = ({
|
|
|
99
98
|
attr.value.trim() !== '' &&
|
|
100
99
|
attr.value.trim().length > 0,
|
|
101
100
|
);
|
|
102
|
-
|
|
103
101
|
if (phoneAttribute?.value) {
|
|
104
102
|
return sanitizePhoneNumber(phoneAttribute.value);
|
|
105
103
|
}
|
|
@@ -152,16 +150,12 @@ const DependentsComponent: React.FC<DependentProps> = ({
|
|
|
152
150
|
return {
|
|
153
151
|
onRequestOtp: async (phoneNumber: string): Promise<void> => {
|
|
154
152
|
const sanitizedPhone = sanitizePhoneNumber(phoneNumber);
|
|
155
|
-
|
|
156
153
|
try {
|
|
157
154
|
if (!otpSource) {
|
|
158
155
|
throw new Error('OTP source not configured. Please contact your administrator.');
|
|
159
156
|
}
|
|
160
|
-
|
|
161
157
|
otpManager.setOtpSource(otpSource);
|
|
162
|
-
|
|
163
158
|
setActivePhoneNumbers((prev) => new Map(prev.set(dependentId, sanitizedPhone)));
|
|
164
|
-
|
|
165
159
|
await otpManager.requestOTP(sanitizedPhone, dependentName, otpExpiryMinutes, null, dependentId);
|
|
166
160
|
} catch (error) {
|
|
167
161
|
throw error;
|
|
@@ -172,12 +166,9 @@ const DependentsComponent: React.FC<DependentProps> = ({
|
|
|
172
166
|
if (!otpSource) {
|
|
173
167
|
throw new Error('OTP source not configured. Please contact your administrator.');
|
|
174
168
|
}
|
|
175
|
-
|
|
176
169
|
otpManager.setOtpSource(otpSource);
|
|
177
|
-
|
|
178
170
|
const activePhone = activePhoneNumbers.get(dependentId) || initialPhone;
|
|
179
171
|
const sanitizedPhone = sanitizePhoneNumber(activePhone);
|
|
180
|
-
|
|
181
172
|
const isValid = await otpManager.verifyOTP(sanitizedPhone, otp, dependentId);
|
|
182
173
|
if (!isValid) {
|
|
183
174
|
throw new Error('OTP verification failed');
|
|
@@ -211,20 +202,24 @@ const DependentsComponent: React.FC<DependentProps> = ({
|
|
|
211
202
|
}
|
|
212
203
|
|
|
213
204
|
if (localPatient) {
|
|
214
|
-
|
|
215
|
-
localPatient
|
|
216
|
-
`${localPatient.person?.personName?.givenName || ''} ${localPatient.person?.personName?.middleName || ''} ${
|
|
217
|
-
localPatient.person?.personName?.familyName || ''
|
|
218
|
-
}`.trim() ||
|
|
219
|
-
dependent.name;
|
|
220
|
-
|
|
221
|
-
launchWorkspace('start-visit-workspace-form', {
|
|
205
|
+
await launchWorkspaceGroup2('ewf-patient-chart', {
|
|
206
|
+
patient: localPatient,
|
|
222
207
|
patientUuid: localPatient.uuid,
|
|
223
|
-
|
|
208
|
+
visitContext: null as unknown as Visit,
|
|
209
|
+
mutateVisitContext: () => {},
|
|
224
210
|
});
|
|
211
|
+
|
|
212
|
+
launchWorkspace2<VisitFormProps, {}, {}>(
|
|
213
|
+
'custom-start-visit-workspace-form',
|
|
214
|
+
{
|
|
215
|
+
openedFrom: 'dependants-check-in',
|
|
216
|
+
showPatientHeader: false,
|
|
217
|
+
},
|
|
218
|
+
{},
|
|
219
|
+
null,
|
|
220
|
+
);
|
|
225
221
|
} else {
|
|
226
222
|
setSubmittingStates((prev) => ({ ...prev, [dependent.id]: true }));
|
|
227
|
-
|
|
228
223
|
try {
|
|
229
224
|
await registerOrLaunchDependent(dependent, t);
|
|
230
225
|
} catch (error) {
|
|
@@ -246,34 +241,13 @@ const DependentsComponent: React.FC<DependentProps> = ({
|
|
|
246
241
|
|
|
247
242
|
const headers = useMemo(
|
|
248
243
|
() => [
|
|
249
|
-
{
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
key: 'gender',
|
|
259
|
-
header: t('gender', 'Gender'),
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
key: 'birthDate',
|
|
263
|
-
header: t('birthDate', 'Birth Date'),
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
key: 'identifiers',
|
|
267
|
-
header: t('identifiers', 'Identifiers'),
|
|
268
|
-
},
|
|
269
|
-
{
|
|
270
|
-
key: 'status',
|
|
271
|
-
header: t('status', 'Status'),
|
|
272
|
-
},
|
|
273
|
-
{
|
|
274
|
-
key: 'actions',
|
|
275
|
-
header: t('actions', 'Actions'),
|
|
276
|
-
},
|
|
244
|
+
{ key: 'name', header: t('name', 'Name') },
|
|
245
|
+
{ key: 'relationship', header: t('relationship', 'Relationship') },
|
|
246
|
+
{ key: 'gender', header: t('gender', 'Gender') },
|
|
247
|
+
{ key: 'birthDate', header: t('birthDate', 'Birth Date') },
|
|
248
|
+
{ key: 'identifiers', header: t('identifiers', 'Identifiers') },
|
|
249
|
+
{ key: 'status', header: t('status', 'Status') },
|
|
250
|
+
{ key: 'actions', header: t('actions', 'Actions') },
|
|
277
251
|
],
|
|
278
252
|
[t],
|
|
279
253
|
);
|
|
@@ -475,18 +449,16 @@ const DependentsComponent: React.FC<DependentProps> = ({
|
|
|
475
449
|
<Table {...getTableProps()}>
|
|
476
450
|
<TableHead>
|
|
477
451
|
<TableRow>
|
|
478
|
-
{headers.map((header
|
|
479
|
-
<TableHeader
|
|
480
|
-
{header.header}
|
|
481
|
-
</TableHeader>
|
|
452
|
+
{headers.map((header) => (
|
|
453
|
+
<TableHeader {...getHeaderProps({ header })}>{header.header}</TableHeader>
|
|
482
454
|
))}
|
|
483
455
|
</TableRow>
|
|
484
456
|
</TableHead>
|
|
485
457
|
<TableBody>
|
|
486
|
-
{rows.map((row
|
|
487
|
-
<TableRow
|
|
488
|
-
{row.cells.map((cell
|
|
489
|
-
<TableCell key={
|
|
458
|
+
{rows.map((row) => (
|
|
459
|
+
<TableRow {...getRowProps({ row })}>
|
|
460
|
+
{row.cells.map((cell) => (
|
|
461
|
+
<TableCell key={cell.id}>{cell.value}</TableCell>
|
|
490
462
|
))}
|
|
491
463
|
</TableRow>
|
|
492
464
|
))}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
getSessionLocation,
|
|
3
|
+
launchWorkspace2,
|
|
4
|
+
launchWorkspaceGroup2,
|
|
5
|
+
openmrsFetch,
|
|
6
|
+
restBaseUrl,
|
|
7
|
+
showSnackbar,
|
|
8
|
+
type Visit,
|
|
9
|
+
} from '@openmrs/esm-framework';
|
|
2
10
|
import { DependentPayload, HIEPatient } from '../type';
|
|
3
|
-
import { generateIdentifier, getIdentifierTypeUUID } from '../helper';
|
|
11
|
+
import { generateIdentifier, getIdentifierTypeUUID, sanitizeName } from '../helper';
|
|
4
12
|
import { openmrsId, openmrsIdSource } from '../constant';
|
|
5
13
|
import { useEffect, useState } from 'react';
|
|
14
|
+
import { VisitFormProps } from '../start-visit-form/visit-form-workspace/visit-form.workspace';
|
|
6
15
|
|
|
7
16
|
export interface PatientRegistrationPayload {
|
|
8
17
|
name: string;
|
|
@@ -12,18 +21,34 @@ export interface PatientRegistrationPayload {
|
|
|
12
21
|
type: 'hie-patient' | 'dependent';
|
|
13
22
|
}
|
|
14
23
|
|
|
24
|
+
interface AddressPayload {
|
|
25
|
+
address1: string;
|
|
26
|
+
address2?: string;
|
|
27
|
+
cityVillage: string;
|
|
28
|
+
country: string;
|
|
29
|
+
postalCode: string;
|
|
30
|
+
stateProvince: string;
|
|
31
|
+
countyDistrict?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
15
34
|
export async function createPatient(payload: PatientRegistrationPayload, t: any) {
|
|
16
35
|
try {
|
|
17
|
-
const { patientData, type,
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
36
|
+
const { patientData, type, gender, birthDate } = payload;
|
|
37
|
+
const sessionLocation = await getSessionLocation();
|
|
38
|
+
const locationUuid = sessionLocation?.uuid ?? '';
|
|
39
|
+
|
|
40
|
+
let identifiers: Array<{
|
|
41
|
+
identifier: string;
|
|
42
|
+
identifierType: string;
|
|
43
|
+
location: string;
|
|
44
|
+
preferred: boolean;
|
|
45
|
+
}> = [];
|
|
21
46
|
let givenName = '';
|
|
22
47
|
let middleName = '';
|
|
23
48
|
let familyName = '';
|
|
24
49
|
let patientBirthDate = birthDate;
|
|
25
50
|
let patientGender = gender;
|
|
26
|
-
let addresses = [];
|
|
51
|
+
let addresses: AddressPayload[] = [];
|
|
27
52
|
|
|
28
53
|
if (type === 'hie-patient') {
|
|
29
54
|
const hiePatient = patientData as HIEPatient;
|
|
@@ -37,13 +62,13 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
|
|
|
37
62
|
preferred: false,
|
|
38
63
|
}))
|
|
39
64
|
.filter((identifier) => identifier.identifierType) || [];
|
|
40
|
-
|
|
65
|
+
|
|
66
|
+
identifiers.push({
|
|
41
67
|
identifier: hiePatient?.id,
|
|
42
68
|
identifierType: getIdentifierTypeUUID('sha-id-number'),
|
|
43
69
|
location: locationUuid,
|
|
44
70
|
preferred: false,
|
|
45
|
-
};
|
|
46
|
-
identifiers.push(crIdentifier);
|
|
71
|
+
});
|
|
47
72
|
|
|
48
73
|
const patientName = hiePatient.name?.[0];
|
|
49
74
|
if (patientName) {
|
|
@@ -85,13 +110,13 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
|
|
|
85
110
|
preferred: false,
|
|
86
111
|
}))
|
|
87
112
|
.filter((identifier: any) => identifier.identifierType) || [];
|
|
88
|
-
|
|
113
|
+
|
|
114
|
+
identifiers.push({
|
|
89
115
|
identifier: dependentInfo?.id,
|
|
90
116
|
identifierType: getIdentifierTypeUUID('sha-id-number'),
|
|
91
117
|
location: locationUuid,
|
|
92
118
|
preferred: false,
|
|
93
|
-
};
|
|
94
|
-
identifiers.push(crIdentifier);
|
|
119
|
+
});
|
|
95
120
|
|
|
96
121
|
const birthdate = dependentInfo.extension?.find(
|
|
97
122
|
(ext: any) => ext.url === 'https://ts.kenya-hie.health/fhir/StructureDefinition/date_of_birth',
|
|
@@ -129,7 +154,7 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
|
|
|
129
154
|
identifiers[0].preferred = true;
|
|
130
155
|
}
|
|
131
156
|
|
|
132
|
-
const phoneAttributes = [];
|
|
157
|
+
const phoneAttributes: Array<{ attributeType: string; value: string }> = [];
|
|
133
158
|
if (type === 'hie-patient') {
|
|
134
159
|
const phoneContact = patientData.telecom?.find((t: any) => t.system === 'phone');
|
|
135
160
|
if (phoneContact?.value) {
|
|
@@ -140,32 +165,29 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
|
|
|
140
165
|
}
|
|
141
166
|
}
|
|
142
167
|
|
|
168
|
+
const defaultAddress: AddressPayload = {
|
|
169
|
+
address1: '',
|
|
170
|
+
cityVillage: '',
|
|
171
|
+
country: '',
|
|
172
|
+
postalCode: '',
|
|
173
|
+
stateProvince: '',
|
|
174
|
+
};
|
|
175
|
+
|
|
143
176
|
const registrationPayload = {
|
|
144
177
|
person: {
|
|
145
178
|
names: [
|
|
146
179
|
{
|
|
147
180
|
preferred: true,
|
|
148
|
-
givenName: givenName || 'Unknown',
|
|
149
|
-
middleName: middleName || '',
|
|
150
|
-
familyName: familyName || 'Unknown',
|
|
181
|
+
givenName: sanitizeName(givenName) || 'Unknown',
|
|
182
|
+
middleName: sanitizeName(middleName) || '',
|
|
183
|
+
familyName: sanitizeName(familyName) || 'Unknown',
|
|
151
184
|
},
|
|
152
185
|
],
|
|
153
186
|
gender: patientGender?.charAt(0).toUpperCase() || 'U',
|
|
154
187
|
birthdate: patientBirthDate || null,
|
|
155
188
|
birthdateEstimated: !patientBirthDate,
|
|
156
189
|
attributes: phoneAttributes,
|
|
157
|
-
addresses:
|
|
158
|
-
addresses.length > 0
|
|
159
|
-
? addresses
|
|
160
|
-
: [
|
|
161
|
-
{
|
|
162
|
-
address1: '',
|
|
163
|
-
cityVillage: '',
|
|
164
|
-
country: '',
|
|
165
|
-
postalCode: '',
|
|
166
|
-
stateProvince: '',
|
|
167
|
-
},
|
|
168
|
-
],
|
|
190
|
+
addresses: addresses.length > 0 ? addresses : [defaultAddress],
|
|
169
191
|
},
|
|
170
192
|
identifiers: [...identifiers],
|
|
171
193
|
};
|
|
@@ -174,6 +196,10 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
|
|
|
174
196
|
const identifierResponse = await generateIdentifier(openmrsIdSource);
|
|
175
197
|
const location = await getSessionLocation();
|
|
176
198
|
|
|
199
|
+
if (!location?.uuid) {
|
|
200
|
+
throw new Error('Could not determine session location');
|
|
201
|
+
}
|
|
202
|
+
|
|
177
203
|
const openmrsIdentifier = {
|
|
178
204
|
identifier: identifierResponse.data.identifier,
|
|
179
205
|
identifierType: openmrsId,
|
|
@@ -199,7 +225,7 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
|
|
|
199
225
|
throw new Error('No valid identifiers found for the patient');
|
|
200
226
|
}
|
|
201
227
|
|
|
202
|
-
const response = await openmrsFetch(`${restBaseUrl}/patient`, {
|
|
228
|
+
const response = await openmrsFetch<{ uuid: string }>(`${restBaseUrl}/patient`, {
|
|
203
229
|
method: 'POST',
|
|
204
230
|
headers: {
|
|
205
231
|
'Content-Type': 'application/json',
|
|
@@ -217,7 +243,7 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
|
|
|
217
243
|
});
|
|
218
244
|
|
|
219
245
|
return response.data;
|
|
220
|
-
} catch (error) {
|
|
246
|
+
} catch (error: any) {
|
|
221
247
|
console.error('Error creating patient:', error);
|
|
222
248
|
|
|
223
249
|
const patientType = payload.type === 'hie-patient' ? 'Patient' : 'Dependent';
|
|
@@ -243,6 +269,25 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
|
|
|
243
269
|
}
|
|
244
270
|
}
|
|
245
271
|
|
|
272
|
+
async function launchCheckInWorkspace(patient: any, patientUuid: string) {
|
|
273
|
+
await launchWorkspaceGroup2('ewf-patient-chart', {
|
|
274
|
+
patient,
|
|
275
|
+
patientUuid,
|
|
276
|
+
visitContext: null as unknown as Visit,
|
|
277
|
+
mutateVisitContext: () => {},
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
launchWorkspace2<VisitFormProps, {}, {}>(
|
|
281
|
+
'custom-start-visit-workspace-form',
|
|
282
|
+
{
|
|
283
|
+
openedFrom: 'registration-check-in',
|
|
284
|
+
showPatientHeader: false,
|
|
285
|
+
},
|
|
286
|
+
{},
|
|
287
|
+
null,
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
246
291
|
export async function createDependentPatient(dependent: DependentPayload, t: any) {
|
|
247
292
|
const payload: PatientRegistrationPayload = {
|
|
248
293
|
name: dependent.name,
|
|
@@ -252,14 +297,7 @@ export async function createDependentPatient(dependent: DependentPayload, t: any
|
|
|
252
297
|
};
|
|
253
298
|
|
|
254
299
|
const result = await createPatient(payload, t);
|
|
255
|
-
|
|
256
|
-
launchWorkspace('start-visit-workspace-form', {
|
|
257
|
-
patientUuid: result.uuid,
|
|
258
|
-
workspaceTitle: t('startVisitWorkspaceTitle', 'Start Visit for {{patientName}}', {
|
|
259
|
-
patientName: dependent.name,
|
|
260
|
-
}),
|
|
261
|
-
});
|
|
262
|
-
|
|
300
|
+
await launchCheckInWorkspace(result, result.uuid);
|
|
263
301
|
return result;
|
|
264
302
|
}
|
|
265
303
|
|
|
@@ -278,14 +316,7 @@ export async function createHIEPatient(hiePatient: HIEPatient, t: any) {
|
|
|
278
316
|
};
|
|
279
317
|
|
|
280
318
|
const result = await createPatient(payload, t);
|
|
281
|
-
|
|
282
|
-
launchWorkspace('start-visit-workspace-form', {
|
|
283
|
-
patientUuid: result.uuid,
|
|
284
|
-
workspaceTitle: t('startVisitWorkspaceTitle', 'Start Visit for {{patientName}}', {
|
|
285
|
-
patientName: patientName,
|
|
286
|
-
}),
|
|
287
|
-
});
|
|
288
|
-
|
|
319
|
+
await launchCheckInWorkspace(result, result.uuid);
|
|
289
320
|
return result;
|
|
290
321
|
}
|
|
291
322
|
|
|
@@ -321,11 +352,9 @@ export const getDependentsFromContacts = (patient: HIEPatient) => {
|
|
|
321
352
|
const shaIdNumber = identifierExtensions.find(
|
|
322
353
|
(ext) => ext.valueIdentifier?.type?.coding?.[0]?.code === 'sha-id-number',
|
|
323
354
|
)?.valueIdentifier?.value;
|
|
324
|
-
|
|
325
355
|
const nationalId = identifierExtensions.find(
|
|
326
356
|
(ext) => ext.valueIdentifier?.type?.coding?.[0]?.code === 'national-id',
|
|
327
357
|
)?.valueIdentifier?.value;
|
|
328
|
-
|
|
329
358
|
const birthCertificate = identifierExtensions.find(
|
|
330
359
|
(ext) => ext.valueIdentifier?.type?.coding?.[0]?.code === 'birth-certificate',
|
|
331
360
|
)?.valueIdentifier?.value;
|
|
@@ -372,7 +401,7 @@ export const useActiveVisit = (patientUuid: string | null) => {
|
|
|
372
401
|
const data = await response.json();
|
|
373
402
|
const visits = data?.results || [];
|
|
374
403
|
setActiveVisit(visits.length > 0 ? visits[0] : null);
|
|
375
|
-
} catch (err) {
|
|
404
|
+
} catch (err: any) {
|
|
376
405
|
console.warn(`Error fetching active visit for patient ${patientUuid}:`, err);
|
|
377
406
|
setError(err);
|
|
378
407
|
setActiveVisit(null);
|