@openmrs/esm-form-engine-lib 2.1.0-pre.1584 → 2.1.0-pre.1594
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/inputs/text/text.component.tsx +3 -1
- package/src/components/inputs/text/text.test.tsx +3 -9
- package/src/components/renderer/form/form-renderer.component.tsx +0 -1
- package/src/components/repeat/helpers.ts +1 -0
- package/src/components/repeat/repeat.component.tsx +12 -8
- package/src/hooks/useFormStateHelpers.ts +18 -3
- package/src/types/domain.ts +74 -14
- package/src/utils/form-helper.test.ts +158 -4
- package/src/utils/form-helper.ts +62 -10
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
|
/**
|
@@ -42,7 +42,9 @@ const TextField: React.FC<FormFieldInputProps> = ({ field, value, errors, warnin
|
|
42
42
|
<TextInput
|
43
43
|
id={field.id}
|
44
44
|
labelText={<FieldLabel field={field} />}
|
45
|
-
onChange={
|
45
|
+
onChange={(event) => {
|
46
|
+
setFieldValue(event.target.value);
|
47
|
+
}}
|
46
48
|
onBlur={onBlur}
|
47
49
|
name={field.id}
|
48
50
|
value={value}
|
@@ -161,17 +161,11 @@ describe('Text field input', () => {
|
|
161
161
|
it('should record new obs', async () => {
|
162
162
|
await renderForm(textValues);
|
163
163
|
const inputField = screen.getByLabelText('Indicate your notes');
|
164
|
-
|
165
|
-
await user.
|
164
|
+
await user.click(inputField);
|
165
|
+
await user.paste('Updated patient notes');
|
166
166
|
|
167
167
|
await act(async () => {
|
168
|
-
expect(mockSetFieldValue).toHaveBeenCalledWith(
|
169
|
-
expect.objectContaining({
|
170
|
-
target: expect.objectContaining({
|
171
|
-
value: 'Updated patient notes',
|
172
|
-
}),
|
173
|
-
}),
|
174
|
-
);
|
168
|
+
expect(mockSetFieldValue).toHaveBeenCalledWith('Updated patient notes');
|
175
169
|
});
|
176
170
|
});
|
177
171
|
|
@@ -6,7 +6,6 @@ import { formStateReducer, initialState } from './state';
|
|
6
6
|
import { useEvaluateFormFieldExpressions } from '../../../hooks/useEvaluateFormFieldExpressions';
|
7
7
|
import { useFormFactory } from '../../../provider/form-factory-provider';
|
8
8
|
import { FormProvider, type FormContextProps } from '../../../provider/form-provider';
|
9
|
-
import { isTrue } from '../../../utils/boolean-utils';
|
10
9
|
import { type FormProcessorContextProps } from '../../../types';
|
11
10
|
import { useFormStateHelpers } from '../../../hooks/useFormStateHelpers';
|
12
11
|
import { pageObserver } from '../../sidebar/page-observer';
|
@@ -15,6 +15,7 @@ export function cloneRepeatField(srcField: FormField, value: OpenmrsResource, id
|
|
15
15
|
childField.id = `${childField.id}_${idSuffix}`;
|
16
16
|
childField.meta.groupId = clonedField.id;
|
17
17
|
childField.meta.previousValue = null;
|
18
|
+
childField.fieldDependents = new Set();
|
18
19
|
clearSubmission(childField);
|
19
20
|
|
20
21
|
// cleanup expressions
|
@@ -47,12 +47,13 @@ const Repeat: React.FC<FormFieldInputProps> = ({ field }) => {
|
|
47
47
|
|
48
48
|
const handleAdd = useCallback(
|
49
49
|
(counter: number) => {
|
50
|
+
const clonedFieldsBuffer: FormField[] = [];
|
50
51
|
function evaluateExpressions(field: FormField) {
|
51
52
|
if (field.hide?.hideWhenExpression) {
|
52
53
|
field.isHidden = evaluateExpression(
|
53
54
|
field.hide.hideWhenExpression,
|
54
55
|
{ value: field, type: 'field' },
|
55
|
-
formFields,
|
56
|
+
[...formFields, ...clonedFieldsBuffer],
|
56
57
|
getValues(),
|
57
58
|
{
|
58
59
|
mode: sessionMode,
|
@@ -64,7 +65,7 @@ const Repeat: React.FC<FormFieldInputProps> = ({ field }) => {
|
|
64
65
|
evaluateAsyncExpression(
|
65
66
|
field.questionOptions.calculate?.calculateExpression,
|
66
67
|
{ value: field, type: 'field' },
|
67
|
-
formFields,
|
68
|
+
[...formFields, ...clonedFieldsBuffer],
|
68
69
|
getValues(),
|
69
70
|
{
|
70
71
|
mode: sessionMode,
|
@@ -80,16 +81,19 @@ const Repeat: React.FC<FormFieldInputProps> = ({ field }) => {
|
|
80
81
|
}
|
81
82
|
|
82
83
|
const clonedField = cloneRepeatField(field, null, counter);
|
83
|
-
|
84
|
+
clonedFieldsBuffer.push(clonedField);
|
85
|
+
|
86
|
+
// Handle nested questions
|
84
87
|
if (clonedField.type === 'obsGroup') {
|
85
88
|
clonedField.questions?.forEach((childField) => {
|
86
|
-
|
87
|
-
addFormField(childField);
|
89
|
+
clonedFieldsBuffer.push(childField);
|
88
90
|
});
|
89
|
-
} else {
|
90
|
-
evaluateExpressions(clonedField);
|
91
91
|
}
|
92
|
-
|
92
|
+
|
93
|
+
clonedFieldsBuffer.forEach((field) => {
|
94
|
+
evaluateExpressions(field);
|
95
|
+
addFormField(field);
|
96
|
+
});
|
93
97
|
setRows([...rows, clonedField]);
|
94
98
|
},
|
95
99
|
[formFields, field, rows, context],
|
@@ -8,9 +8,24 @@ export function useFormStateHelpers(dispatch: Dispatch<Action>, formFields: Form
|
|
8
8
|
const addFormField = useCallback((field: FormField) => {
|
9
9
|
dispatch({ type: 'ADD_FORM_FIELD', value: field });
|
10
10
|
}, []);
|
11
|
-
const updateFormField = useCallback(
|
12
|
-
|
13
|
-
|
11
|
+
const updateFormField = useCallback(
|
12
|
+
(field: FormField) => {
|
13
|
+
if (field.meta.groupId) {
|
14
|
+
const group = formFields.find((f) => f.id === field.meta.groupId);
|
15
|
+
if (group) {
|
16
|
+
group.questions = group.questions.map((child) => {
|
17
|
+
if (child.id === field.id) {
|
18
|
+
return field;
|
19
|
+
}
|
20
|
+
return child;
|
21
|
+
});
|
22
|
+
updateFormField(group);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
dispatch({ type: 'UPDATE_FORM_FIELD', value: cloneDeep(field) });
|
26
|
+
},
|
27
|
+
[formFields],
|
28
|
+
);
|
14
29
|
|
15
30
|
const getFormField = useCallback(
|
16
31
|
(fieldId: string) => {
|
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',
|
@@ -172,24 +173,30 @@ export function scrollIntoView(viewId: string, shouldFocus: boolean = false) {
|
|
172
173
|
}
|
173
174
|
}
|
174
175
|
|
175
|
-
export const extractObsValueAndDisplay = (field: FormField, obs:
|
176
|
+
export const extractObsValueAndDisplay = (field: FormField, obs: any) => {
|
176
177
|
const rendering = field.questionOptions.rendering;
|
177
|
-
|
178
|
-
|
178
|
+
if (typeof obs !== 'object') {
|
179
|
+
return { value: obs, display: obs };
|
180
|
+
}
|
181
|
+
const omrsObs = obs.resourceType === 'Observation' ? mapFHIRObsToOpenMRS(obs, rendering) : obs;
|
182
|
+
if (!omrsObs) {
|
183
|
+
return { value: null, display: null };
|
184
|
+
}
|
185
|
+
if (typeof omrsObs.value === 'string' || typeof omrsObs.value === 'number') {
|
179
186
|
if (rendering === 'date' || rendering === 'datetime') {
|
180
|
-
const dateObj = parseToLocalDateTime(`${
|
187
|
+
const dateObj = parseToLocalDateTime(`${omrsObs.value}`);
|
181
188
|
return { value: dateObj, display: dayjs(dateObj).format('YYYY-MM-DD HH:mm') };
|
182
189
|
}
|
183
|
-
return { value:
|
190
|
+
return { value: omrsObs.value, display: omrsObs.value };
|
184
191
|
} else if (['toggle', 'checkbox'].includes(rendering)) {
|
185
192
|
return {
|
186
|
-
value:
|
187
|
-
display:
|
193
|
+
value: omrsObs.value?.uuid,
|
194
|
+
display: omrsObs.value?.name?.name,
|
188
195
|
};
|
189
196
|
} else {
|
190
197
|
return {
|
191
|
-
value:
|
192
|
-
display: field.questionOptions.answers?.find((option) => option.concept ===
|
198
|
+
value: omrsObs.value?.uuid,
|
199
|
+
display: field.questionOptions.answers?.find((option) => option.concept === omrsObs.value?.uuid)?.label,
|
193
200
|
};
|
194
201
|
}
|
195
202
|
};
|
@@ -212,3 +219,48 @@ export function isPageContentVisible(page: FormPage) {
|
|
212
219
|
}) ?? false
|
213
220
|
);
|
214
221
|
}
|
222
|
+
|
223
|
+
function mapFHIRObsToOpenMRS(fhirObs: FHIRObsResource, rendering: RenderType) {
|
224
|
+
try {
|
225
|
+
return {
|
226
|
+
obsDatetime: fhirObs.effectiveDateTime,
|
227
|
+
uuid: fhirObs.id,
|
228
|
+
concept: {
|
229
|
+
uuid: fhirObs.code.coding[0]?.code,
|
230
|
+
display: fhirObs.code.coding[0]?.display,
|
231
|
+
},
|
232
|
+
value: extractFHIRObsValue(fhirObs, rendering),
|
233
|
+
};
|
234
|
+
} catch (error) {
|
235
|
+
console.error('Error converting FHIR Obs to OpenMRS modelling', error);
|
236
|
+
return null;
|
237
|
+
}
|
238
|
+
}
|
239
|
+
|
240
|
+
function extractFHIRObsValue(fhirObs: FHIRObsResource, rendering: RenderType) {
|
241
|
+
switch (rendering) {
|
242
|
+
case 'toggle':
|
243
|
+
return fhirObs.valueBoolean ? { uuid: ConceptTrue } : { uuid: ConceptFalse };
|
244
|
+
|
245
|
+
case 'date':
|
246
|
+
case 'datetime':
|
247
|
+
return fhirObs.valueDateTime;
|
248
|
+
|
249
|
+
case 'number':
|
250
|
+
return fhirObs.valueQuantity?.value ?? null;
|
251
|
+
|
252
|
+
case 'radio':
|
253
|
+
case 'checkbox':
|
254
|
+
case 'select':
|
255
|
+
case 'content-switcher':
|
256
|
+
return fhirObs.valueCodeableConcept?.coding[0]
|
257
|
+
? {
|
258
|
+
uuid: fhirObs.valueCodeableConcept?.coding[0].code,
|
259
|
+
name: { name: fhirObs.valueCodeableConcept?.coding[0].display },
|
260
|
+
}
|
261
|
+
: null;
|
262
|
+
|
263
|
+
default:
|
264
|
+
return fhirObs.valueString;
|
265
|
+
}
|
266
|
+
}
|