@openmrs/esm-form-engine-lib 2.1.0-pre.1585 → 2.1.0-pre.1597
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/package.json +1 -1
- package/src/adapters/obs-adapter.ts +1 -1
- package/src/api/index.ts +8 -5
- package/src/components/renderer/field/fieldLogic.ts +40 -33
- package/src/hooks/useEvaluateFormFieldExpressions.ts +10 -1
- package/src/types/domain.ts +74 -14
- package/src/utils/form-helper.test.ts +158 -4
- package/src/utils/form-helper.ts +72 -13
- package/083bcecacf9ae0b3/083bcecacf9ae0b3.gz +0 -0
- package/1bdd6eb63dcfc148/1bdd6eb63dcfc148.gz +0 -0
- package/5a22470d28efd31b/5a22470d28efd31b.gz +0 -0
- package/bfdd668cd7e4ec20/bfdd668cd7e4ec20.gz +0 -0
package/package.json
CHANGED
@@ -83,7 +83,7 @@ export const ObsAdapter: FormFieldValueAdapter = {
|
|
83
83
|
return null;
|
84
84
|
}
|
85
85
|
if (hasRendering(field, 'checkbox')) {
|
86
|
-
return handleMultiSelect(field, value);
|
86
|
+
return handleMultiSelect(field, Array.isArray(value) ? value : [value]);
|
87
87
|
}
|
88
88
|
if (!isEmpty(value) && hasPreviousObsValueChanged(field, value)) {
|
89
89
|
return gracefullySetSubmission(field, editObs(field, value), undefined);
|
package/src/api/index.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { fhirBaseUrl, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
2
2
|
import { encounterRepresentation } from '../constants';
|
3
|
-
import {
|
3
|
+
import type { FHIRObsResource, OpenmrsForm, PatientIdentifier, PatientProgramPayload } from '../types';
|
4
4
|
import { isUuid } from '../utils/boolean-utils';
|
5
5
|
|
6
6
|
export function saveEncounter(abortController: AbortController, payload, encounterUuid?: string) {
|
@@ -76,15 +76,18 @@ export async function getPreviousEncounter(patientUuid: string, encounterType: s
|
|
76
76
|
return null;
|
77
77
|
}
|
78
78
|
|
79
|
-
export function getLatestObs(
|
79
|
+
export async function getLatestObs(
|
80
|
+
patientUuid: string,
|
81
|
+
conceptUuid: string,
|
82
|
+
encounterTypeUuid?: string,
|
83
|
+
): Promise<FHIRObsResource> {
|
80
84
|
let params = `patient=${patientUuid}&code=${conceptUuid}${
|
81
85
|
encounterTypeUuid ? `&encounter.type=${encounterTypeUuid}` : ''
|
82
86
|
}`;
|
83
87
|
// the latest obs
|
84
88
|
params += '&_sort=-date&_count=1';
|
85
|
-
|
86
|
-
|
87
|
-
});
|
89
|
+
const { data } = await openmrsFetch(`${fhirBaseUrl}/Observation?${params}`);
|
90
|
+
return data.entry?.length ? data.entry[0].resource : null;
|
88
91
|
}
|
89
92
|
|
90
93
|
/**
|
@@ -64,30 +64,40 @@ function evaluateFieldDependents(field: FormField, values: any, context: FormCon
|
|
64
64
|
mode: sessionMode,
|
65
65
|
patient,
|
66
66
|
},
|
67
|
-
)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
67
|
+
)
|
68
|
+
.then((result) => {
|
69
|
+
setValue(dependent.id, result);
|
70
|
+
// validate calculated value
|
71
|
+
const { errors, warnings } = validateFieldValue(dependent, result, context.formFieldValidators, {
|
72
|
+
formFields,
|
73
|
+
values,
|
74
|
+
expressionContext: { patient, mode: sessionMode },
|
75
|
+
});
|
76
|
+
if (!dependent.meta.submission) {
|
77
|
+
dependent.meta.submission = {};
|
78
|
+
}
|
79
|
+
dependent.meta.submission.errors = errors;
|
80
|
+
dependent.meta.submission.warnings = warnings;
|
81
|
+
if (!errors.length) {
|
82
|
+
context.formFieldAdapters[dependent.type].transformFieldValue(dependent, result, context);
|
83
|
+
}
|
84
|
+
updateFormField(dependent);
|
85
|
+
})
|
86
|
+
.catch((error) => {
|
87
|
+
reportError(error, 'Error evaluating calculate expression');
|
74
88
|
});
|
75
|
-
if (!dependent.meta.submission) {
|
76
|
-
dependent.meta.submission = {};
|
77
|
-
}
|
78
|
-
dependent.meta.submission.errors = errors;
|
79
|
-
dependent.meta.submission.warnings = warnings;
|
80
|
-
if (!errors.length) {
|
81
|
-
context.formFieldAdapters[dependent.type].transformFieldValue(dependent, result, context);
|
82
|
-
}
|
83
|
-
updateFormField(dependent);
|
84
|
-
}).catch((error) => {
|
85
|
-
reportError(error, 'Error evaluating calculate expression');
|
86
|
-
});
|
87
89
|
}
|
88
90
|
// evaluate hide
|
89
91
|
if (dependent.hide) {
|
90
|
-
evaluateHide(
|
92
|
+
evaluateHide(
|
93
|
+
{ value: dependent, type: 'field' },
|
94
|
+
formFields,
|
95
|
+
values,
|
96
|
+
sessionMode,
|
97
|
+
patient,
|
98
|
+
evaluateExpression,
|
99
|
+
updateFormField,
|
100
|
+
);
|
91
101
|
}
|
92
102
|
// evaluate disabled
|
93
103
|
if (typeof dependent.disabled === 'object' && dependent.disabled.disableWhenExpression) {
|
@@ -197,12 +207,8 @@ function evaluateFieldDependents(field: FormField, values: any, context: FormCon
|
|
197
207
|
sessionMode,
|
198
208
|
patient,
|
199
209
|
evaluateExpression,
|
210
|
+
updateFormField,
|
200
211
|
);
|
201
|
-
if (isTrue(section.isHidden)) {
|
202
|
-
section.questions.forEach((field) => {
|
203
|
-
field.isParentHidden = true;
|
204
|
-
});
|
205
|
-
}
|
206
212
|
shouldUpdateForm = true;
|
207
213
|
break;
|
208
214
|
}
|
@@ -214,14 +220,15 @@ function evaluateFieldDependents(field: FormField, values: any, context: FormCon
|
|
214
220
|
if (field.pageDependents) {
|
215
221
|
field.pageDependents?.forEach((dep) => {
|
216
222
|
const dependent = formJson.pages.find((f) => f.label == dep);
|
217
|
-
evaluateHide(
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
223
|
+
evaluateHide(
|
224
|
+
{ value: dependent, type: 'page' },
|
225
|
+
formFields,
|
226
|
+
values,
|
227
|
+
sessionMode,
|
228
|
+
patient,
|
229
|
+
evaluateExpression,
|
230
|
+
updateFormField,
|
231
|
+
);
|
225
232
|
shouldUpdateForm = true;
|
226
233
|
});
|
227
234
|
}
|
@@ -109,7 +109,15 @@ export const useEvaluateFormFieldExpressions = (
|
|
109
109
|
useEffect(() => {
|
110
110
|
factoryContext.formJson?.pages?.forEach((page) => {
|
111
111
|
if (page.hide) {
|
112
|
-
evaluateHide(
|
112
|
+
evaluateHide(
|
113
|
+
{ value: page, type: 'page' },
|
114
|
+
formFields,
|
115
|
+
formValues,
|
116
|
+
sessionMode,
|
117
|
+
patient,
|
118
|
+
evaluateExpression,
|
119
|
+
null,
|
120
|
+
);
|
113
121
|
} else {
|
114
122
|
page.isHidden = false;
|
115
123
|
}
|
@@ -122,6 +130,7 @@ export const useEvaluateFormFieldExpressions = (
|
|
122
130
|
sessionMode,
|
123
131
|
patient,
|
124
132
|
evaluateExpression,
|
133
|
+
null,
|
125
134
|
);
|
126
135
|
} else {
|
127
136
|
section.isHidden = false;
|
package/src/types/domain.ts
CHANGED
@@ -15,20 +15,80 @@ export interface OpenmrsEncounter {
|
|
15
15
|
}
|
16
16
|
|
17
17
|
export interface OpenmrsObs extends OpenmrsResource {
|
18
|
-
concept
|
19
|
-
obsDatetime
|
20
|
-
obsGroup
|
21
|
-
groupMembers
|
22
|
-
comment
|
23
|
-
location
|
24
|
-
order
|
25
|
-
encounter
|
26
|
-
voided
|
27
|
-
value
|
28
|
-
formFieldPath
|
29
|
-
formFieldNamespace
|
30
|
-
status
|
31
|
-
interpretation
|
18
|
+
concept?: any;
|
19
|
+
obsDatetime?: string | Date;
|
20
|
+
obsGroup?: OpenmrsObs;
|
21
|
+
groupMembers?: Array<OpenmrsObs>;
|
22
|
+
comment?: string;
|
23
|
+
location?: OpenmrsResource;
|
24
|
+
order?: OpenmrsResource;
|
25
|
+
encounter?: OpenmrsResource;
|
26
|
+
voided?: boolean;
|
27
|
+
value?: any;
|
28
|
+
formFieldPath?: string;
|
29
|
+
formFieldNamespace?: string;
|
30
|
+
status?: string;
|
31
|
+
interpretation?: string;
|
32
|
+
}
|
33
|
+
|
34
|
+
export interface FHIRObsResource {
|
35
|
+
resourceType: string;
|
36
|
+
id: string;
|
37
|
+
category: Array<{
|
38
|
+
coding: Array<{
|
39
|
+
system: string;
|
40
|
+
code: string;
|
41
|
+
display: string;
|
42
|
+
}>;
|
43
|
+
}>;
|
44
|
+
code: {
|
45
|
+
coding: Array<{
|
46
|
+
code: string;
|
47
|
+
display: string;
|
48
|
+
}>;
|
49
|
+
text: string;
|
50
|
+
};
|
51
|
+
encounter?: {
|
52
|
+
reference: string;
|
53
|
+
type: string;
|
54
|
+
};
|
55
|
+
effectiveDateTime: string;
|
56
|
+
issued: string;
|
57
|
+
valueBoolean?: boolean;
|
58
|
+
valueString?: string;
|
59
|
+
valueDateTime?: string;
|
60
|
+
valueQuantity?: {
|
61
|
+
value: number;
|
62
|
+
unit: string;
|
63
|
+
system: string;
|
64
|
+
code: string;
|
65
|
+
};
|
66
|
+
valueCodeableConcept?: {
|
67
|
+
coding: [
|
68
|
+
{
|
69
|
+
code: string;
|
70
|
+
display: string;
|
71
|
+
},
|
72
|
+
];
|
73
|
+
text: string;
|
74
|
+
};
|
75
|
+
referenceRange: Array<{
|
76
|
+
low?: {
|
77
|
+
value: number;
|
78
|
+
};
|
79
|
+
high?: {
|
80
|
+
value: number;
|
81
|
+
};
|
82
|
+
type: {
|
83
|
+
coding: Array<{
|
84
|
+
system: string;
|
85
|
+
code: string;
|
86
|
+
}>;
|
87
|
+
};
|
88
|
+
}>;
|
89
|
+
hasMember?: Array<{
|
90
|
+
reference: string;
|
91
|
+
}>;
|
32
92
|
}
|
33
93
|
|
34
94
|
export interface OpenmrsForm {
|
@@ -1,14 +1,12 @@
|
|
1
1
|
import {
|
2
2
|
findConceptByReference,
|
3
|
-
evaluateConditionalAnswered,
|
4
3
|
evaluateFieldReadonlyProp,
|
5
4
|
evaluateDisabled,
|
6
5
|
isPageContentVisible,
|
6
|
+
extractObsValueAndDisplay,
|
7
7
|
} from './form-helper';
|
8
|
-
import { DefaultValueValidator } from '../validators/default-value-validator';
|
9
|
-
import { type LayoutType } from '@openmrs/esm-framework';
|
10
8
|
import { ConceptTrue } from '../constants';
|
11
|
-
import {
|
9
|
+
import type { FormPage, FormField } from '../types';
|
12
10
|
|
13
11
|
jest.mock('../validators/default-value-validator');
|
14
12
|
|
@@ -507,4 +505,160 @@ describe('Form Engine Helper', () => {
|
|
507
505
|
expect(isPageContentVisible(page)).toBe(false);
|
508
506
|
});
|
509
507
|
});
|
508
|
+
|
509
|
+
describe('extractObsValueAndDisplay', () => {
|
510
|
+
// Mock form field types
|
511
|
+
const mockFormFields = {
|
512
|
+
codedField: {
|
513
|
+
questionOptions: {
|
514
|
+
rendering: 'select',
|
515
|
+
answers: [{ concept: '2395de62-f5a6-49b6-ab0f-57a21a9029c1', label: 'Sneezing Symptom' }],
|
516
|
+
},
|
517
|
+
},
|
518
|
+
toggleField: {
|
519
|
+
questionOptions: {
|
520
|
+
rendering: 'toggle',
|
521
|
+
answers: [],
|
522
|
+
},
|
523
|
+
},
|
524
|
+
dateField: {
|
525
|
+
questionOptions: {
|
526
|
+
rendering: 'date',
|
527
|
+
},
|
528
|
+
},
|
529
|
+
stringField: {
|
530
|
+
questionOptions: {
|
531
|
+
rendering: 'text',
|
532
|
+
},
|
533
|
+
},
|
534
|
+
} as any;
|
535
|
+
|
536
|
+
// Primitive value tests
|
537
|
+
describe('Primitive Value Handling', () => {
|
538
|
+
it('should handle string primitive value', () => {
|
539
|
+
const result = extractObsValueAndDisplay(mockFormFields.stringField, 'Hello World');
|
540
|
+
expect(result).toEqual({
|
541
|
+
value: 'Hello World',
|
542
|
+
display: 'Hello World',
|
543
|
+
});
|
544
|
+
});
|
545
|
+
|
546
|
+
it('should handle number primitive value', () => {
|
547
|
+
const result = extractObsValueAndDisplay(mockFormFields.stringField, 42);
|
548
|
+
expect(result).toEqual({
|
549
|
+
value: 42,
|
550
|
+
display: 42,
|
551
|
+
});
|
552
|
+
});
|
553
|
+
});
|
554
|
+
|
555
|
+
// FHIR Observation tests
|
556
|
+
describe('FHIR Observation Handling', () => {
|
557
|
+
const codedFHIRObs = {
|
558
|
+
resourceType: 'Observation',
|
559
|
+
code: {
|
560
|
+
coding: {
|
561
|
+
code: '1095de62-b5a6-49v6-ab0f-57a21a9029cb',
|
562
|
+
},
|
563
|
+
},
|
564
|
+
valueCodeableConcept: {
|
565
|
+
coding: [
|
566
|
+
{
|
567
|
+
code: '2395de62-f5a6-49b6-ab0f-57a21a9029c1',
|
568
|
+
display: 'Sneezing',
|
569
|
+
},
|
570
|
+
],
|
571
|
+
},
|
572
|
+
};
|
573
|
+
|
574
|
+
const booleanFHIRObs = {
|
575
|
+
resourceType: 'Observation',
|
576
|
+
code: {
|
577
|
+
coding: {
|
578
|
+
code: 'b095deb2-b5a6-49v6-ab0f-57a21a9029cx',
|
579
|
+
},
|
580
|
+
},
|
581
|
+
valueBoolean: true,
|
582
|
+
};
|
583
|
+
|
584
|
+
const dateFHIRObs = {
|
585
|
+
resourceType: 'Observation',
|
586
|
+
code: {
|
587
|
+
coding: {
|
588
|
+
code: 'e095de62-b5a6-49v6-ab0f-57a21a9029cy',
|
589
|
+
},
|
590
|
+
},
|
591
|
+
valueDateTime: '2024-07-31T01:33:19+00:00',
|
592
|
+
};
|
593
|
+
|
594
|
+
it('should handle coded FHIR observation', () => {
|
595
|
+
const result = extractObsValueAndDisplay(mockFormFields.codedField, codedFHIRObs);
|
596
|
+
expect(result).toEqual({
|
597
|
+
value: '2395de62-f5a6-49b6-ab0f-57a21a9029c1',
|
598
|
+
display: 'Sneezing Symptom',
|
599
|
+
});
|
600
|
+
});
|
601
|
+
|
602
|
+
it('should handle boolean FHIR observation', () => {
|
603
|
+
const result = extractObsValueAndDisplay(mockFormFields.toggleField, booleanFHIRObs);
|
604
|
+
expect(result).toEqual({
|
605
|
+
value: ConceptTrue,
|
606
|
+
display: undefined,
|
607
|
+
});
|
608
|
+
});
|
609
|
+
|
610
|
+
it('should handle date FHIR observation', () => {
|
611
|
+
const result = extractObsValueAndDisplay(mockFormFields.dateField, dateFHIRObs);
|
612
|
+
expect(result).toEqual({
|
613
|
+
value: expect.any(Date),
|
614
|
+
display: expect.stringContaining('2024-07-31'),
|
615
|
+
});
|
616
|
+
});
|
617
|
+
});
|
618
|
+
|
619
|
+
// OpenMRS Observation tests
|
620
|
+
describe('OpenMRS Observation Handling', () => {
|
621
|
+
const codedOpenMRSObs = {
|
622
|
+
value: {
|
623
|
+
uuid: '2395de62-f5a6-49b6-ab0f-57a21a9029c1',
|
624
|
+
name: { name: 'Sneezing' },
|
625
|
+
},
|
626
|
+
};
|
627
|
+
|
628
|
+
const booleanOpenMRSObs = {
|
629
|
+
value: {
|
630
|
+
uuid: 'cf82933b-3f3f-45e7-a5ab-5d31aaee3da3',
|
631
|
+
name: { name: 'True' },
|
632
|
+
},
|
633
|
+
};
|
634
|
+
|
635
|
+
const dateOpenMRSObs = {
|
636
|
+
value: '2024-07-31T01:33:19+00:00',
|
637
|
+
};
|
638
|
+
|
639
|
+
it('should handle coded OpenMRS observation', () => {
|
640
|
+
const result = extractObsValueAndDisplay(mockFormFields.codedField, codedOpenMRSObs);
|
641
|
+
expect(result).toEqual({
|
642
|
+
value: '2395de62-f5a6-49b6-ab0f-57a21a9029c1',
|
643
|
+
display: 'Sneezing Symptom',
|
644
|
+
});
|
645
|
+
});
|
646
|
+
|
647
|
+
it('should handle boolean OpenMRS observation', () => {
|
648
|
+
const result = extractObsValueAndDisplay(mockFormFields.toggleField, booleanOpenMRSObs);
|
649
|
+
expect(result).toEqual({
|
650
|
+
value: 'cf82933b-3f3f-45e7-a5ab-5d31aaee3da3',
|
651
|
+
display: 'True',
|
652
|
+
});
|
653
|
+
});
|
654
|
+
|
655
|
+
it('should handle date OpenMRS observation', () => {
|
656
|
+
const result = extractObsValueAndDisplay(mockFormFields.dateField, dateOpenMRSObs);
|
657
|
+
expect(result).toEqual({
|
658
|
+
value: expect.any(Date),
|
659
|
+
display: expect.stringMatching(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/),
|
660
|
+
});
|
661
|
+
});
|
662
|
+
});
|
663
|
+
});
|
510
664
|
});
|
package/src/utils/form-helper.ts
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
import { type LayoutType } from '@openmrs/esm-framework';
|
2
|
-
import
|
2
|
+
import type { FormField, FormPage, FormSection, SessionMode, FHIRObsResource, RenderType } from '../types';
|
3
3
|
import { isEmpty } from '../validators/form-validator';
|
4
4
|
import { parseToLocalDateTime } from './common-utils';
|
5
5
|
import dayjs from 'dayjs';
|
6
|
+
import { ConceptFalse, ConceptTrue } from '../constants';
|
6
7
|
|
7
8
|
export function shouldUseInlineLayout(
|
8
9
|
renderingType: 'single-line' | 'multiline' | 'automatic',
|
@@ -94,6 +95,7 @@ export function evaluateHide(
|
|
94
95
|
sessionMode: SessionMode,
|
95
96
|
patient: fhir.Patient,
|
96
97
|
expressionRunnerFn,
|
98
|
+
updateFormFieldFn: (field: FormField) => void | null,
|
97
99
|
) {
|
98
100
|
const { value, type } = node;
|
99
101
|
const isHidden = expressionRunnerFn(value['hide']?.hideWhenExpression, node, allFields, allValues, {
|
@@ -110,15 +112,20 @@ export function evaluateHide(
|
|
110
112
|
if (type == 'page') {
|
111
113
|
value['sections'].forEach((section) => {
|
112
114
|
section.isParentHidden = isHidden;
|
113
|
-
cascadeVisibilityToChildFields(isHidden, section, allFields);
|
115
|
+
cascadeVisibilityToChildFields(isHidden, section, allFields, updateFormFieldFn);
|
114
116
|
});
|
115
117
|
}
|
116
118
|
if (type == 'section') {
|
117
|
-
cascadeVisibilityToChildFields(isHidden, value, allFields);
|
119
|
+
cascadeVisibilityToChildFields(isHidden, value, allFields, updateFormFieldFn);
|
118
120
|
}
|
119
121
|
}
|
120
122
|
|
121
|
-
function cascadeVisibilityToChildFields(
|
123
|
+
function cascadeVisibilityToChildFields(
|
124
|
+
visibility: boolean,
|
125
|
+
section: FormSection,
|
126
|
+
allFields: Array<FormField>,
|
127
|
+
updateFormFieldFn: (field: FormField) => void,
|
128
|
+
) {
|
122
129
|
const candidateIds = section.questions.map((q) => q.id);
|
123
130
|
allFields
|
124
131
|
.filter((field) => candidateIds.includes(field.id))
|
@@ -129,6 +136,7 @@ function cascadeVisibilityToChildFields(visibility: boolean, section: FormSectio
|
|
129
136
|
member.isParentHidden = visibility;
|
130
137
|
});
|
131
138
|
}
|
139
|
+
updateFormFieldFn?.(field);
|
132
140
|
});
|
133
141
|
}
|
134
142
|
|
@@ -172,24 +180,30 @@ export function scrollIntoView(viewId: string, shouldFocus: boolean = false) {
|
|
172
180
|
}
|
173
181
|
}
|
174
182
|
|
175
|
-
export const extractObsValueAndDisplay = (field: FormField, obs:
|
183
|
+
export const extractObsValueAndDisplay = (field: FormField, obs: any) => {
|
176
184
|
const rendering = field.questionOptions.rendering;
|
177
|
-
|
178
|
-
|
185
|
+
if (typeof obs !== 'object') {
|
186
|
+
return { value: obs, display: obs };
|
187
|
+
}
|
188
|
+
const omrsObs = obs.resourceType === 'Observation' ? mapFHIRObsToOpenMRS(obs, rendering) : obs;
|
189
|
+
if (!omrsObs) {
|
190
|
+
return { value: null, display: null };
|
191
|
+
}
|
192
|
+
if (typeof omrsObs.value === 'string' || typeof omrsObs.value === 'number') {
|
179
193
|
if (rendering === 'date' || rendering === 'datetime') {
|
180
|
-
const dateObj = parseToLocalDateTime(`${
|
194
|
+
const dateObj = parseToLocalDateTime(`${omrsObs.value}`);
|
181
195
|
return { value: dateObj, display: dayjs(dateObj).format('YYYY-MM-DD HH:mm') };
|
182
196
|
}
|
183
|
-
return { value:
|
197
|
+
return { value: omrsObs.value, display: omrsObs.value };
|
184
198
|
} else if (['toggle', 'checkbox'].includes(rendering)) {
|
185
199
|
return {
|
186
|
-
value:
|
187
|
-
display:
|
200
|
+
value: omrsObs.value?.uuid,
|
201
|
+
display: omrsObs.value?.name?.name,
|
188
202
|
};
|
189
203
|
} else {
|
190
204
|
return {
|
191
|
-
value:
|
192
|
-
display: field.questionOptions.answers?.find((option) => option.concept ===
|
205
|
+
value: omrsObs.value?.uuid,
|
206
|
+
display: field.questionOptions.answers?.find((option) => option.concept === omrsObs.value?.uuid)?.label,
|
193
207
|
};
|
194
208
|
}
|
195
209
|
};
|
@@ -212,3 +226,48 @@ export function isPageContentVisible(page: FormPage) {
|
|
212
226
|
}) ?? false
|
213
227
|
);
|
214
228
|
}
|
229
|
+
|
230
|
+
function mapFHIRObsToOpenMRS(fhirObs: FHIRObsResource, rendering: RenderType) {
|
231
|
+
try {
|
232
|
+
return {
|
233
|
+
obsDatetime: fhirObs.effectiveDateTime,
|
234
|
+
uuid: fhirObs.id,
|
235
|
+
concept: {
|
236
|
+
uuid: fhirObs.code.coding[0]?.code,
|
237
|
+
display: fhirObs.code.coding[0]?.display,
|
238
|
+
},
|
239
|
+
value: extractFHIRObsValue(fhirObs, rendering),
|
240
|
+
};
|
241
|
+
} catch (error) {
|
242
|
+
console.error('Error converting FHIR Obs to OpenMRS modelling', error);
|
243
|
+
return null;
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
247
|
+
function extractFHIRObsValue(fhirObs: FHIRObsResource, rendering: RenderType) {
|
248
|
+
switch (rendering) {
|
249
|
+
case 'toggle':
|
250
|
+
return fhirObs.valueBoolean ? { uuid: ConceptTrue } : { uuid: ConceptFalse };
|
251
|
+
|
252
|
+
case 'date':
|
253
|
+
case 'datetime':
|
254
|
+
return fhirObs.valueDateTime;
|
255
|
+
|
256
|
+
case 'number':
|
257
|
+
return fhirObs.valueQuantity?.value ?? null;
|
258
|
+
|
259
|
+
case 'radio':
|
260
|
+
case 'checkbox':
|
261
|
+
case 'select':
|
262
|
+
case 'content-switcher':
|
263
|
+
return fhirObs.valueCodeableConcept?.coding[0]
|
264
|
+
? {
|
265
|
+
uuid: fhirObs.valueCodeableConcept?.coding[0].code,
|
266
|
+
name: { name: fhirObs.valueCodeableConcept?.coding[0].display },
|
267
|
+
}
|
268
|
+
: null;
|
269
|
+
|
270
|
+
default:
|
271
|
+
return fhirObs.valueString;
|
272
|
+
}
|
273
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|