Skip to content

Commit 640599a

Browse files
committed
Add converter for enableChart extension
1 parent fe358a1 commit 640599a

File tree

5 files changed

+200
-17
lines changed

5 files changed

+200
-17
lines changed

src/converter/__tests__/fce.test.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,22 @@ import { describe, expect, test } from 'vitest';
33

44
// fce questionnaire
55
import fce_allergies from './resources/questionnaire_fce/allergies.json';
6+
import fce_answer_options_toggle_expression from './resources/questionnaire_fce/answerOptionsToggleExpression.json';
7+
import fce_assemble_context from './resources/questionnaire_fce/assemble_context.json';
68
import fce_beverages from './resources/questionnaire_fce/beverages.json';
79
import fce_choice_answer_option from './resources/questionnaire_fce/choice_answer_option.json';
810
import fce_consent from './resources/questionnaire_fce/consent.json';
911
import fce_constraint from './resources/questionnaire_fce/constraint.json';
10-
import fce_answer_options_toggle_expression from './resources/questionnaire_fce/answerOptionsToggleExpression.json';
1112
import fce_cqf_examples from './resources/questionnaire_fce/cqf-examples.json';
13+
import fce_enable_chart from './resources/questionnaire_fce/enable_chart.json';
1214
import fce_enable_when from './resources/questionnaire_fce/enable_when.json';
1315
import fce_encounter_create from './resources/questionnaire_fce/encounter_create.json';
1416
import fce_gad_7 from './resources/questionnaire_fce/gad_7.json';
1517
import fce_immunization from './resources/questionnaire_fce/immunization.json';
1618
import fce_medication from './resources/questionnaire_fce/medication.json';
19+
import fce_mixed_fce_with_extensions from './resources/questionnaire_fce/mixed-fce-with-extensions.json';
1720
import fce_multiple_type_launch_context from './resources/questionnaire_fce/multiple_type_launch_context.json';
21+
import fce_occurs from './resources/questionnaire_fce/occurs.json';
1822
import fce_patient_create from './resources/questionnaire_fce/patient_create.json';
1923
import fce_patient_edit from './resources/questionnaire_fce/patient_edit.json';
2024
import fce_phq_2_phq_9 from './resources/questionnaire_fce/phq_2_phq_9.json';
@@ -26,29 +30,30 @@ import fce_practitioner_role_create from './resources/questionnaire_fce/practiti
2630
import fce_public_appointment from './resources/questionnaire_fce/public_appointment.json';
2731
import fce_review_of_systems from './resources/questionnaire_fce/review_of_systems.json';
2832
import fce_source_queries from './resources/questionnaire_fce/source_queries.json';
33+
import fce_sub_questionnaire from './resources/questionnaire_fce/sub-questionnaire.json';
2934
import fce_unit_option from './resources/questionnaire_fce/unit-option.json';
30-
import fce_vitals from './resources/questionnaire_fce/vitals.json';
35+
import fce_unknown_extensions from './resources/questionnaire_fce/unknown-extensions.json';
3136
import fce_variable from './resources/questionnaire_fce/variable.json';
32-
import fce_sub_questionnaire from './resources/questionnaire_fce/sub-questionnaire.json';
37+
import fce_vitals from './resources/questionnaire_fce/vitals.json';
3338
import fce_with_attachment_questionnaire from './resources/questionnaire_fce/with-attachment-question.json';
34-
import fce_mixed_fce_with_extensions from './resources/questionnaire_fce/mixed-fce-with-extensions.json';
35-
import fce_unknown_extensions from './resources/questionnaire_fce/unknown-extensions.json';
36-
import fce_occurs from './resources/questionnaire_fce/occurs.json';
37-
import fce_assemble_context from './resources/questionnaire_fce/assemble_context.json';
3839
// fhir questionnaire
3940
import fhir_allergies from './resources/questionnaire_fhir/allergies.json';
41+
import fhir_answer_options_toggle_expression from './resources/questionnaire_fhir/answerOptionsToggleExpression.json';
42+
import fhir_assemble_context from './resources/questionnaire_fhir/assemble_context.json';
4043
import fhir_beverages from './resources/questionnaire_fhir/beverages.json';
4144
import fhir_choice_answer_option from './resources/questionnaire_fhir/choice_answer_option.json';
4245
import fhir_consent from './resources/questionnaire_fhir/consent.json';
4346
import fhir_constraint from './resources/questionnaire_fhir/constraint.json';
44-
import fhir_answer_options_toggle_expression from './resources/questionnaire_fhir/answerOptionsToggleExpression.json';
4547
import fhir_cqf_examples from './resources/questionnaire_fhir/cqf-examples.json';
48+
import fhir_enable_chart from './resources/questionnaire_fhir/enable_chart.json';
4649
import fhir_enable_when from './resources/questionnaire_fhir/enable_when.json';
4750
import fhir_encounter_create from './resources/questionnaire_fhir/encounter_create.json';
4851
import fhir_gad_7 from './resources/questionnaire_fhir/gad_7.json';
4952
import fhir_immunization from './resources/questionnaire_fhir/immunization.json';
5053
import fhir_medication from './resources/questionnaire_fhir/medication.json';
54+
import fhir_mixed_fce_with_extensions from './resources/questionnaire_fhir/mixed-fce-with-extensions.json';
5155
import fhir_multiple_type_launch_context from './resources/questionnaire_fhir/multiple_type_launch_context.json';
56+
import fhir_occurs from './resources/questionnaire_fhir/occurs.json';
5257
import fhir_patient_create from './resources/questionnaire_fhir/patient_create.json';
5358
import fhir_patient_edit from './resources/questionnaire_fhir/patient_edit.json';
5459
import fhir_phq_2_phq_9 from './resources/questionnaire_fhir/phq_2_phq_9.json';
@@ -60,19 +65,16 @@ import fhir_practitioner_role_create from './resources/questionnaire_fhir/practi
6065
import fhir_public_appointment from './resources/questionnaire_fhir/public_appointment.json';
6166
import fhir_review_of_systems from './resources/questionnaire_fhir/review_of_systems.json';
6267
import fhir_source_queries from './resources/questionnaire_fhir/source_queries.json';
68+
import fhir_sub_questionnaire from './resources/questionnaire_fhir/sub-questionnaire.json';
6369
import fhir_unit_option from './resources/questionnaire_fhir/unit-option.json';
64-
import fhir_vitals from './resources/questionnaire_fhir/vitals.json';
70+
import fhir_unknown_extensions from './resources/questionnaire_fhir/unknown-extensions.json';
6571
import fhir_variable from './resources/questionnaire_fhir/variable.json';
66-
import fhir_sub_questionnaire from './resources/questionnaire_fhir/sub-questionnaire.json';
72+
import fhir_vitals from './resources/questionnaire_fhir/vitals.json';
6773
import fhir_with_attachment_questionnaire from './resources/questionnaire_fhir/with-attachment-question.json';
68-
import fhir_mixed_fce_with_extensions from './resources/questionnaire_fhir/mixed-fce-with-extensions.json';
69-
import fhir_unknown_extensions from './resources/questionnaire_fhir/unknown-extensions.json';
70-
import fhir_occurs from './resources/questionnaire_fhir/occurs.json';
71-
import fhir_assemble_context from './resources/questionnaire_fhir/assemble_context.json';
7274

