@kenyaemr/esm-ward-app 8.5.4-pre.1 → 8.5.4-pre.10
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/README.md +31 -0
- package/package.json +1 -1
- package/src/config-schema.ts +21 -1
- package/src/in-patient/labourCareGuide/alert-rules.ts +97 -4
- package/src/in-patient/labourCareGuide/components/lcg-correction-audit-banner.component.tsx +42 -0
- package/src/in-patient/labourCareGuide/constants/admission-form.constants.ts +22 -0
- package/src/in-patient/labourCareGuide/context/lcg-section-state.context.tsx +252 -0
- package/src/in-patient/labourCareGuide/forms/admission-details-form.component.tsx +28 -14
- package/src/in-patient/labourCareGuide/forms/baby-form.component.tsx +55 -179
- package/src/in-patient/labourCareGuide/forms/labour-care-guide-forms.component.tsx +69 -31
- package/src/in-patient/labourCareGuide/forms/labour-progress-form.component.tsx +163 -216
- package/src/in-patient/labourCareGuide/forms/lcg-session-correction-wizard.component.tsx +214 -0
- package/src/in-patient/labourCareGuide/forms/medication-form.component.tsx +598 -220
- package/src/in-patient/labourCareGuide/forms/shared-decision-assessment-field.component.tsx +109 -0
- package/src/in-patient/labourCareGuide/forms/shared-decision-making-form.component.tsx +186 -187
- package/src/in-patient/labourCareGuide/forms/supportive-care-form.component.tsx +33 -90
- package/src/in-patient/labourCareGuide/forms/time-form.component.tsx +12 -4
- package/src/in-patient/labourCareGuide/forms/time-picker-dropdown.component.tsx +168 -53
- package/src/in-patient/labourCareGuide/forms/woman-form.component.tsx +51 -79
- package/src/in-patient/labourCareGuide/global-cds-alerts/global-cds-alert-context.tsx +2 -2
- package/src/in-patient/labourCareGuide/graphs/labour-progress.component.tsx +188 -86
- package/src/in-patient/labourCareGuide/graphs/medication.component.tsx +15 -23
- package/src/in-patient/labourCareGuide/graphs/shared-decision-making.component.tsx +157 -44
- package/src/in-patient/labourCareGuide/graphs/supportive-care.component.tsx +4 -1
- package/src/in-patient/labourCareGuide/graphs/woman.component.tsx +3 -39
- package/src/in-patient/labourCareGuide/hooks/use-lcg-data.ts +473 -229
- package/src/in-patient/labourCareGuide/hooks/use-lcg-debounced-value.ts +17 -0
- package/src/in-patient/labourCareGuide/hooks/use-lcg-form-clock.ts +36 -0
- package/src/in-patient/labourCareGuide/hooks/use-lcg-section-autosave.ts +33 -0
- package/src/in-patient/labourCareGuide/labour-care-guide.component.tsx +311 -53
- package/src/in-patient/labourCareGuide/labour-care-guide.scss +47 -0
- package/src/in-patient/labourCareGuide/labour-care-guide.utils.ts +146 -7
- package/src/in-patient/labourCareGuide/lcg-alert-lifecycle.ts +161 -0
- package/src/in-patient/labourCareGuide/partography-data-form.scss +119 -3
- package/src/in-patient/labourCareGuide/partography.resource.ts +15 -27
- package/src/in-patient/labourCareGuide/resources/admission-details.resource.ts +26 -25
- package/src/in-patient/labourCareGuide/resources/drug-stock.resource.ts +98 -0
- package/src/in-patient/labourCareGuide/resources/labour-progress.resource.ts +34 -2
- package/src/in-patient/labourCareGuide/resources/lcg-session-correction.resource.ts +1027 -0
- package/src/in-patient/labourCareGuide/resources/medication.resource.ts +241 -37
- package/src/in-patient/labourCareGuide/resources/shared-decision-making.resource.ts +37 -3
- package/src/in-patient/labourCareGuide/resources/supportive-care.resource.ts +53 -5
- package/src/in-patient/labourCareGuide/storage/lcg-local-storage.ts +374 -0
- package/src/in-patient/labourCareGuide/time-slot-utils.ts +180 -26
- package/src/in-patient/labourCareGuide/types/concept-uuids.constants.ts +21 -0
- package/src/in-patient/labourCareGuide/types/index.ts +31 -7
- package/src/index.ts +17 -0
- package/src/routes.json +20 -0
- package/src/ward-patients/ward-patients-slots.ts +21 -0
- package/src/ward-patients/ward-patients-table.test.tsx +58 -0
- package/src/ward-patients/ward-patients-table.tsx +25 -8
- package/translations/en.json +56 -15
- package/translations/fr.json +57 -15
- package/.turbo/turbo-build.log +0 -8
- package/dist/1084.js +0 -1
- package/dist/1084.js.map +0 -1
- package/dist/1189.js +0 -1
- package/dist/1189.js.map +0 -1
- package/dist/12.js +0 -17
- package/dist/12.js.map +0 -1
- package/dist/126.js +0 -1
- package/dist/1308.js +0 -1
- package/dist/1308.js.map +0 -1
- package/dist/1374.js +0 -1
- package/dist/1374.js.map +0 -1
- package/dist/1387.js +0 -1
- package/dist/1387.js.map +0 -1
- package/dist/15.js +0 -1
- package/dist/1564.js +0 -1
- package/dist/1567.js +0 -1
- package/dist/1567.js.map +0 -1
- package/dist/1739.js +0 -1
- package/dist/1739.js.map +0 -1
- package/dist/1845.js +0 -1
- package/dist/1972.js +0 -1
- package/dist/1972.js.map +0 -1
- package/dist/2016.js +0 -1
- package/dist/2016.js.map +0 -1
- package/dist/2117.js +0 -1
- package/dist/2117.js.map +0 -1
- package/dist/215.js +0 -1
- package/dist/2178.js +0 -1
- package/dist/239.js +0 -1
- package/dist/239.js.map +0 -1
- package/dist/2486.js +0 -1
- package/dist/2486.js.map +0 -1
- package/dist/2566.js +0 -1
- package/dist/2710.js +0 -1
- package/dist/2710.js.map +0 -1
- package/dist/2759.js +0 -1
- package/dist/2823.js +0 -15
- package/dist/2823.js.map +0 -1
- package/dist/3089.js +0 -1
- package/dist/3089.js.map +0 -1
- package/dist/3230.js +0 -1
- package/dist/3261.js +0 -1
- package/dist/3261.js.map +0 -1
- package/dist/3321.js +0 -1
- package/dist/3321.js.map +0 -1
- package/dist/3350.js +0 -1
- package/dist/3399.js +0 -1
- package/dist/3399.js.map +0 -1
- package/dist/3441.js +0 -1
- package/dist/3547.js +0 -1
- package/dist/3547.js.map +0 -1
- package/dist/3548.js +0 -1
- package/dist/3548.js.map +0 -1
- package/dist/3565.js +0 -1
- package/dist/3571.js +0 -1
- package/dist/3571.js.map +0 -1
- package/dist/364.js +0 -1
- package/dist/364.js.map +0 -1
- package/dist/3746.js +0 -1
- package/dist/3925.js +0 -1
- package/dist/3946.js +0 -1
- package/dist/401.js +0 -1
- package/dist/401.js.map +0 -1
- package/dist/4032.js +0 -1
- package/dist/4032.js.map +0 -1
- package/dist/4206.js +0 -1
- package/dist/4206.js.map +0 -1
- package/dist/4480.js +0 -1
- package/dist/4480.js.map +0 -1
- package/dist/4635.js +0 -1
- package/dist/4635.js.map +0 -1
- package/dist/4684.js +0 -1
- package/dist/4684.js.map +0 -1
- package/dist/4735.js +0 -1
- package/dist/4735.js.map +0 -1
- package/dist/4744.js +0 -1
- package/dist/4744.js.map +0 -1
- package/dist/4894.js +0 -1
- package/dist/4970.js +0 -1
- package/dist/4970.js.map +0 -1
- package/dist/5069.js +0 -1
- package/dist/5069.js.map +0 -1
- package/dist/5090.js +0 -1
- package/dist/5090.js.map +0 -1
- package/dist/5130.js +0 -1
- package/dist/5187.js +0 -1
- package/dist/5411.js +0 -1
- package/dist/5411.js.map +0 -1
- package/dist/5441.js +0 -1
- package/dist/5441.js.map +0 -1
- package/dist/5491.js +0 -1
- package/dist/5491.js.map +0 -1
- package/dist/5496.js +0 -1
- package/dist/5496.js.map +0 -1
- package/dist/5595.js +0 -1
- package/dist/5659.js +0 -1
- package/dist/5659.js.map +0 -1
- package/dist/5706.js +0 -1
- package/dist/5706.js.map +0 -1
- package/dist/5961.js +0 -1
- package/dist/6061.js +0 -1
- package/dist/6061.js.map +0 -1
- package/dist/6133.js +0 -1
- package/dist/6180.js +0 -1
- package/dist/6180.js.map +0 -1
- package/dist/6296.js +0 -1
- package/dist/6296.js.map +0 -1
- package/dist/6322.js +0 -1
- package/dist/6322.js.map +0 -1
- package/dist/6381.js +0 -1
- package/dist/6381.js.map +0 -1
- package/dist/6455.js +0 -1
- package/dist/6455.js.map +0 -1
- package/dist/6456.js +0 -1
- package/dist/6466.js +0 -1
- package/dist/6613.js +0 -1
- package/dist/6783.js +0 -1
- package/dist/6925.js +0 -1
- package/dist/6925.js.map +0 -1
- package/dist/7091.js +0 -1
- package/dist/7091.js.map +0 -1
- package/dist/7263.js +0 -1
- package/dist/7263.js.map +0 -1
- package/dist/7348.js +0 -1
- package/dist/7431.js +0 -1
- package/dist/7431.js.map +0 -1
- package/dist/7543.js +0 -1
- package/dist/7607.js +0 -1
- package/dist/762.js +0 -1
- package/dist/762.js.map +0 -1
- package/dist/772.js +0 -1
- package/dist/775.js +0 -1
- package/dist/775.js.map +0 -1
- package/dist/8171.js +0 -1
- package/dist/8171.js.map +0 -1
- package/dist/8488.js +0 -1
- package/dist/8488.js.map +0 -1
- package/dist/8727.js +0 -1
- package/dist/8736.js +0 -1
- package/dist/8736.js.map +0 -1
- package/dist/8847.js +0 -1
- package/dist/9009.js +0 -1
- package/dist/9009.js.map +0 -1
- package/dist/9015.js +0 -1
- package/dist/906.js +0 -1
- package/dist/9065.js +0 -1
- package/dist/9182.js +0 -1
- package/dist/9314.js +0 -1
- package/dist/9314.js.map +0 -1
- package/dist/9339.js +0 -1
- package/dist/9361.js +0 -1
- package/dist/9361.js.map +0 -1
- package/dist/9453.js +0 -1
- package/dist/9465.js +0 -1
- package/dist/9465.js.map +0 -1
- package/dist/9535.js +0 -22
- package/dist/9535.js.map +0 -1
- package/dist/9610.js +0 -1
- package/dist/9610.js.map +0 -1
- package/dist/9668.js +0 -1
- package/dist/9668.js.map +0 -1
- package/dist/9727.js +0 -1
- package/dist/9727.js.map +0 -1
- package/dist/9734.js +0 -1
- package/dist/9734.js.map +0 -1
- package/dist/9833.js +0 -1
- package/dist/9833.js.map +0 -1
- package/dist/9848.js +0 -1
- package/dist/9848.js.map +0 -1
- package/dist/9876.js +0 -1
- package/dist/9876.js.map +0 -1
- package/dist/9920.js +0 -1
- package/dist/9938.js +0 -1
- package/dist/kenyaemr-esm-ward-app.js +0 -5
- package/dist/kenyaemr-esm-ward-app.js.buildmanifest.json +0 -2723
- package/dist/kenyaemr-esm-ward-app.js.map +0 -1
- package/dist/main.js +0 -5
- package/dist/main.js.map +0 -1
- package/dist/routes.json +0 -1
package/README.md
CHANGED
|
@@ -22,6 +22,37 @@ Please see the [EMR API README](https://github.com/openmrs/openmrs-module-emrapi
|
|
|
22
22
|
|
|
23
23
|
See the [config-schema](./src/config-schema.ts) for details on the configuration options available to the ward app.
|
|
24
24
|
|
|
25
|
+
## Ward Patient Table Tab Extension Slots
|
|
26
|
+
|
|
27
|
+
The default ward table view renders four fixed tabs (Awaiting Admission, Admitted, Discharge In, Discharged). Each tab panel is backed by an extension slot so implementers can replace the default table UI without forking the ward app.
|
|
28
|
+
|
|
29
|
+
| Tab | Slot name | Default extension name |
|
|
30
|
+
|-----|-----------|------------------------|
|
|
31
|
+
| Awaiting Admission | `ward-patients-awaiting-admission-slot` | `ward-patients-awaiting-admission` |
|
|
32
|
+
| Admitted | `ward-patients-admitted-slot` | `ward-patients-admitted` |
|
|
33
|
+
| Discharge In | `ward-patients-discharge-in-slot` | `ward-patients-discharge-in` |
|
|
34
|
+
| Discharged | `ward-patients-discharged-slot` | `ward-patients-discharged` |
|
|
35
|
+
|
|
36
|
+
### Custom component requirements
|
|
37
|
+
|
|
38
|
+
- Render under `DefaultWardView` so `useAppContext('ward-view-context')` provides ward patient data.
|
|
39
|
+
- Reuse types from [`src/types/index.ts`](./src/types/index.ts): `WardViewContext`, `WardPatient`, etc.
|
|
40
|
+
- Optional shared UI helpers: `HyperLinkPatientCell`, `EmptyState`, `ErrorState`, `getOpenmrsId`.
|
|
41
|
+
|
|
42
|
+
### Replacing a default table
|
|
43
|
+
|
|
44
|
+
In your module's `routes.json`, register the replacement extension:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"name": "my-custom-awaiting-admission",
|
|
49
|
+
"component": "myAwaitingAdmissionTable",
|
|
50
|
+
"slot": "ward-patients-awaiting-admission-slot"
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The default table components are exported from this module (`wardPatientsAwaitingAdmissionTable`, `wardPatientsAdmittedTable`, `wardPatientsDischargeInTable`, `wardPatientsDischargedTable`) if you need to wrap or extend them.
|
|
55
|
+
|
|
25
56
|
## Bed Management
|
|
26
57
|
|
|
27
58
|
The ward app is designed to support patient bed assignments and to be used in conjunction with the bedmanagement module and the bed-management-app ESM. However, bed management is entirely optional. Patients will appear on a ward if they:
|
package/package.json
CHANGED
package/src/config-schema.ts
CHANGED
|
@@ -45,6 +45,7 @@ export const labourCareGuideConceptUuids = {
|
|
|
45
45
|
UUID_URINE_ONE_PLUS: '1362AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
46
46
|
UUID_URINE_TWO_PLUS: '1363AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
47
47
|
UUID_URINE_THREE_PLUS: '1364AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
48
|
+
UUID_URINE_NOT_DONE: '1118AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
48
49
|
UUID_URINE_TEST_TIME_SLOT: 'bb3724c9-fbcc-49c5-9702-6cde0be325ca',
|
|
49
50
|
UUID_PARTOGRAPHY_ENCOUNTER: '022d62af-e2a5-4282-953b-52dd5cba3296',
|
|
50
51
|
UUID_MEDICATION_OXYTOCIN_ADMINISTERED: '82580974-ff46-41c5-b218-4bea7f53bf7e',
|
|
@@ -83,6 +84,19 @@ export const labourCareGuideConceptUuids = {
|
|
|
83
84
|
UUID_URGE_TO_PUSH: '9ad5b56d-597c-4a40-ade6-387802daa44a',
|
|
84
85
|
UUID_EMERGENCY_OVERRIDE: '1670AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
85
86
|
UUID_EMERGENCY_REASON: '163761AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
87
|
+
UUID_SHARED_DECISION_TERMINATE_ONGOING_PROGRESS: '737fa73a-509f-40d8-9e84-91dc71db7f4c',
|
|
88
|
+
UUID_LCG_TERMINATION_REASON_TYPE: '6098AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
89
|
+
UUID_LCG_TERMINATION_REASON_WRONG_PATIENT: '164144AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
90
|
+
UUID_LCG_TERMINATION_REASON_OTHER: '5622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
91
|
+
UUID_LCG_CORRECTION_ENCOUNTER_TYPE: 'b2c4d5e6-7f8a-4e9b-8c1d-2e3f8e4a3b8f',
|
|
92
|
+
UUID_LCG_CORRECTION_TYPE: '4b3eb27b-43c0-4862-bd83-be06beb3d699',
|
|
93
|
+
UUID_LCG_CORRECTION_TYPE_WRONG_PATIENT_TRANSFER: '1286AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
94
|
+
UUID_LCG_CORRECTION_SOURCE_PATIENT_UUID: '162720AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
95
|
+
UUID_LCG_CORRECTION_SOURCE_TERMINATE_ENCOUNTER_UUID: '1671AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
96
|
+
UUID_LCG_CORRECTION_TERMINATION_REASON: '162704AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
97
|
+
UUID_LCG_CORRECTION_SOURCE_PATIENT_DISPLAY: '850a960b-e8b5-4775-ba74-aaddb2abbf51',
|
|
98
|
+
UUID_LCG_CORRECTION_TERMINATED_AT: '163286AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
99
|
+
UUID_LCG_CORRECTION_TRANSFER_NOTES: '1056dc03-ce4d-45cb-a1eb-87707162e6ee',
|
|
86
100
|
FETAL_HEART_RATE_CONCEPT: '1440AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
87
101
|
FETAL_HEART_RATE_TIME_CONCEPT: 'bb3724c9-fbcc-49c5-9702-6cde0be325ca',
|
|
88
102
|
FETAL_HEART_RATE_HOUR_CONCEPT: '160632AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
@@ -98,7 +112,7 @@ export const labourCareGuideConceptUuids = {
|
|
|
98
112
|
CONTRACTION_LEVEL_MODERATE_CONCEPT: '1499AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
99
113
|
CONTRACTION_LEVEL_STRONG_CONCEPT: '166788AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
100
114
|
UTERINE_CONTRACTION_FREQUENCY_CONCEPT: 'd266dee4-bbe8-4736-b94d-c33300f55bca',
|
|
101
|
-
UTERINE_CONTRACTION_DURATION_CONCEPT: '
|
|
115
|
+
UTERINE_CONTRACTION_DURATION_CONCEPT: '159368AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
102
116
|
OXYTOCIN_TIME_CONCEPT: 'bb3724c9-fbcc-49c5-9702-6cde0be325ca',
|
|
103
117
|
OXYTOCIN_DROPS_PER_MINUTE_CONCEPT: '1d109b10-7b30-4bfa-8a7c-6ecb73357fc2',
|
|
104
118
|
OXYTOCIN_DOSE_CONCEPT: '81369AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
@@ -920,6 +934,11 @@ export const configSchema: ConfigSchema = {
|
|
|
920
934
|
_description: 'Labour care guide partography module configuration',
|
|
921
935
|
_default: labourCareGuidePartographyConfig,
|
|
922
936
|
},
|
|
937
|
+
lcgSessionCorrectionPrivilege: {
|
|
938
|
+
_type: Type.String,
|
|
939
|
+
_description: 'OpenMRS privilege required to open the LCG wrong-patient correction wizard',
|
|
940
|
+
_default: 'Correct LCG Wrong Patient',
|
|
941
|
+
},
|
|
923
942
|
} as const;
|
|
924
943
|
|
|
925
944
|
export interface WardConfigObject {
|
|
@@ -1030,6 +1049,7 @@ export interface WardConfigObject {
|
|
|
1030
1049
|
treatmentChartNameConceptUuid: string;
|
|
1031
1050
|
treatmentChartTimeConceptUuid: string;
|
|
1032
1051
|
partography: LabourCareGuidePartographyConfig;
|
|
1052
|
+
lcgSessionCorrectionPrivilege: string;
|
|
1033
1053
|
}
|
|
1034
1054
|
export interface PendingItemsElementConfig {
|
|
1035
1055
|
id: string;
|
|
@@ -29,13 +29,15 @@ export const isSupportiveAlertValue = (rowKey: SupportiveAlertKey, rawValue: str
|
|
|
29
29
|
return false;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
const isNoValue = value === 'N' || value === 'NO' || value.includes('1066');
|
|
33
|
+
|
|
32
34
|
switch (rowKey) {
|
|
33
35
|
case 'posture':
|
|
34
|
-
return value === 'SP';
|
|
36
|
+
return value === 'SP' || value.includes('SUPINE');
|
|
35
37
|
case 'companion':
|
|
36
38
|
case 'painRelief':
|
|
37
39
|
case 'oralFluid':
|
|
38
|
-
return
|
|
40
|
+
return isNoValue;
|
|
39
41
|
default:
|
|
40
42
|
return false;
|
|
41
43
|
}
|
|
@@ -190,9 +192,16 @@ export const isBabyAlertValue = (rowKey: BabyAlertKey, rawValue: string) => {
|
|
|
190
192
|
return Number.isFinite(numericValue) && (numericValue < 110 || numericValue >= 160);
|
|
191
193
|
}
|
|
192
194
|
case 'fhrDeceleration':
|
|
193
|
-
return value === 'L';
|
|
195
|
+
return value === 'L' || value.includes('LATE');
|
|
194
196
|
case 'amnioticFluid':
|
|
195
|
-
return
|
|
197
|
+
return (
|
|
198
|
+
value === 'B' ||
|
|
199
|
+
value === 'M' ||
|
|
200
|
+
value === 'M+' ||
|
|
201
|
+
value === 'M++' ||
|
|
202
|
+
value === 'M+++' ||
|
|
203
|
+
value.startsWith('M+')
|
|
204
|
+
);
|
|
196
205
|
case 'fetalPosition':
|
|
197
206
|
return value === 'P' || value === 'T';
|
|
198
207
|
case 'caput':
|
|
@@ -464,3 +473,87 @@ export const getCervixStallTokenGuidance = (t: TFunction, token: string): string
|
|
|
464
473
|
);
|
|
465
474
|
return t('cervixStallTokenGuidancePlaceholder', 'Labour progress alert: review and act.');
|
|
466
475
|
};
|
|
476
|
+
|
|
477
|
+
// ─── Shared Decision Making assessment prefill ───────────────────────────────
|
|
478
|
+
|
|
479
|
+
export type SharedDecisionAlertItem = {
|
|
480
|
+
id?: string;
|
|
481
|
+
section: string;
|
|
482
|
+
code: string;
|
|
483
|
+
guidance: string;
|
|
484
|
+
timestampCreatedMs?: number;
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
export type SharedDecisionAssessmentLine = {
|
|
488
|
+
label: string;
|
|
489
|
+
comment: string;
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
export const formatAlertItemAsAssessmentLabel = (item: SharedDecisionAlertItem): string => {
|
|
493
|
+
const code = String(item.code ?? '').trim();
|
|
494
|
+
if (!code) {
|
|
495
|
+
return '';
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
const parenMatch = code.match(/^(.+?)\s+\((.+)\)$/);
|
|
499
|
+
if (parenMatch) {
|
|
500
|
+
return `${parenMatch[2].trim()} ${parenMatch[1].trim()}`;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
const guidancePrefix = item.guidance.match(/^([^:\n]+):/);
|
|
504
|
+
if (guidancePrefix?.[1]) {
|
|
505
|
+
return guidancePrefix[1].trim();
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
return code;
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
export const buildAssessmentPrefillFromAlerts = (items: SharedDecisionAlertItem[]): string => {
|
|
512
|
+
const seen = new Set<string>();
|
|
513
|
+
const lines: string[] = [];
|
|
514
|
+
|
|
515
|
+
for (const item of items) {
|
|
516
|
+
if (!item?.code) {
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const label = formatAlertItemAsAssessmentLabel(item);
|
|
521
|
+
const dedupeKey = label.toLowerCase();
|
|
522
|
+
if (!label || seen.has(dedupeKey)) {
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
seen.add(dedupeKey);
|
|
527
|
+
lines.push(`${label}: `);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
return lines.join('\n');
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
export const parseAssessmentValue = (value: string): SharedDecisionAssessmentLine[] => {
|
|
534
|
+
if (!value.trim()) {
|
|
535
|
+
return [];
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
return value
|
|
539
|
+
.split('\n')
|
|
540
|
+
.map((line) => {
|
|
541
|
+
const colonIndex = line.indexOf(':');
|
|
542
|
+
if (colonIndex === -1) {
|
|
543
|
+
return { label: line.trim(), comment: '' };
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return {
|
|
547
|
+
label: line.slice(0, colonIndex).trim(),
|
|
548
|
+
comment: line.slice(colonIndex + 1).replace(/^\s/, ''),
|
|
549
|
+
};
|
|
550
|
+
})
|
|
551
|
+
.filter((line) => line.label);
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
export const serializeAssessmentLines = (lines: SharedDecisionAssessmentLine[]): string => {
|
|
555
|
+
return lines
|
|
556
|
+
.map(({ label, comment }) => (label ? `${label}: ${comment}` : ''))
|
|
557
|
+
.filter(Boolean)
|
|
558
|
+
.join('\n');
|
|
559
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { InlineNotification } from '@carbon/react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import {
|
|
5
|
+
formatCorrectionAuditSubtitle,
|
|
6
|
+
type LcgCorrectionAuditRecord,
|
|
7
|
+
} from '../resources/lcg-session-correction.resource';
|
|
8
|
+
import styles from '../labour-care-guide.scss';
|
|
9
|
+
|
|
10
|
+
type LcgCorrectionAuditBannerProps = {
|
|
11
|
+
auditRecord?: LcgCorrectionAuditRecord | null;
|
|
12
|
+
variant?: 'chart' | 'sdm' | 'form';
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const LcgCorrectionAuditBanner: React.FC<LcgCorrectionAuditBannerProps> = ({ auditRecord, variant = 'sdm' }) => {
|
|
16
|
+
const { t } = useTranslation();
|
|
17
|
+
|
|
18
|
+
if (!auditRecord) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const subtitle = formatCorrectionAuditSubtitle(auditRecord);
|
|
23
|
+
const title =
|
|
24
|
+
variant === 'chart'
|
|
25
|
+
? t('lcgAuditChartTitle', 'Session corrected — data transferred from wrong chart')
|
|
26
|
+
: t('lcgAuditSdmTitle', 'Shared Decision Making — transferred session audit');
|
|
27
|
+
|
|
28
|
+
const bannerClassName =
|
|
29
|
+
variant === 'form'
|
|
30
|
+
? styles.correctionAuditBannerForm
|
|
31
|
+
: variant === 'chart'
|
|
32
|
+
? styles.correctionAuditBannerChart
|
|
33
|
+
: styles.correctionAuditBanner;
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div className={bannerClassName}>
|
|
37
|
+
<InlineNotification kind="warning" lowContrast hideCloseButton title={title} subtitle={subtitle} />
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default LcgCorrectionAuditBanner;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const LCG_LABOUR_ONSET_CODE = {
|
|
2
|
+
spontaneous: 'spontaneous',
|
|
3
|
+
induction: 'induction',
|
|
4
|
+
preLabourCsection: 'preLabourCsection',
|
|
5
|
+
} as const;
|
|
6
|
+
|
|
7
|
+
export type LcgLabourOnsetCode = (typeof LCG_LABOUR_ONSET_CODE)[keyof typeof LCG_LABOUR_ONSET_CODE];
|
|
8
|
+
|
|
9
|
+
export const LCG_ADMISSION_RISK_FACTOR_CODE = {
|
|
10
|
+
chronicHypertension: 'chronicHypertension',
|
|
11
|
+
preEclampsia: 'preEclampsia',
|
|
12
|
+
advancedAge: 'advancedAge',
|
|
13
|
+
adolescentPregnancy: 'adolescentPregnancy',
|
|
14
|
+
pretermLabour: 'pretermLabour',
|
|
15
|
+
multipleGestation: 'multipleGestation',
|
|
16
|
+
colonization: 'colonization',
|
|
17
|
+
other: 'other',
|
|
18
|
+
none: 'none',
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
export type LcgAdmissionRiskFactorCode =
|
|
22
|
+
(typeof LCG_ADMISSION_RISK_FACTOR_CODE)[keyof typeof LCG_ADMISSION_RISK_FACTOR_CODE];
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import React, { startTransition } from 'react';
|
|
2
|
+
import type { BabyEntry } from '../graphs/baby.component';
|
|
3
|
+
import type { LabourProgressEntry } from '../graphs/labour-progress.component';
|
|
4
|
+
import type { WomanLocalEntry } from '../graphs/woman.component';
|
|
5
|
+
import type { MedicationEntry } from '../resources/medication.resource';
|
|
6
|
+
import type { SupportiveCareEntry } from '../resources/supportive-care.resource';
|
|
7
|
+
import type { SharedDecisionMakingEntry } from '../resources/shared-decision-making.resource';
|
|
8
|
+
import { readLcgSectionEntries } from '../storage/lcg-local-storage';
|
|
9
|
+
import { useLcgSectionAutosave } from '../hooks/use-lcg-section-autosave';
|
|
10
|
+
|
|
11
|
+
export type LcgSectionKey =
|
|
12
|
+
| 'supportive-care'
|
|
13
|
+
| 'baby'
|
|
14
|
+
| 'woman'
|
|
15
|
+
| 'labour-progress'
|
|
16
|
+
| 'medication'
|
|
17
|
+
| 'shared-decision-making';
|
|
18
|
+
|
|
19
|
+
type SectionEntryMap = {
|
|
20
|
+
'supportive-care': SupportiveCareEntry;
|
|
21
|
+
baby: BabyEntry;
|
|
22
|
+
woman: WomanLocalEntry;
|
|
23
|
+
'labour-progress': LabourProgressEntry;
|
|
24
|
+
medication: MedicationEntry;
|
|
25
|
+
'shared-decision-making': SharedDecisionMakingEntry;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type SectionContextValue<T> = {
|
|
29
|
+
entries: T[];
|
|
30
|
+
setEntries: React.Dispatch<React.SetStateAction<T[]>>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function useTransitionBackedEntries<T>(initializer: () => T[]) {
|
|
34
|
+
const [entries, setEntriesState] = React.useState(initializer);
|
|
35
|
+
const setEntries = React.useCallback((updater: React.SetStateAction<T[]>) => {
|
|
36
|
+
startTransition(() => {
|
|
37
|
+
setEntriesState(updater);
|
|
38
|
+
});
|
|
39
|
+
}, []);
|
|
40
|
+
|
|
41
|
+
return [entries, setEntries] as const;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const SupportiveCareSectionContext = React.createContext<SectionContextValue<SupportiveCareEntry> | null>(null);
|
|
45
|
+
const BabySectionContext = React.createContext<SectionContextValue<BabyEntry> | null>(null);
|
|
46
|
+
const WomanSectionContext = React.createContext<SectionContextValue<WomanLocalEntry> | null>(null);
|
|
47
|
+
const LabourProgressSectionContext = React.createContext<SectionContextValue<LabourProgressEntry> | null>(null);
|
|
48
|
+
const MedicationSectionContext = React.createContext<SectionContextValue<MedicationEntry> | null>(null);
|
|
49
|
+
const SharedDecisionSectionContext = React.createContext<SectionContextValue<SharedDecisionMakingEntry> | null>(null);
|
|
50
|
+
|
|
51
|
+
const missingProviderError = 'useLcgSectionState must be used within LcgSectionStateProvider';
|
|
52
|
+
|
|
53
|
+
function hydrateSectionEntries<T>(patientUuid: string, section: LcgSectionKey): T[] {
|
|
54
|
+
if (!patientUuid) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return readLcgSectionEntries<T>(patientUuid, section);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function SectionAutosaveBridge<T>({
|
|
62
|
+
patientUuid,
|
|
63
|
+
section,
|
|
64
|
+
entries,
|
|
65
|
+
}: {
|
|
66
|
+
patientUuid: string;
|
|
67
|
+
section: LcgSectionKey;
|
|
68
|
+
entries: T[];
|
|
69
|
+
}) {
|
|
70
|
+
useLcgSectionAutosave(patientUuid, section, entries);
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export type LcgSectionStateProviderProps = {
|
|
75
|
+
patientUuid: string;
|
|
76
|
+
children: React.ReactNode;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const LcgSectionStateProvider: React.FC<LcgSectionStateProviderProps> = ({ patientUuid, children }) => {
|
|
80
|
+
const [supportiveCareEntries, setSupportiveCareEntries] = useTransitionBackedEntries<SupportiveCareEntry>(() =>
|
|
81
|
+
hydrateSectionEntries<SupportiveCareEntry>(patientUuid, 'supportive-care'),
|
|
82
|
+
);
|
|
83
|
+
const [babyEntries, setBabyEntries] = useTransitionBackedEntries<BabyEntry>(() =>
|
|
84
|
+
hydrateSectionEntries<BabyEntry>(patientUuid, 'baby'),
|
|
85
|
+
);
|
|
86
|
+
const [womanEntries, setWomanEntries] = useTransitionBackedEntries<WomanLocalEntry>(() =>
|
|
87
|
+
hydrateSectionEntries<WomanLocalEntry>(patientUuid, 'woman'),
|
|
88
|
+
);
|
|
89
|
+
const [labourProgressEntries, setLabourProgressEntries] = useTransitionBackedEntries<LabourProgressEntry>(() =>
|
|
90
|
+
hydrateSectionEntries<LabourProgressEntry>(patientUuid, 'labour-progress'),
|
|
91
|
+
);
|
|
92
|
+
const [medicationEntries, setMedicationEntries] = useTransitionBackedEntries<MedicationEntry>(() =>
|
|
93
|
+
hydrateSectionEntries<MedicationEntry>(patientUuid, 'medication'),
|
|
94
|
+
);
|
|
95
|
+
const [sharedDecisionEntries, setSharedDecisionEntries] = useTransitionBackedEntries<SharedDecisionMakingEntry>(() =>
|
|
96
|
+
hydrateSectionEntries<SharedDecisionMakingEntry>(patientUuid, 'shared-decision-making'),
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
React.useEffect(() => {
|
|
100
|
+
startTransition(() => {
|
|
101
|
+
setSupportiveCareEntries(hydrateSectionEntries<SupportiveCareEntry>(patientUuid, 'supportive-care'));
|
|
102
|
+
setBabyEntries(hydrateSectionEntries<BabyEntry>(patientUuid, 'baby'));
|
|
103
|
+
setWomanEntries(hydrateSectionEntries<WomanLocalEntry>(patientUuid, 'woman'));
|
|
104
|
+
setLabourProgressEntries(hydrateSectionEntries<LabourProgressEntry>(patientUuid, 'labour-progress'));
|
|
105
|
+
setMedicationEntries(hydrateSectionEntries<MedicationEntry>(patientUuid, 'medication'));
|
|
106
|
+
setSharedDecisionEntries(hydrateSectionEntries<SharedDecisionMakingEntry>(patientUuid, 'shared-decision-making'));
|
|
107
|
+
});
|
|
108
|
+
}, [
|
|
109
|
+
patientUuid,
|
|
110
|
+
setBabyEntries,
|
|
111
|
+
setLabourProgressEntries,
|
|
112
|
+
setMedicationEntries,
|
|
113
|
+
setSharedDecisionEntries,
|
|
114
|
+
setSupportiveCareEntries,
|
|
115
|
+
setWomanEntries,
|
|
116
|
+
]);
|
|
117
|
+
|
|
118
|
+
const supportiveCareValue = React.useMemo(
|
|
119
|
+
() => ({ entries: supportiveCareEntries, setEntries: setSupportiveCareEntries }),
|
|
120
|
+
[supportiveCareEntries, setSupportiveCareEntries],
|
|
121
|
+
);
|
|
122
|
+
const babyValue = React.useMemo(
|
|
123
|
+
() => ({ entries: babyEntries, setEntries: setBabyEntries }),
|
|
124
|
+
[babyEntries, setBabyEntries],
|
|
125
|
+
);
|
|
126
|
+
const womanValue = React.useMemo(
|
|
127
|
+
() => ({ entries: womanEntries, setEntries: setWomanEntries }),
|
|
128
|
+
[womanEntries, setWomanEntries],
|
|
129
|
+
);
|
|
130
|
+
const labourProgressValue = React.useMemo(
|
|
131
|
+
() => ({ entries: labourProgressEntries, setEntries: setLabourProgressEntries }),
|
|
132
|
+
[labourProgressEntries, setLabourProgressEntries],
|
|
133
|
+
);
|
|
134
|
+
const medicationValue = React.useMemo(
|
|
135
|
+
() => ({ entries: medicationEntries, setEntries: setMedicationEntries }),
|
|
136
|
+
[medicationEntries, setMedicationEntries],
|
|
137
|
+
);
|
|
138
|
+
const sharedDecisionValue = React.useMemo(
|
|
139
|
+
() => ({ entries: sharedDecisionEntries, setEntries: setSharedDecisionEntries }),
|
|
140
|
+
[sharedDecisionEntries, setSharedDecisionEntries],
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<SupportiveCareSectionContext.Provider value={supportiveCareValue}>
|
|
145
|
+
<BabySectionContext.Provider value={babyValue}>
|
|
146
|
+
<WomanSectionContext.Provider value={womanValue}>
|
|
147
|
+
<LabourProgressSectionContext.Provider value={labourProgressValue}>
|
|
148
|
+
<MedicationSectionContext.Provider value={medicationValue}>
|
|
149
|
+
<SharedDecisionSectionContext.Provider value={sharedDecisionValue}>
|
|
150
|
+
<SectionAutosaveBridge
|
|
151
|
+
patientUuid={patientUuid}
|
|
152
|
+
section="supportive-care"
|
|
153
|
+
entries={supportiveCareEntries}
|
|
154
|
+
/>
|
|
155
|
+
<SectionAutosaveBridge patientUuid={patientUuid} section="baby" entries={babyEntries} />
|
|
156
|
+
<SectionAutosaveBridge patientUuid={patientUuid} section="woman" entries={womanEntries} />
|
|
157
|
+
<SectionAutosaveBridge
|
|
158
|
+
patientUuid={patientUuid}
|
|
159
|
+
section="labour-progress"
|
|
160
|
+
entries={labourProgressEntries}
|
|
161
|
+
/>
|
|
162
|
+
<SectionAutosaveBridge patientUuid={patientUuid} section="medication" entries={medicationEntries} />
|
|
163
|
+
<SectionAutosaveBridge
|
|
164
|
+
patientUuid={patientUuid}
|
|
165
|
+
section="shared-decision-making"
|
|
166
|
+
entries={sharedDecisionEntries}
|
|
167
|
+
/>
|
|
168
|
+
{children}
|
|
169
|
+
</SharedDecisionSectionContext.Provider>
|
|
170
|
+
</MedicationSectionContext.Provider>
|
|
171
|
+
</LabourProgressSectionContext.Provider>
|
|
172
|
+
</WomanSectionContext.Provider>
|
|
173
|
+
</BabySectionContext.Provider>
|
|
174
|
+
</SupportiveCareSectionContext.Provider>
|
|
175
|
+
);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export function useLcgSectionState<K extends LcgSectionKey>(section: K): SectionContextValue<SectionEntryMap[K]> {
|
|
179
|
+
const supportiveCareContext = React.useContext(SupportiveCareSectionContext);
|
|
180
|
+
const babyContext = React.useContext(BabySectionContext);
|
|
181
|
+
const womanContext = React.useContext(WomanSectionContext);
|
|
182
|
+
const labourProgressContext = React.useContext(LabourProgressSectionContext);
|
|
183
|
+
const medicationContext = React.useContext(MedicationSectionContext);
|
|
184
|
+
const sharedDecisionContext = React.useContext(SharedDecisionSectionContext);
|
|
185
|
+
|
|
186
|
+
switch (section) {
|
|
187
|
+
case 'supportive-care': {
|
|
188
|
+
if (!supportiveCareContext) {
|
|
189
|
+
throw new Error(missingProviderError);
|
|
190
|
+
}
|
|
191
|
+
return supportiveCareContext as SectionContextValue<SectionEntryMap[K]>;
|
|
192
|
+
}
|
|
193
|
+
case 'baby': {
|
|
194
|
+
if (!babyContext) {
|
|
195
|
+
throw new Error(missingProviderError);
|
|
196
|
+
}
|
|
197
|
+
return babyContext as SectionContextValue<SectionEntryMap[K]>;
|
|
198
|
+
}
|
|
199
|
+
case 'woman': {
|
|
200
|
+
if (!womanContext) {
|
|
201
|
+
throw new Error(missingProviderError);
|
|
202
|
+
}
|
|
203
|
+
return womanContext as SectionContextValue<SectionEntryMap[K]>;
|
|
204
|
+
}
|
|
205
|
+
case 'labour-progress': {
|
|
206
|
+
if (!labourProgressContext) {
|
|
207
|
+
throw new Error(missingProviderError);
|
|
208
|
+
}
|
|
209
|
+
return labourProgressContext as SectionContextValue<SectionEntryMap[K]>;
|
|
210
|
+
}
|
|
211
|
+
case 'medication': {
|
|
212
|
+
if (!medicationContext) {
|
|
213
|
+
throw new Error(missingProviderError);
|
|
214
|
+
}
|
|
215
|
+
return medicationContext as SectionContextValue<SectionEntryMap[K]>;
|
|
216
|
+
}
|
|
217
|
+
case 'shared-decision-making': {
|
|
218
|
+
if (!sharedDecisionContext) {
|
|
219
|
+
throw new Error(missingProviderError);
|
|
220
|
+
}
|
|
221
|
+
return sharedDecisionContext as SectionContextValue<SectionEntryMap[K]>;
|
|
222
|
+
}
|
|
223
|
+
default: {
|
|
224
|
+
const exhaustiveCheck: never = section;
|
|
225
|
+
throw new Error(`Unsupported LCG section: ${String(exhaustiveCheck)}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export function useLcgAllSectionEntries() {
|
|
231
|
+
const supportiveCare = useLcgSectionState('supportive-care');
|
|
232
|
+
const baby = useLcgSectionState('baby');
|
|
233
|
+
const woman = useLcgSectionState('woman');
|
|
234
|
+
const labourProgress = useLcgSectionState('labour-progress');
|
|
235
|
+
const medication = useLcgSectionState('medication');
|
|
236
|
+
const sharedDecision = useLcgSectionState('shared-decision-making');
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
localSupportiveCareEntries: supportiveCare.entries,
|
|
240
|
+
setLocalSupportiveCareEntries: supportiveCare.setEntries,
|
|
241
|
+
localBabyEntries: baby.entries,
|
|
242
|
+
setLocalBabyEntries: baby.setEntries,
|
|
243
|
+
localWomanEntries: woman.entries,
|
|
244
|
+
setLocalWomanEntries: woman.setEntries,
|
|
245
|
+
localLabourProgressEntries: labourProgress.entries,
|
|
246
|
+
setLocalLabourProgressEntries: labourProgress.setEntries,
|
|
247
|
+
localMedicationEntries: medication.entries,
|
|
248
|
+
setLocalMedicationEntries: medication.setEntries,
|
|
249
|
+
localSharedDecisionMakingEntries: sharedDecision.entries,
|
|
250
|
+
setLocalSharedDecisionMakingEntries: sharedDecision.setEntries,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
import styles from '../partography-data-form.scss';
|
|
17
17
|
import { saveAdmissionDetails } from '../resources/admission-details.resource';
|
|
18
18
|
import { AdmissionDetailsTimePickerDropdown } from './form-scoped-time-pickers.component';
|
|
19
|
+
import { LCG_ADMISSION_RISK_FACTOR_CODE, LCG_LABOUR_ONSET_CODE } from '../constants/admission-form.constants';
|
|
19
20
|
|
|
20
21
|
export type AdmissionDetailsFormData = {
|
|
21
22
|
labourOnset: string;
|
|
@@ -89,22 +90,30 @@ const AdmissionDetailsForm: React.FC<AdmissionDetailsFormProps> = ({ isOpen, onC
|
|
|
89
90
|
|
|
90
91
|
const rupturedMembranesValue = watch('rupturedMembranes');
|
|
91
92
|
const riskFactorsValue = watch('riskFactors');
|
|
92
|
-
const hasOtherRiskFactor = (riskFactorsValue || []).includes(
|
|
93
|
+
const hasOtherRiskFactor = (riskFactorsValue || []).includes(LCG_ADMISSION_RISK_FACTOR_CODE.other);
|
|
93
94
|
const patientAge = React.useMemo(() => resolvePatientAge(patient), [patient]);
|
|
94
95
|
const canSelectAdolescentPregnancy = Number.isFinite(patientAge) && patientAge >= 10 && patientAge <= 19;
|
|
95
96
|
|
|
96
97
|
const riskFactorOptions = React.useMemo(
|
|
97
98
|
() =>
|
|
98
99
|
[
|
|
99
|
-
{
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
{ id:
|
|
104
|
-
{ id:
|
|
105
|
-
{
|
|
106
|
-
|
|
107
|
-
|
|
100
|
+
{
|
|
101
|
+
id: LCG_ADMISSION_RISK_FACTOR_CODE.chronicHypertension,
|
|
102
|
+
text: t('chronicHypertension', 'Chronic hypertension'),
|
|
103
|
+
},
|
|
104
|
+
{ id: LCG_ADMISSION_RISK_FACTOR_CODE.preEclampsia, text: t('preEclampsia', 'Pre-eclampsia') },
|
|
105
|
+
{ id: LCG_ADMISSION_RISK_FACTOR_CODE.advancedAge, text: t('advancedAge', "Woman's advanced age") },
|
|
106
|
+
{
|
|
107
|
+
id: LCG_ADMISSION_RISK_FACTOR_CODE.adolescentPregnancy,
|
|
108
|
+
text: t('adolescentPregnancy', 'Adolescent pregnancy'),
|
|
109
|
+
},
|
|
110
|
+
{ id: LCG_ADMISSION_RISK_FACTOR_CODE.multipleGestation, text: t('multipleGestation', 'Multiple gestation') },
|
|
111
|
+
{ id: LCG_ADMISSION_RISK_FACTOR_CODE.colonization, text: t('colonization', 'Colonization') },
|
|
112
|
+
{ id: LCG_ADMISSION_RISK_FACTOR_CODE.other, text: t('other', 'Other') },
|
|
113
|
+
{ id: LCG_ADMISSION_RISK_FACTOR_CODE.none, text: t('none', 'None') },
|
|
114
|
+
].filter(
|
|
115
|
+
(option) => option.id !== LCG_ADMISSION_RISK_FACTOR_CODE.adolescentPregnancy || canSelectAdolescentPregnancy,
|
|
116
|
+
),
|
|
108
117
|
[canSelectAdolescentPregnancy, t],
|
|
109
118
|
);
|
|
110
119
|
|
|
@@ -131,7 +140,9 @@ const AdmissionDetailsForm: React.FC<AdmissionDetailsFormProps> = ({ isOpen, onC
|
|
|
131
140
|
...data,
|
|
132
141
|
riskFactors: canSelectAdolescentPregnancy
|
|
133
142
|
? data.riskFactors
|
|
134
|
-
: (data.riskFactors || []).filter(
|
|
143
|
+
: (data.riskFactors || []).filter(
|
|
144
|
+
(riskFactor) => riskFactor !== LCG_ADMISSION_RISK_FACTOR_CODE.adolescentPregnancy,
|
|
145
|
+
),
|
|
135
146
|
};
|
|
136
147
|
const result = await saveAdmissionDetails(patientUuid, payload, t);
|
|
137
148
|
if (!result.success) {
|
|
@@ -191,9 +202,12 @@ const AdmissionDetailsForm: React.FC<AdmissionDetailsFormProps> = ({ isOpen, onC
|
|
|
191
202
|
invalid={!!fieldState.error}
|
|
192
203
|
invalidText={fieldState.error?.message}>
|
|
193
204
|
<SelectItem value="" text={t('selectOption', 'Select option')} />
|
|
194
|
-
<SelectItem value=
|
|
195
|
-
<SelectItem value=
|
|
196
|
-
<SelectItem
|
|
205
|
+
<SelectItem value={LCG_LABOUR_ONSET_CODE.spontaneous} text={t('spontaneous', 'Spontaneous')} />
|
|
206
|
+
<SelectItem value={LCG_LABOUR_ONSET_CODE.induction} text={t('induction', 'Induction')} />
|
|
207
|
+
<SelectItem
|
|
208
|
+
value={LCG_LABOUR_ONSET_CODE.preLabourCsection}
|
|
209
|
+
text={t('preLabourCsection', 'Pre-labour C-section')}
|
|
210
|
+
/>
|
|
197
211
|
</Select>
|
|
198
212
|
)}
|
|
199
213
|
/>
|