@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
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getAsyncLifecycle } from '@openmrs/esm-framework';
|
|
2
2
|
|
|
3
3
|
import { moduleName } from '../../constants';
|
|
4
|
-
import { createLeftPanelLink } from '../../shared/dashboard-link/dashboard-link.component';
|
|
5
|
-
import Registration from './registration.component';
|
|
6
4
|
|
|
7
5
|
const options = {
|
|
8
6
|
featureName: 'express-workflow',
|
|
9
7
|
moduleName,
|
|
10
8
|
};
|
|
11
9
|
|
|
12
|
-
export const registrationDashboard =
|
|
10
|
+
export const registrationDashboard = getAsyncLifecycle(() => import('./registration.component'), options);
|
|
13
11
|
// t('registration', 'Registration')
|
|
14
|
-
export const registrationLeftPanelLink =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
export const registrationLeftPanelLink = getAsyncLifecycle(
|
|
13
|
+
() =>
|
|
14
|
+
import('../../shared/dashboard-link/dashboard-link.component').then((m) => ({
|
|
15
|
+
default: m.createLeftPanelLink({
|
|
16
|
+
title: 'registration',
|
|
17
|
+
name: 'registration',
|
|
18
|
+
}),
|
|
19
|
+
})),
|
|
19
20
|
options,
|
|
20
21
|
);
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
FetchResponse,
|
|
4
|
+
launchWorkspace2,
|
|
5
|
+
launchWorkspaceGroup2,
|
|
6
|
+
makeUrl,
|
|
7
|
+
openmrsFetch,
|
|
8
|
+
restBaseUrl,
|
|
9
|
+
type Visit,
|
|
10
|
+
} from '@openmrs/esm-framework';
|
|
3
11
|
import useSWR from 'swr';
|
|
4
12
|
import { type EligibilityResponse, type HIEEligibilityResponse, type LocalPatientApiResponse } from '../type';
|
|
5
13
|
import {
|
|
@@ -11,6 +19,7 @@ import {
|
|
|
11
19
|
} from '../constant';
|
|
12
20
|
import { createDependentPatient, createHIEPatient } from '../dependants/dependants.resource';
|
|
13
21
|
import { transformToDependentPayload } from '../helper';
|
|
22
|
+
import { VisitFormProps } from '../start-visit-form/visit-form-workspace/visit-form.workspace';
|
|
14
23
|
|
|
15
24
|
export const searchPatientFromHIE = async (identifierType: string, searchQuery: string) => {
|
|
16
25
|
const url = `${restBaseUrl}/kenyaemr/getSHAPatient/${searchQuery}/${identifierType}`;
|
|
@@ -64,11 +73,10 @@ export const useSHAEligibility = (nationalId: string) => {
|
|
|
64
73
|
};
|
|
65
74
|
|
|
66
75
|
export const extractPatientIdentifiers = (patient: any, isDependent = false) => {
|
|
67
|
-
const identifiers = [];
|
|
76
|
+
const identifiers: Array<{ value: string; type: string }> = [];
|
|
68
77
|
|
|
69
78
|
if (isDependent) {
|
|
70
79
|
const identifierExtensions = patient.extension?.filter((ext: any) => ext.url === 'identifiers') || [];
|
|
71
|
-
|
|
72
80
|
identifierExtensions.forEach((ext: any) => {
|
|
73
81
|
if (ext.valueIdentifier?.value && ext.valueIdentifier?.type?.coding?.[0]?.code) {
|
|
74
82
|
identifiers.push({
|
|
@@ -101,7 +109,7 @@ export const findExistingLocalPatient = async (patient: any, isDependent = false
|
|
|
101
109
|
}
|
|
102
110
|
|
|
103
111
|
const prioritizedIdentifiers = identifiers.sort((a, b) => {
|
|
104
|
-
const priorityOrder = { 'national-id': 1, 'sha-number': 2, 'birth-certificate': 3 };
|
|
112
|
+
const priorityOrder: Record<string, number> = { 'national-id': 1, 'sha-number': 2, 'birth-certificate': 3 };
|
|
105
113
|
return (priorityOrder[a.type] || 999) - (priorityOrder[b.type] || 999);
|
|
106
114
|
});
|
|
107
115
|
|
|
@@ -119,26 +127,30 @@ export const findExistingLocalPatient = async (patient: any, isDependent = false
|
|
|
119
127
|
return null;
|
|
120
128
|
};
|
|
121
129
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
130
|
+
async function launchCheckInWorkspace(patient: any, patientUuid: string) {
|
|
131
|
+
await launchWorkspaceGroup2('ewf-patient-chart', {
|
|
132
|
+
patient,
|
|
133
|
+
patientUuid,
|
|
134
|
+
visitContext: null as unknown as Visit,
|
|
135
|
+
mutateVisitContext: () => {},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
launchWorkspace2<VisitFormProps, {}, {}>(
|
|
139
|
+
'custom-start-visit-workspace-form',
|
|
140
|
+
{
|
|
141
|
+
openedFrom: 'registration-check-in',
|
|
142
|
+
showPatientHeader: false,
|
|
143
|
+
},
|
|
144
|
+
{},
|
|
145
|
+
null,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
129
149
|
export const registerOrLaunchHIEPatient = async (hiePatient: any, t: any) => {
|
|
130
150
|
try {
|
|
131
151
|
const existingLocalPatient = await findExistingLocalPatient(hiePatient, false);
|
|
132
152
|
|
|
133
153
|
if (existingLocalPatient) {
|
|
134
|
-
const patientName =
|
|
135
|
-
existingLocalPatient.person?.personName?.display ||
|
|
136
|
-
`${existingLocalPatient.person?.personName?.givenName || ''} ${
|
|
137
|
-
existingLocalPatient.person?.personName?.middleName || ''
|
|
138
|
-
} ${existingLocalPatient.person?.personName?.familyName || ''}`.trim() ||
|
|
139
|
-
hiePatient.name?.[0]?.text ||
|
|
140
|
-
'Unknown Patient';
|
|
141
|
-
|
|
142
154
|
return existingLocalPatient;
|
|
143
155
|
} else {
|
|
144
156
|
return await createHIEPatient(hiePatient, t);
|
|
@@ -148,32 +160,12 @@ export const registerOrLaunchHIEPatient = async (hiePatient: any, t: any) => {
|
|
|
148
160
|
}
|
|
149
161
|
};
|
|
150
162
|
|
|
151
|
-
/**
|
|
152
|
-
* Registers a new dependent patient if they don't exist locally, or launches the start visit workspace if they do.
|
|
153
|
-
*
|
|
154
|
-
* @param {Object} dependent - The dependent object returned from the HIE
|
|
155
|
-
* @param {Object} t - The i18n translation function
|
|
156
|
-
* @returns {Promise<Object>} The patient record for the newly registered or existing patient
|
|
157
|
-
*/
|
|
158
163
|
export const registerOrLaunchDependent = async (dependent: any, t: any) => {
|
|
159
164
|
try {
|
|
160
165
|
const existingLocalPatient = await findExistingLocalPatient(dependent.contactData, true);
|
|
161
166
|
|
|
162
167
|
if (existingLocalPatient) {
|
|
163
|
-
|
|
164
|
-
existingLocalPatient.person?.personName?.display ||
|
|
165
|
-
`${existingLocalPatient.person?.personName?.givenName || ''} ${
|
|
166
|
-
existingLocalPatient.person?.personName?.middleName || ''
|
|
167
|
-
} ${existingLocalPatient.person?.personName?.familyName || ''}`.trim() ||
|
|
168
|
-
dependent.name;
|
|
169
|
-
|
|
170
|
-
launchWorkspace('start-visit-workspace-form', {
|
|
171
|
-
patientUuid: existingLocalPatient.uuid,
|
|
172
|
-
workspaceTitle: t('startVisitWorkspaceTitle', 'Start Visit for {{patientName}}', {
|
|
173
|
-
patientName: patientName,
|
|
174
|
-
}),
|
|
175
|
-
});
|
|
176
|
-
|
|
168
|
+
await launchCheckInWorkspace(existingLocalPatient, existingLocalPatient.uuid);
|
|
177
169
|
return existingLocalPatient;
|
|
178
170
|
} else {
|
|
179
171
|
const dependentPayload = transformToDependentPayload(dependent);
|
|
@@ -184,12 +176,6 @@ export const registerOrLaunchDependent = async (dependent: any, t: any) => {
|
|
|
184
176
|
}
|
|
185
177
|
};
|
|
186
178
|
|
|
187
|
-
/**
|
|
188
|
-
* Searches for multiple dependents locally.
|
|
189
|
-
*
|
|
190
|
-
* @param {Object[]} dependents - Array of dependent objects returned from the HIE
|
|
191
|
-
* @returns {Promise<Map<string, any>>} A Map of dependent IDs to the corresponding patient records if found, or `null` if the dependent is not found.
|
|
192
|
-
*/
|
|
193
179
|
export const searchMultipleDependentsLocally = async (dependents: any[]) => {
|
|
194
180
|
const results = new Map();
|
|
195
181
|
|
|
@@ -205,13 +191,6 @@ export const searchMultipleDependentsLocally = async (dependents: any[]) => {
|
|
|
205
191
|
return results;
|
|
206
192
|
};
|
|
207
193
|
|
|
208
|
-
/**
|
|
209
|
-
* Searches for a patient by identifier value in the local OpenMRS database.
|
|
210
|
-
*
|
|
211
|
-
* @param {string} identifierValue - The value of the identifier to search for
|
|
212
|
-
* @param {string} [identifierType] - The type of identifier to search by, if specified
|
|
213
|
-
* @returns {Promise<Object | null>} The patient record for the matching patient, or `null` if no match is found
|
|
214
|
-
*/
|
|
215
194
|
export const searchLocalPatientByIdentifier = async (identifierValue: string, identifierType?: string) => {
|
|
216
195
|
if (!identifierValue) {
|
|
217
196
|
return null;
|
|
@@ -253,22 +232,6 @@ export const searchLocalPatientByIdentifier = async (identifierValue: string, id
|
|
|
253
232
|
}
|
|
254
233
|
};
|
|
255
234
|
|
|
256
|
-
/**
|
|
257
|
-
* @param {string | null} identifierValue - The identifier value to search for, or null to not search.
|
|
258
|
-
* @returns {object} An object containing the local patient, if found, and booleans indicating whether the search is loading or encountered an error.
|
|
259
|
-
*
|
|
260
|
-
* @example
|
|
261
|
-
* const { localPatient, isLoading, error } = useLocalPatientByIdentifier('12345678');
|
|
262
|
-
* if (isLoading) {
|
|
263
|
-
* // show a loading indicator
|
|
264
|
-
* }
|
|
265
|
-
* if (error) {
|
|
266
|
-
* // handle the error
|
|
267
|
-
* }
|
|
268
|
-
* if (localPatient) {
|
|
269
|
-
* // do something with the local patient
|
|
270
|
-
* }
|
|
271
|
-
*/
|
|
272
235
|
export const useLocalPatientByIdentifier = (identifierValue: string | null) => {
|
|
273
236
|
const { data, error, isLoading } = useSWR(
|
|
274
237
|
identifierValue ? `local-patient-${identifierValue}` : null,
|
|
@@ -287,30 +250,6 @@ export const useLocalPatientByIdentifier = (identifierValue: string | null) => {
|
|
|
287
250
|
};
|
|
288
251
|
};
|
|
289
252
|
|
|
290
|
-
/**
|
|
291
|
-
* Searches for local patients with the given identifiers and returns an array of results.
|
|
292
|
-
*
|
|
293
|
-
* Each result is an object with an `identifier` property (the identifier that was searched for),
|
|
294
|
-
* a `patient` property (the local patient that was found, or null if none was found), and an
|
|
295
|
-
* `error` property (an error message if the search failed, or null if the search was successful).
|
|
296
|
-
*
|
|
297
|
-
* @param {Array<{ value: string; type: string }>} identifiers - The identifiers to search for.
|
|
298
|
-
* @returns {Promise<Array<{ identifier: { value: string; type: string }; patient: LocalPatient | null; error: string | null }>>} The results of the search.
|
|
299
|
-
*
|
|
300
|
-
* @example
|
|
301
|
-
* const results = await searchLocalPatientsByIdentifiers([
|
|
302
|
-
* { value: '12345678', type: 'national-id' },
|
|
303
|
-
* { value: '1234567890', type: 'ccc-number' },
|
|
304
|
-
* ]);
|
|
305
|
-
* results.forEach((result) => {
|
|
306
|
-
* if (result.patient) {
|
|
307
|
-
* // do something with the local patient
|
|
308
|
-
* }
|
|
309
|
-
* if (result.error) {
|
|
310
|
-
* // handle the error
|
|
311
|
-
* }
|
|
312
|
-
* });
|
|
313
|
-
*/
|
|
314
253
|
export const searchLocalPatientsByIdentifiers = async (identifiers: Array<{ value: string; type: string }>) => {
|
|
315
254
|
const results = await Promise.allSettled(
|
|
316
255
|
identifiers.map((identifier) => searchLocalPatientByIdentifier(identifier.value, identifier.type)),
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type FetchResponse, openmrsFetch, useConfig } from '@openmrs/esm-framework';
|
|
2
|
+
import useSWRImmutable from 'swr/immutable';
|
|
3
|
+
import { ExpressWorkflowConfig } from '../../../../config-schema';
|
|
4
|
+
|
|
5
|
+
export const useDefaultFacilityLocation = () => {
|
|
6
|
+
const config = useConfig() as ExpressWorkflowConfig;
|
|
7
|
+
const apiUrl = config.defaultFacilityUrl;
|
|
8
|
+
const { data, error, isLoading } = useSWRImmutable<FetchResponse>(apiUrl, openmrsFetch);
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
defaultFacility: data ? data?.data : null,
|
|
12
|
+
isLoading: isLoading,
|
|
13
|
+
error: error,
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type FetchResponse, type Location, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import useSWR from 'swr';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Fetches the default visit location based on the location and the restrictByVisitLocationTag
|
|
7
|
+
* If restrictByVisitLocationTag is true, it fetches the nearest ancestor location that supports visits, otherwise it returns the passed-in location
|
|
8
|
+
*
|
|
9
|
+
* @param location
|
|
10
|
+
* @param restrictByVisitLocationTag
|
|
11
|
+
*/
|
|
12
|
+
export function useDefaultVisitLocation(location: Location | undefined, restrictByVisitLocationTag: boolean) {
|
|
13
|
+
let url = location?.uuid ? `${restBaseUrl}/emrapi/locationThatSupportsVisits?location=${location.uuid}` : null;
|
|
14
|
+
|
|
15
|
+
const { data, error } = useSWR<FetchResponse>(restrictByVisitLocationTag ? url : null, openmrsFetch);
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (error) {
|
|
19
|
+
console.error(error);
|
|
20
|
+
}
|
|
21
|
+
}, [error]);
|
|
22
|
+
|
|
23
|
+
return !restrictByVisitLocationTag ? location : data?.data;
|
|
24
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type VisitType, useConfig } from '@openmrs/esm-framework';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import { ExpressWorkflowConfig } from '../../../../config-schema';
|
|
5
|
+
|
|
6
|
+
export const useOfflineVisitType = () => {
|
|
7
|
+
const config = useConfig() as ExpressWorkflowConfig;
|
|
8
|
+
const { t } = useTranslation();
|
|
9
|
+
const [visitTypes, setVisitTypes] = useState<Array<VisitType>>([]);
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
setVisitTypes([
|
|
13
|
+
{ uuid: config.offlineVisitTypeUuid, name: 'Offline Visit', display: t('offlineVisit', 'Offline Visit') },
|
|
14
|
+
]);
|
|
15
|
+
}, [t, config.offlineVisitTypeUuid]);
|
|
16
|
+
|
|
17
|
+
return visitTypes;
|
|
18
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import useSWR from 'swr';
|
|
3
|
+
import { openmrsFetch, useConfig } from '@openmrs/esm-framework';
|
|
4
|
+
import { ExpressWorkflowConfig } from '../../../../config-schema';
|
|
5
|
+
|
|
6
|
+
interface EnrollmentVisitType {
|
|
7
|
+
uuid: string;
|
|
8
|
+
dataDependencies: Array<string>;
|
|
9
|
+
enrollmentOptions: object;
|
|
10
|
+
incompatibleWith: Array<string>;
|
|
11
|
+
name: string;
|
|
12
|
+
visitTypes: { allowed: Array<EnrollmentVisitType>; disallowed: Array<EnrollmentVisitType> };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const useRecommendedVisitTypes = (
|
|
16
|
+
patientUuid: string,
|
|
17
|
+
enrollmentUuid: string,
|
|
18
|
+
programUuid: string,
|
|
19
|
+
locationUuid: string,
|
|
20
|
+
) => {
|
|
21
|
+
const { visitTypeResourceUrl, showRecommendedVisitTypeTab } = useConfig() as ExpressWorkflowConfig;
|
|
22
|
+
const url = `${visitTypeResourceUrl}${patientUuid}/program/${programUuid}/enrollment/${enrollmentUuid}?intendedLocationUuid=${locationUuid}`;
|
|
23
|
+
|
|
24
|
+
const { data, error, isLoading } = useSWR<{ data: EnrollmentVisitType }>(
|
|
25
|
+
showRecommendedVisitTypeTab && patientUuid && enrollmentUuid && programUuid ? url : null,
|
|
26
|
+
openmrsFetch,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const recommendedVisitTypes = useMemo(() => data?.data?.visitTypes?.allowed.map(mapToVisitType) ?? [], [data]);
|
|
30
|
+
return { recommendedVisitTypes, error, isLoading };
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const mapToVisitType = (visitType: EnrollmentVisitType) => ({
|
|
34
|
+
...visitType,
|
|
35
|
+
display: visitType.name,
|
|
36
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { type FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
|
3
|
+
import useSWRImmutable from 'swr/immutable';
|
|
4
|
+
|
|
5
|
+
interface VisitAttributeType {
|
|
6
|
+
uuid: string;
|
|
7
|
+
display: string;
|
|
8
|
+
name: string;
|
|
9
|
+
description: string | null;
|
|
10
|
+
datatypeClassname:
|
|
11
|
+
| 'org.openmrs.customdatatype.datatype.ConceptDatatype'
|
|
12
|
+
| 'org.openmrs.customdatatype.datatype.FloatDatatype'
|
|
13
|
+
| 'org.openmrs.customdatatype.datatype.BooleanDatatype'
|
|
14
|
+
| 'org.openmrs.customdatatype.datatype.LongFreeTextDatatype'
|
|
15
|
+
| 'org.openmrs.customdatatype.datatype.FreeTextDatatype'
|
|
16
|
+
| 'org.openmrs.customdatatype.datatype.DateDatatype';
|
|
17
|
+
datatypeConfig: string;
|
|
18
|
+
preferredHandlerClassname: any;
|
|
19
|
+
retired: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface Concept {
|
|
23
|
+
uuid: string;
|
|
24
|
+
name: {
|
|
25
|
+
display: string;
|
|
26
|
+
};
|
|
27
|
+
display: string;
|
|
28
|
+
answers: Array<{
|
|
29
|
+
display: string;
|
|
30
|
+
uuid: string;
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const visitAttributeTypeCustomRepresentation =
|
|
35
|
+
'custom:(uuid,display,name,description,datatypeClassname,datatypeConfig)';
|
|
36
|
+
|
|
37
|
+
export function useVisitAttributeTypes() {
|
|
38
|
+
const { data, error, isLoading } = useSWRImmutable<FetchResponse<{ results: VisitAttributeType[] }>, Error>(
|
|
39
|
+
`${restBaseUrl}/visitattributetype?v=${visitAttributeTypeCustomRepresentation}`,
|
|
40
|
+
openmrsFetch,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
if (error) {
|
|
44
|
+
console.error('Failed to fetch visit attribute types: ', error);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const results = useMemo(
|
|
48
|
+
() => ({
|
|
49
|
+
isLoading,
|
|
50
|
+
error,
|
|
51
|
+
visitAttributeTypes: data?.data?.results ?? [],
|
|
52
|
+
}),
|
|
53
|
+
[data, error, isLoading],
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
return results;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function useVisitAttributeType(uuid: string) {
|
|
60
|
+
const { data, error, isLoading } = useSWRImmutable<FetchResponse<VisitAttributeType>, Error>(
|
|
61
|
+
`${restBaseUrl}/visitattributetype/${uuid}?v=${visitAttributeTypeCustomRepresentation}`,
|
|
62
|
+
openmrsFetch,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
if (error) {
|
|
66
|
+
console.error(`Failed to fetch visit attribute type ${uuid}: `, error);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const results = useMemo(
|
|
70
|
+
() => ({
|
|
71
|
+
isLoading,
|
|
72
|
+
error: error,
|
|
73
|
+
data: data?.data,
|
|
74
|
+
}),
|
|
75
|
+
[data, error, isLoading],
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return results;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function useConceptAnswersForVisitAttributeType(conceptUuid: string | null) {
|
|
82
|
+
const { data, error, isLoading } = useSWRImmutable<FetchResponse<Concept>, Error>(
|
|
83
|
+
conceptUuid ? `${restBaseUrl}/concept/${conceptUuid}` : null,
|
|
84
|
+
openmrsFetch,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
if (error) {
|
|
88
|
+
console.error(`Failed to fetch concept answers for visit attribute type ${conceptUuid}: `, error);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const results = useMemo(
|
|
92
|
+
() => ({
|
|
93
|
+
isLoading,
|
|
94
|
+
error: error,
|
|
95
|
+
data: data?.data,
|
|
96
|
+
answers: data?.data?.answers,
|
|
97
|
+
}),
|
|
98
|
+
[data, error, isLoading],
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
return results;
|
|
102
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { OverflowMenuItem } from '@carbon/react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import { launchWorkspace2, launchWorkspaceGroup2, type Visit } from '@openmrs/esm-framework';
|
|
5
|
+
import styles from './overflow-menu-item.scss';
|
|
6
|
+
import { type VisitFormProps } from '../visit-form-workspace/visit-form.workspace';
|
|
7
|
+
|
|
8
|
+
interface CustomStartVisitOverflowMenuItemProps {
|
|
9
|
+
patientUuid?: string;
|
|
10
|
+
patient?: fhir.Patient;
|
|
11
|
+
closeMenu?: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const CustomStartVisitOverflowMenuItem: React.FC<CustomStartVisitOverflowMenuItemProps> = ({
|
|
15
|
+
patient,
|
|
16
|
+
patientUuid,
|
|
17
|
+
closeMenu,
|
|
18
|
+
}) => {
|
|
19
|
+
const { t } = useTranslation();
|
|
20
|
+
const isDeceased = Boolean(patient?.deceasedDateTime);
|
|
21
|
+
|
|
22
|
+
const handleLaunchModal = useCallback(async () => {
|
|
23
|
+
const resolvedPatientUuid = patient?.id ?? patientUuid ?? '';
|
|
24
|
+
|
|
25
|
+
await launchWorkspaceGroup2('ewf-patient-chart', {
|
|
26
|
+
patient,
|
|
27
|
+
patientUuid: resolvedPatientUuid,
|
|
28
|
+
visitContext: null as unknown as Visit,
|
|
29
|
+
mutateVisitContext: () => {},
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
launchWorkspace2<VisitFormProps, {}, {}>(
|
|
33
|
+
'custom-start-visit-workspace-form',
|
|
34
|
+
{
|
|
35
|
+
openedFrom: 'patient-chart-start-visit',
|
|
36
|
+
showPatientHeader: false,
|
|
37
|
+
},
|
|
38
|
+
{},
|
|
39
|
+
null,
|
|
40
|
+
);
|
|
41
|
+
}, [patient, patientUuid]);
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
!isDeceased && (
|
|
45
|
+
<OverflowMenuItem
|
|
46
|
+
className={styles.menuitem}
|
|
47
|
+
itemText={t('customCheckin', 'Check in')}
|
|
48
|
+
onClick={handleLaunchModal}
|
|
49
|
+
closeMenu={closeMenu}
|
|
50
|
+
/>
|
|
51
|
+
)
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default CustomStartVisitOverflowMenuItem;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import React, { useState, useMemo, useCallback, useEffect, useRef, type ChangeEvent } from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import { Layer, RadioButton, RadioButtonGroup, Search, StructuredListSkeleton, Tile } from '@carbon/react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import { useFormContext, Controller } from 'react-hook-form';
|
|
6
|
+
import { PatientChartPagination } from '@openmrs/esm-patient-common-lib';
|
|
7
|
+
import { useConfig, useDebounce, useLayoutType, usePagination, type VisitType } from '@openmrs/esm-framework';
|
|
8
|
+
import { type VisitFormData } from './visit-form.resource';
|
|
9
|
+
import { type ExpressWorkflowConfig } from '../../../../config-schema';
|
|
10
|
+
import styles from './base-visit-type.scss';
|
|
11
|
+
|
|
12
|
+
interface BaseVisitTypeProps {
|
|
13
|
+
visitTypes: Array<VisitType>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const BaseVisitType: React.FC<BaseVisitTypeProps> = ({ visitTypes }) => {
|
|
17
|
+
const { t } = useTranslation();
|
|
18
|
+
const { control, setValue } = useFormContext<VisitFormData>();
|
|
19
|
+
const isTablet = useLayoutType() === 'tablet';
|
|
20
|
+
const [searchTerm, setSearchTerm] = useState<string>('');
|
|
21
|
+
const debouncedSearchTerm = useDebounce(searchTerm, 300);
|
|
22
|
+
const config = useConfig<ExpressWorkflowConfig>();
|
|
23
|
+
|
|
24
|
+
const filteredVisitTypes = useMemo(() => {
|
|
25
|
+
const excluded = config?.excludedVisitTypeUuids;
|
|
26
|
+
return visitTypes.filter((visitType) => !excluded.includes(visitType.uuid));
|
|
27
|
+
}, [visitTypes, config?.excludedVisitTypeUuids]);
|
|
28
|
+
|
|
29
|
+
const searchResults = useMemo(() => {
|
|
30
|
+
if (!debouncedSearchTerm.trim()) {
|
|
31
|
+
return filteredVisitTypes;
|
|
32
|
+
}
|
|
33
|
+
const lowercasedTerm = debouncedSearchTerm.toLowerCase();
|
|
34
|
+
return filteredVisitTypes.filter((visitType) => visitType.display.toLowerCase().includes(lowercasedTerm));
|
|
35
|
+
}, [debouncedSearchTerm, filteredVisitTypes]);
|
|
36
|
+
|
|
37
|
+
const { results, currentPage, goTo } = usePagination(searchResults, 5);
|
|
38
|
+
const hasNoMatchingSearchResults = debouncedSearchTerm.trim() !== '' && searchResults.length === 0;
|
|
39
|
+
const prevSearchTermRef = useRef(debouncedSearchTerm);
|
|
40
|
+
|
|
41
|
+
const handleSearchTermChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
|
|
42
|
+
setSearchTerm(e.target.value);
|
|
43
|
+
}, []);
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (searchResults?.length === 1) {
|
|
47
|
+
setValue('visitType', searchResults[0].uuid);
|
|
48
|
+
}
|
|
49
|
+
}, [searchResults, setValue]);
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (prevSearchTermRef.current !== debouncedSearchTerm && currentPage !== 1) {
|
|
53
|
+
goTo(1);
|
|
54
|
+
}
|
|
55
|
+
prevSearchTermRef.current = debouncedSearchTerm;
|
|
56
|
+
}, [debouncedSearchTerm, currentPage, goTo]);
|
|
57
|
+
|
|
58
|
+
const searchComponent = (
|
|
59
|
+
<Search
|
|
60
|
+
labelText={t('searchForAVisitType', 'Search for a visit type')}
|
|
61
|
+
onChange={handleSearchTermChange}
|
|
62
|
+
placeholder={t('searchForAVisitType', 'Search for a visit type')}
|
|
63
|
+
value={searchTerm}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div className={classNames(styles.visitTypeOverviewWrapper, isTablet ? styles.tablet : styles.desktop)}>
|
|
69
|
+
{filteredVisitTypes.length ? (
|
|
70
|
+
<>
|
|
71
|
+
{isTablet ? <Layer>{searchComponent}</Layer> : searchComponent}
|
|
72
|
+
|
|
73
|
+
{hasNoMatchingSearchResults ? (
|
|
74
|
+
<div className={styles.tileContainer}>
|
|
75
|
+
<Tile className={styles.tile}>
|
|
76
|
+
<div className={styles.tileContent}>
|
|
77
|
+
<p className={styles.content}>{t('noVisitTypesToDisplay', 'No visit types to display')}</p>
|
|
78
|
+
<p className={styles.helper}>{t('checkFilters', 'Check the filters above')}</p>
|
|
79
|
+
</div>
|
|
80
|
+
</Tile>
|
|
81
|
+
</div>
|
|
82
|
+
) : (
|
|
83
|
+
<Controller
|
|
84
|
+
name="visitType"
|
|
85
|
+
control={control}
|
|
86
|
+
render={({ field: { onChange, value } }) => (
|
|
87
|
+
<RadioButtonGroup
|
|
88
|
+
className={styles.radioButtonGroup}
|
|
89
|
+
name="visit-types"
|
|
90
|
+
onChange={onChange}
|
|
91
|
+
orientation="vertical"
|
|
92
|
+
valueSelected={value}>
|
|
93
|
+
{results.map(({ display, uuid }) => (
|
|
94
|
+
<RadioButton
|
|
95
|
+
className={styles.radioButton}
|
|
96
|
+
id={`visit-type-${uuid}`}
|
|
97
|
+
key={uuid}
|
|
98
|
+
labelText={display}
|
|
99
|
+
value={uuid}
|
|
100
|
+
/>
|
|
101
|
+
))}
|
|
102
|
+
</RadioButtonGroup>
|
|
103
|
+
)}
|
|
104
|
+
/>
|
|
105
|
+
)}
|
|
106
|
+
|
|
107
|
+
{!hasNoMatchingSearchResults && (
|
|
108
|
+
<div className={styles.paginationContainer}>
|
|
109
|
+
<PatientChartPagination
|
|
110
|
+
currentItems={results.length}
|
|
111
|
+
onPageNumberChange={({ page }: { page: number }) => goTo(page)}
|
|
112
|
+
pageNumber={currentPage}
|
|
113
|
+
pageSize={5}
|
|
114
|
+
totalItems={searchResults.length}
|
|
115
|
+
/>
|
|
116
|
+
</div>
|
|
117
|
+
)}
|
|
118
|
+
</>
|
|
119
|
+
) : (
|
|
120
|
+
<StructuredListSkeleton className={styles.skeleton} />
|
|
121
|
+
)}
|
|
122
|
+
</div>
|
|
123
|
+
);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export default BaseVisitType;
|