7375
import { FCEQuestionnaire } from '../../fce.types';
7476

75-
import { toFirstClassExtension, fromFirstClassExtension } from '../../converter';
77+
import { fromFirstClassExtension, toFirstClassExtension } from '../../converter';
7678
import { sortExtensionsList } from '../utils';
7779

7880
describe('Questionanire and QuestionnaireResponses transformation', () => {
@@ -115,6 +117,7 @@ describe('Questionanire and QuestionnaireResponses transformation', () => {
115117
['unknown-extensions', fhir_unknown_extensions, fce_unknown_extensions],
116118
['occurs', fhir_occurs, fce_occurs],
117119
['assemble-context', fhir_assemble_context, fce_assemble_context],
120+
['enable-chart', fhir_enable_chart, fce_enable_chart],
118121
])('Each FHIR Questionnaire should convert to FCE %s', async (_, fhir_questionnaire, fce_questionnaire) => {
119122
expect(toFirstClassExtension(fhir_questionnaire as FHIRQuestionnaire)).toStrictEqual(fce_questionnaire);
120123
});
@@ -157,6 +160,7 @@ describe('Questionanire and QuestionnaireResponses transformation', () => {
157160
['unknown-extensions', fce_unknown_extensions, fhir_unknown_extensions],
158161
['occurs', fce_occurs, fhir_occurs],
159162
['assemble-context', fce_assemble_context, fhir_assemble_context],
163+
['enable-chart', fce_enable_chart, fhir_enable_chart],
160164
])('Each FCE Questionnaire should convert to FHIR %s', async (_, fce_questionnaire, fhir_questionnaire) => {
161165
expect(sortExtensionsList(fromFirstClassExtension(fce_questionnaire as FCEQuestionnaire))).toStrictEqual(
162166
sortExtensionsList(fhir_questionnaire),
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"item": [
3+
{
4+
"text": "Group Table Chart",
5+
"type": "group",
6+
"linkId": "group-table",
7+
"item": [
8+
{
9+
"text": "Chart data",
10+
"type": "group",
11+
"repeats": true,
12+
"itemControl": {
13+
"Coding": [
14+
{
15+
"code": "group-table"
16+
}
17+
]
18+
},
19+
"enableChart": [
20+
{
21+
"linkIdX": "date",
22+
"linkIdY": "weight"
23+
}
24+
],
25+
"item": [
26+
{
27+
"text": "Date",
28+
"type": "date",
29+
"linkId": "date"
30+
},
31+
{
32+
"text": "Weight",
33+
"type": "quantity",
34+
"linkId": "weight",
35+
"unitOption": [
36+
{
37+
"code": "kg",
38+
"system": "http://unitsofmeasure.org",
39+
"display": "kg"
40+
}
41+
]
42+
}
43+
]
44+
}
45+
]
46+
}
47+
],
48+
"status": "draft",
49+
"subjectType": ["Patient"],
50+
"assembledFrom": "enable-chart",
51+
"id": "example",
52+
"resourceType": "Questionnaire",
53+
"meta": {
54+
"profile": ["https://emr-core.beda.software/StructureDefinition/fhir-emr-questionnaire"],
55+
"lastUpdated": "2026-02-10T00:09:00.000000Z",
56+
"versionId": "205"
57+
}
58+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{
2+
"item": [
3+
{
4+
"text": "Group Table Chart",
5+
"type": "group",
6+
"linkId": "group-table",
7+
"item": [
8+
{
9+
"text": "Chart data",
10+
"type": "group",
11+
"repeats": true,
12+
"extension": [
13+
{
14+
"url": "https://emr-core.beda.software/StructureDefinition/enable-chart",
15+
"extension": [
16+
{
17+
"url": "link-id-x",
18+
"valueString": "date"
19+
},
20+
{
21+
"url": "link-id-y",
22+
"valueString": "weight"
23+
}
24+
]
25+
},
26+
{
27+
"url": "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl",
28+
"valueCodeableConcept": {
29+
"Coding": [
30+
{
31+
"code": "group-table"
32+
}
33+
]
34+
}
35+
}
36+
],
37+
"item": [
38+
{
39+
"text": "Date",
40+
"type": "date",
41+
"linkId": "date"
42+
},
43+
{
44+
"text": "Weight",
45+
"type": "quantity",
46+
"linkId": "weight",
47+
"extension": [
48+
{
49+
"url": "http://hl7.org/fhir/StructureDefinition/questionnaire-unitOption",
50+
"valueCoding": {
51+
"code": "kg",
52+
"system": "http://unitsofmeasure.org",
53+
"display": "kg"
54+
}
55+
}
56+
]
57+
}
58+
]
59+
}
60+
]
61+
}
62+
],
63+
"status": "draft",
64+
"subjectType": ["Patient"],
65+
"extension": [
66+
{
67+
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-assembledFrom",
68+
"valueCanonical": "enable-chart"
69+
}
70+
],
71+
"id": "example",
72+
"resourceType": "Questionnaire",
73+
"meta": {
74+
"profile": ["https://emr-core.beda.software/StructureDefinition/fhir-emr-questionnaire"],
75+
"lastUpdated": "2026-02-10T00:09:00.000000Z",
76+
"versionId": "205"
77+
}
78+
}

src/converter/extensions.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { FCEQuestionnaireItem, FCEQuestionnaireItemAnswerOptionsToggleExpressionOption } from '../fce.types';
21
import { Extension as FHIRExtension } from 'fhir/r4b';
2+
import { FCEQuestionnaireItem, FCEQuestionnaireItemAnswerOptionsToggleExpressionOption } from '../fce.types';
33

44
export enum ExtensionIdentifier {
55
Hidden = 'http://hl7.org/fhir/StructureDefinition/questionnaire-hidden',
@@ -51,6 +51,8 @@ export enum ExtensionIdentifier {
5151
SubQuestionnaire = 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-subQuestionnaire',
5252
MinOccurs = 'http://hl7.org/fhir/StructureDefinition/questionnaire-minOccurs',
5353
MaxOccurs = 'http://hl7.org/fhir/StructureDefinition/questionnaire-maxOccurs',
54+
55+
EnableChart = 'https://emr-core.beda.software/StructureDefinition/enable-chart',
5456
}
5557

5658
export type ExtensionTransformer = {
@@ -367,6 +369,41 @@ export const extensionTransformers: ExtensionTransformer = {
367369
[ExtensionIdentifier.Macro]: {
368370
path: { extension: 'valueString', questionnaire: 'macro' },
369371
},
372+
[ExtensionIdentifier.EnableChart]: {
373+
transform: {
374+
fromExtensions: (extensions) => {
375+
return {
376+
enableChart: extensions.map((extension) => {
377+
const enableChartExtension = extension.extension!;
378+
379+
return {
380+
linkIdX: enableChartExtension.find((obj) => obj.url === 'link-id-x')?.valueString,
381+
linkIdY: enableChartExtension.find((obj) => obj.url === 'link-id-y')?.valueString,
382+
};
383+
}),
384+
};
385+
},
386+
toExtensions: (item) => {
387+
if (item.enableChart) {
388+
return item.enableChart.map((enableChart) => ({
389+
url: ExtensionIdentifier.EnableChart,
390+
extension: [
391+
{
392+
url: 'link-id-x',
393+
valueString: enableChart.linkIdX,
394+
},
395+
{
396+
url: 'link-id-y',
397+
valueString: enableChart.linkIdY,
398+
},
399+
],
400+
}));
401+
}
402+
403+
return [];
404+
},
405+
},
406+
},
370407
};
371408

372409
function getExtensionValue(extension: FHIRExtension) {

src/fce.types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import {
88
Quantity,
99
Questionnaire,
1010
QuestionnaireItem,
11-
Reference,
1211
QuestionnaireItemAnswerOption,
12+
Reference,
1313
} from 'fhir/r4b';
1414

1515
export interface FCEQuestionnaire extends Questionnaire {
@@ -114,6 +114,7 @@ export interface FCEQuestionnaireItem extends QuestionnaireItem {
114114
choiceColumns?: number;
115115
ordinalValue?: number;
116116
mimeType?: string[];
117+
enableChart?: FCEQuestionnaireItemEnableChart[];
117118
}
118119

119120
export interface FCEQuestionnaireItemText {
@@ -172,6 +173,11 @@ export interface FCEQuestionnaireItemAnswerOptionsToggleExpression {
172173
option: Array<FCEQuestionnaireItemAnswerOptionsToggleExpressionOption>;
173174
}
174175

176+
export interface FCEQuestionnaireItemEnableChart {
177+
linkIdX?: string;
178+
linkIdY?: string;
179+
}
180+
175181
export interface FCEQuestionnaireLaunchContext {
176182
/** NOTE: from extension description */
177183
description?: string;

0 commit comments

Comments
 (0)