lforms 29.3.0 → 33.2.0

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.
Files changed (116) hide show
  1. package/CHANGELOG.md +261 -0
  2. package/README.md +97 -14
  3. package/changed-features.md +99 -0
  4. package/dist/lforms/LICENSE.md +70 -0
  5. package/dist/lforms/README.md +100 -0
  6. package/dist/lforms/fhir/R4/lformsFHIR.min.js +2 -0
  7. package/dist/lforms/fhir/R4/lformsFHIR.min.js.map +1 -0
  8. package/dist/lforms/fhir/STU3/lformsFHIR.min.js +2 -0
  9. package/dist/lforms/fhir/STU3/lformsFHIR.min.js.map +1 -0
  10. package/dist/lforms/fhir/lformsFHIRAll.min.js +2 -0
  11. package/dist/lforms/fhir/lformsFHIRAll.min.js.map +1 -0
  12. package/dist/lforms/webcomponent/assets/lib/zone.min.js +134 -0
  13. package/dist/lforms/webcomponent/down_arrow_gray_10_10.png +0 -0
  14. package/dist/lforms/webcomponent/favicon.ico +0 -0
  15. package/dist/lforms/webcomponent/index.html +9 -0
  16. package/dist/lforms/webcomponent/lhc-forms.js +2471 -0
  17. package/dist/lforms/webcomponent/magnifying_glass.png +0 -0
  18. package/dist/lforms/webcomponent/main.js +2464 -0
  19. package/dist/lforms/webcomponent/main.js.map +1 -0
  20. package/dist/lforms/webcomponent/polyfills.js +2 -0
  21. package/dist/lforms/webcomponent/polyfills.js.map +1 -0
  22. package/dist/lforms/webcomponent/runtime.js +2 -0
  23. package/dist/lforms/webcomponent/runtime.js.map +1 -0
  24. package/dist/lforms/webcomponent/scripts.js +3 -0
  25. package/dist/lforms/webcomponent/scripts.js.map +1 -0
  26. package/dist/lforms/webcomponent/styles.css +3 -0
  27. package/dist/lforms/webcomponent/styles.css.map +1 -0
  28. package/form_definition.md +382 -0
  29. package/lforms-33.2.0.tgz +0 -0
  30. package/package.json +94 -88
  31. package/r4-support.md +147 -0
  32. package/sdc-support.md +127 -0
  33. package/app/.npmignore +0 -3
  34. package/app/images/blank.gif +0 -0
  35. package/app/images/signal-stop.png +0 -0
  36. package/app/index.html +0 -10
  37. package/app/lforms.js +0 -56
  38. package/app/lforms.tpl.js +0 -964
  39. package/app/scripts/angular-packages.js +0 -11
  40. package/app/scripts/bootstrap-decorators.js +0 -31
  41. package/app/scripts/bower-index.js +0 -14
  42. package/app/scripts/fhir/R4/export.js +0 -33
  43. package/app/scripts/fhir/R4/fhirRequire.js +0 -36
  44. package/app/scripts/fhir/R4/lformsFHIR.js +0 -27260
  45. package/app/scripts/fhir/R4/sdc-export.js +0 -455
  46. package/app/scripts/fhir/R4/sdc-import.js +0 -483
  47. package/app/scripts/fhir/STU3/export.js +0 -27
  48. package/app/scripts/fhir/STU3/fhirRequire.js +0 -36
  49. package/app/scripts/fhir/STU3/lformsFHIR.js +0 -27291
  50. package/app/scripts/fhir/STU3/sdc-export.js +0 -493
  51. package/app/scripts/fhir/STU3/sdc-import.js +0 -494
  52. package/app/scripts/fhir/diagnostic-report.js +0 -707
  53. package/app/scripts/fhir/export-common.js +0 -209
  54. package/app/scripts/fhir/expression-processor.js +0 -670
  55. package/app/scripts/fhir/extensions/rendering-style.js +0 -23
  56. package/app/scripts/fhir/fhir-common.js +0 -3
  57. package/app/scripts/fhir/obs-prepop.mjs +0 -97
  58. package/app/scripts/fhir/runtime-common.js +0 -33
  59. package/app/scripts/fhir/sdc-common.js +0 -334
  60. package/app/scripts/fhir/sdc-export-common.js +0 -1046
  61. package/app/scripts/fhir/sdc-import-common.js +0 -1343
  62. package/app/scripts/fhir/versions.js +0 -8
  63. package/app/scripts/index.js +0 -20
  64. package/app/scripts/lforms-config.js +0 -12
  65. package/app/scripts/lforms-constants.js +0 -10
  66. package/app/scripts/lforms-controllers.js +0 -1196
  67. package/app/scripts/lforms-directives.js +0 -424
  68. package/app/scripts/lforms-index.js +0 -20
  69. package/app/scripts/lib/cross_browser.js +0 -21
  70. package/app/scripts/lib/lforms-data.js +0 -3591
  71. package/app/scripts/lib/lforms-hl7.js +0 -525
  72. package/app/scripts/lib/lforms-util.js +0 -1122
  73. package/app/scripts/lib/lforms-validate.js +0 -277
  74. package/app/scripts/lib/polyfill.js +0 -81
  75. package/app/scripts/themeList.js +0 -17
  76. package/app/styles/lforms.css +0 -1219
  77. package/app/styles/redmond-theme/README.txt +0 -2
  78. package/app/styles/redmond-theme/images/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
  79. package/app/styles/redmond-theme/images/ui-bg_glass_85_dfeffc_1x400.png +0 -0
  80. package/app/styles/redmond-theme/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  81. package/app/styles/redmond-theme/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
  82. package/app/styles/redmond-theme/images/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
  83. package/app/styles/redmond-theme/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
  84. package/app/styles/redmond-theme/images/ui-icons_217bc0_256x240.png +0 -0
  85. package/app/styles/redmond-theme/images/ui-icons_2e83ff_256x240.png +0 -0
  86. package/app/styles/redmond-theme/images/ui-icons_469bdd_256x240.png +0 -0
  87. package/app/styles/redmond-theme/images/ui-icons_6da8d5_256x240.png +0 -0
  88. package/app/styles/redmond-theme/images/ui-icons_cd0a0a_256x240.png +0 -0
  89. package/app/styles/redmond-theme/images/ui-icons_d8e7f3_256x240.png +0 -0
  90. package/app/styles/redmond-theme/images/ui-icons_f9bd01_256x240.png +0 -0
  91. package/app/styles/redmond-theme/jquery-ui.css +0 -1311
  92. package/app/styles/redmond-theme/jquery-ui.min.css +0 -7
  93. package/app/styles/redmond-theme/theme.css +0 -443
  94. package/app/styles/themes.css +0 -1541
  95. package/app/styles/themes.css.map +0 -9
  96. package/app/styles/themes.scss +0 -411
  97. package/app/version.json +0 -1
  98. package/app/views/partials/attachment.html +0 -38
  99. package/app/views/partials/field-answers.html +0 -67
  100. package/app/views/partials/field-units.html +0 -24
  101. package/app/views/partials/form-controls.html +0 -19
  102. package/app/views/partials/form-header.html +0 -35
  103. package/app/views/partials/form-options.html +0 -50
  104. package/app/views/partials/form-title.html +0 -20
  105. package/app/views/partials/form-view.html +0 -13
  106. package/app/views/partials/item-options.html +0 -48
  107. package/app/views/partials/item.html +0 -126
  108. package/app/views/partials/itemPrefixAndText.html +0 -4
  109. package/app/views/partials/layout-horizontal.html +0 -156
  110. package/app/views/partials/layout-matrix.html +0 -145
  111. package/app/views/partials/popover-content.html +0 -1
  112. package/app/views/partials/repeating-button.html +0 -16
  113. package/app/views/partials/table-item.html +0 -30
  114. package/app/views/partials/template-table.html +0 -69
  115. package/app/views/partials/uib-popover-templates/uib-popover-template.html +0 -13
  116. package/app/views/partials/uib-popover-templates/uib-popover.html +0 -11
@@ -1,707 +0,0 @@
1
- /**
2
- * A package to handle FHIR DiagnosticReport for LForms
3
- * https://www.hl7.org/fhir/diagnosticreport.html
4
- *
5
- * Note that this was written for DSTU2 and has not been updated.
6
- *
7
- * It provides the following functions:
8
- * createDiagnosticReport()
9
- * -- Convert existing LOINC panels/forms data in LForms format into FHIR DiagnosticReport data
10
- * mergeDiagnosticReportToLForms()
11
- * -- Merge FHIR SDC DiagnosticReport data into corresponding LForms data
12
- */
13
-
14
- var LForms = require('../lforms-index');
15
-
16
- var dr = {
17
-
18
- // a prefix for references to Observation resources
19
- _OBX_REF_PREFIX: "Observation/",
20
-
21
-
22
- /**
23
- * Functions for creating a DiagnosticReport instance from an LFormsData object
24
- */
25
-
26
- /** Get date in a standard string format
27
- * @param dateObj, a date object
28
- * @returns {string} a formatted date string
29
- * @private
30
- */
31
- _getFormattedDate : function (dateObj) {
32
- //"2013-01-27T11:45:33+11:00",
33
- return dateObj ? LForms.Util.dateToDTMString(dateObj) : "";
34
- },
35
-
36
-
37
- /**
38
- * Get the additional data in a form's formHeaderItems
39
- * Note: For DiagnosticReport only the effectiveDateTime is needed
40
- * @param formData an LFormsData object
41
- * @returns {{}} the extra data captured in the "OBR" fields of an LForms form
42
- * @private
43
- */
44
- _getExtensionData : function(formData) {
45
- var extension = {};
46
- if (formData.templateOptions.formHeaderItems &&
47
- formData.templateOptions.formHeaderItems.length>0) {
48
- for(var i=0, iLen= formData.templateOptions.formHeaderItems.length; i<iLen; i++) {
49
- var obrItem = formData.templateOptions.formHeaderItems[i];
50
- if (obrItem.questionCode === 'date_done' && obrItem.value) {
51
- extension["lforms_dateDone"] = obrItem.value;
52
- }
53
-
54
- if (obrItem.questionCode === 'where_done' && obrItem.value) {
55
- extension["lforms_whereDone"] = {
56
- display: obrItem.value.text
57
- }
58
- }
59
- if (obrItem.questionCode === 'time_done' && obrItem.value) {
60
- extension["lforms_timeDone"] = obrItem.value;
61
- }
62
- if (obrItem.questionCode === 'comment' && obrItem.value) {
63
- extension["lforms_comments"] = obrItem.value;
64
- }
65
-
66
- }
67
- }
68
- return extension;
69
- },
70
-
71
-
72
- /**
73
- * A recursive function that generates the DiagnosticReport content by
74
- * going through the LForms form data structure
75
- * @param item an LForms item
76
- * @param contained the "contained" field in a DiagnosticReport where all the Observation instances are kept.
77
- * @returns {{result: Array, resultObj: Array}} the content part of a Diagnostic Report instance
78
- * @private
79
- */
80
- _createDiagnosticReportContent : function (item, contained) {
81
- // return the content of "result" and "contained"
82
- var content = {
83
- result: [],
84
- resultObj: []
85
- };
86
-
87
- for(var i=0, iLen=item.items.length; i<iLen; i++) {
88
- var subItem = item.items[i];
89
- if (subItem) {
90
- var obx = this._commonExport._createObservation(subItem, true);
91
- if (subItem.items && subItem.items.length>0) {
92
- // single obx returned if it is a header item
93
- obx[0].related = [];
94
- var ret = this._createDiagnosticReportContent(subItem, contained);
95
- for(var j=0, jLen=ret.result.length; j<jLen; j++) {
96
- var subObxRef = ret.result[j];
97
- obx[0].related.push({
98
- type: "has-member",
99
- target: {
100
- reference: subObxRef.reference
101
- }
102
- });
103
- }
104
- }
105
- for (var l=0, lLen=obx.length; l<lLen; l++) {
106
- contained.push(obx[l]);
107
- content.result.push({
108
- reference: "#" + obx[l].id
109
- });
110
- content.resultObj.push(obx[l]);
111
- }
112
- }
113
- }
114
- return content;
115
- },
116
-
117
-
118
- /**
119
- * Convert a DiagnosticReport resource with contained Observation resources to
120
- * a FHIR Bundle resource that includes a DiagnosticReport resource and associated Observation resources
121
- * @param dr a DiagnosticReport resource with contained Observation resources
122
- * @param bundleType the FHIR Bundle type. Only "transaction" and "collection" types are allowed.
123
- * @returns {{}} a Bundle resource that includes a DiagnosticReport resource and associated Observation resources
124
- */
125
- _convertFromContainedToBundle: function (dr, bundleType) {
126
- var bundleDr = {};
127
-
128
- // default bundleType
129
- if (!bundleType) {
130
- bundleType = "transaction";
131
- }
132
- if (dr) {
133
- switch(bundleType) {
134
- case "transaction":
135
- bundleDr = this._convertContainedToTransactionBundle(dr);
136
- break;
137
- case "collection":
138
- bundleDr = this._convertContainedToCollectionBundle(dr);
139
- break;
140
- default:
141
- console.log("Bundle type not supported: " + bundleType);
142
- }
143
- }
144
- return bundleDr;
145
- },
146
-
147
-
148
- /**
149
- * Convert a DiagnosticReport resource with contained Observation resources to
150
- * a FHIR "transaction" typed Bundle resource that includes a DiagnosticReport resource
151
- * and associated Observation resources
152
- * @param dr a DiagnosticReport resource with contained Observation resources
153
- * @returns {{}} a Bundle resource that includes a DiagnosticReport resource and associated Observation resources
154
- * @private
155
- */
156
- _convertContainedToTransactionBundle: function(dr) {
157
-
158
- var bundleDr = {
159
- resourceType:"Bundle",
160
- type: "transaction",
161
- entry: []
162
- };
163
-
164
- var contained = dr.contained;
165
- delete dr.contained;
166
-
167
- // update reference to Observation resources
168
- for (var i=0, iLen=dr.result.length; i<iLen; i++) {
169
- var ref = dr.result[i];
170
- ref.reference = this._OBX_REF_PREFIX + ref.reference.slice(1);
171
- }
172
- // add DiagnosticReport resource into Bundle entry
173
- bundleDr.entry.push({
174
- resource: dr,
175
- request: {
176
- method: "POST",
177
- url: "DiagnosticReport"
178
- }
179
- });
180
-
181
- // add Observation resources into Bundle entry
182
- for (var j=0, jLen=contained.length; j<jLen; j++) {
183
- var res = contained[j];
184
-
185
- // if it has related Observation resources (as it is a section in LForms)
186
- // update values of the references to the related Observation resources
187
- if (res.related) {
188
- for (var k=0, kLen=res.related.length; k<kLen; k++) {
189
- var targetObservation = res.related[k];
190
- targetObservation.target.reference = this._OBX_REF_PREFIX + targetObservation.target.reference.slice(1);
191
- }
192
- }
193
-
194
- // add to the Bundle entry
195
- bundleDr.entry.push({
196
- resource: res,
197
- request: {
198
- method: "POST",
199
- url: "Observation"
200
- }
201
- });
202
- }
203
-
204
- return bundleDr;
205
- },
206
-
207
-
208
- /**
209
- * Convert a DiagnosticReport resource with contained Observation resources to
210
- * a FHIR "collection" typed Bundle resource that includes a DiagnosticReport resource
211
- * and associated Observation resources
212
- * @param dr a DiagnosticReport resource with contained Observation resources
213
- * @returns {{}} a Bundle resource that includes a DiagnosticReport resource and associated Observation resources
214
- * @private
215
- */
216
- _convertContainedToCollectionBundle: function(dr) {
217
- var bundleDr = {
218
- resourceType:"Bundle",
219
- type: "collection",
220
- entry: []
221
- };
222
-
223
- var contained = dr.contained;
224
- delete dr.contained;
225
-
226
- // add DiagnosticReport resource into Bundle entry
227
- bundleDr.entry.push({
228
- resource: dr
229
- });
230
-
231
- // add Observation resources into Bundle entry
232
- for (var j=0, jLen=contained.length; j<jLen; j++) {
233
- var res = contained[j];
234
- // add to the Bundle entry
235
- bundleDr.entry.push({
236
- resource: res
237
- });
238
- }
239
-
240
- return bundleDr;
241
- },
242
-
243
-
244
- /**
245
- * Generate FHIR DiagnosticReport data from an LForms form data
246
- * @param formData an LFormsData object
247
- * @param subject optional, A local FHIR resource that is the subject for this
248
- * DiagnoticReport.
249
- * @param inBundle optional, a flag that a DiagnosticReport resources and associated Observation resources
250
- * should be placed into a FHIR Bundle. The default is false.
251
- * @param bundleType, optional, the FHIR Bundle type if inBundle is true.
252
- * Only "transaction" and "collection" types are allowed.
253
- * @returns {{}} a Diagnostic Report instance
254
- */
255
- createDiagnosticReport : function(formData, subject, inBundle, bundleType) {
256
- var dr = null, contained =[];
257
- if (formData) {
258
-
259
- var formAndUserData = formData.getFormData(true,true,true);
260
-
261
- var drContent = this._createDiagnosticReportContent(formAndUserData, contained);
262
-
263
- dr = {
264
- resourceType: "DiagnosticReport",
265
- id: this._commonExport._getUniqueId(formAndUserData.code),
266
- status: "final",
267
- code: {
268
- "coding": [
269
- {
270
- "system": "http://loinc.org",
271
- "code": formAndUserData.code,
272
- "display": formAndUserData.name
273
- }
274
- ],
275
- "text": formAndUserData.name
276
- },
277
- result: drContent.result,
278
- contained: contained
279
- };
280
- this._commonExport._addVersionTag(dr);
281
-
282
- if (subject)
283
- dr.subject = LForms.Util.createLocalFHIRReference(subject);
284
-
285
- // obr data
286
- var extension = this._getExtensionData(formAndUserData);
287
- if (extension["lforms_dateDone"]) {
288
- dr["effectiveDateTime"] = extension["lforms_dateDone"];
289
- }
290
- // issued
291
- dr["issued"] = this._getFormattedDate(new Date());
292
- }
293
-
294
- var ret = inBundle ? this._convertFromContainedToBundle(dr, bundleType) : dr;
295
- LForms.Util.pruneNulls(ret);
296
- return ret;
297
- },
298
-
299
-
300
- /**
301
- * Functions for merging a DiagnosticReport instance into an LFormsData object
302
- */
303
-
304
- /**
305
- * Find an observation from the "contained" list by an observation id
306
- * @param refId an observation instance's id
307
- * @param contained the "contained" field in a DiagnosticReport instance
308
- * @returns {{}} an observation instance
309
- * @private
310
- */
311
- _findObxById : function(refId, contained) {
312
- var obx = null;
313
- if (refId) {
314
- var id = refId[0] === "#" ? refId.slice(1) : refId;
315
- for(var i=0, iLen=contained.length; i<iLen; i++) {
316
- if (contained[i].id === id) {
317
- obx = contained[i];
318
- break;
319
- }
320
- }
321
- }
322
- return obx;
323
- },
324
-
325
-
326
- /**
327
- * Merge an Observation instance into an item object
328
- * @param obx an observation instance
329
- * @param item an item in an LForms object
330
- * @private
331
- */
332
- _setupItemValueAndUnit : function(obx, item) {
333
- if (item && obx.code.coding[0].code === item.questionCode) {
334
- var dataType = item.dataType;
335
- // any one has a unit must be a numerical type, let use REAL for now.
336
- // dataType conversion should be handled when panel data are added to lforms-service.
337
- if ((!dataType || dataType==="ST") && item.units && item.units.length>0 ) {
338
- dataType = "REAL";
339
- }
340
-
341
- switch (dataType) {
342
- case "INT":
343
- if (obx.valueInteger) {
344
- item.value = obx.valueInteger;
345
- break;
346
- }
347
- // else handle as Quantity
348
- case "REAL": // handle as Quantity
349
- case "QTY":
350
- let qty = obx.valueQuantity;
351
- item.value = qty.value;
352
- let unitName = qty.unit || qty.code;
353
- if (unitName || qty.code || qty.system) {
354
- item.unit = {};
355
- if (unitName)
356
- item.unit.name = unitName;
357
- if (qty.code)
358
- item.unit.code = qty.code;
359
- if (qty.system)
360
- item.unit.system = qty.system;
361
- }
362
- break;
363
- case "DT":
364
- item.value = LForms.Util.stringToDTDateISO(obx.valueDate);
365
- break;
366
- case "DTM":
367
- item.value = LForms.Util.stringToDate(obx.valueDateTime);
368
- break;
369
- case "CNE":
370
- case "CWE":
371
- // get the value from Observation resource.
372
- // for multiple-selected answers/values in LForms, each selected answer is exported as
373
- // a separated Observation resource
374
- var itemValue;
375
- if (obx.valueCodeableConcept) {
376
- itemValue = {
377
- "code": obx.valueCodeableConcept.coding[0].code,
378
- "text": obx.valueCodeableConcept.coding[0].display,
379
- "codeSystem": obx.valueCodeableConcept.coding[0].system
380
- };
381
- }
382
- else if (obx.valueString) {
383
- itemValue = obx.valueString;
384
- }
385
-
386
- if (item.answerCardinality &&
387
- (item.answerCardinality.max === "*" || parseInt(item.answerCardinality.max) > 1)) {
388
- if (!item.value) {
389
- item.value = [];
390
- }
391
- item.value.push(itemValue)
392
- }
393
- else {
394
- item.value = itemValue;
395
- }
396
- break;
397
- case "SECTION":
398
- case "TITLE":
399
- case "":
400
- // do nothing
401
- break;
402
- default:
403
- item.value = obx.valueString;
404
- }
405
- }
406
- },
407
-
408
-
409
- /**
410
- * Find the number of the repeating items that have the same code
411
- * in the "contained" field of a DiagnosticReport instance
412
- * @param refIdList a list Observation instance IDs to be checked
413
- * @param code an item code
414
- * @param contained a list of Observation instances (in the "contained")
415
- * @returns a structural info object for a repeating item
416
- * of the repeating items
417
- * @private
418
- */
419
- _findTotalRepeatingNum : function(refIdList, code, contained) {
420
-
421
- var total = 0;
422
- var refIds = [];
423
- for (var i=0, iLen=refIdList.length; i<iLen; i++) {
424
- var obx = this._findObxById(refIdList[i], contained);
425
- if (obx.code.coding[0].code === code) {
426
- refIds.push(refIdList[i]);
427
- total += 1;
428
- }
429
- }
430
-
431
- return {
432
- total: total,
433
- refIds: refIds
434
- }
435
- },
436
-
437
-
438
- /**
439
- * Get structural info of a DiagnosticReport by going though each level of observations
440
- * @param parentObxInfo the structural info of a parent Observation
441
- * @param parentRefId the instance ID of a parent Observation
442
- * @param diagnosticReport a DiagnosticReport instance
443
- * @private
444
- */
445
- _checkRepeatingItems : function(parentObxInfo, parentRefId, diagnosticReport) {
446
-
447
- var obxInfoList = [];
448
- var repeatingItemInfo = {};
449
- var obxIdList = [];
450
-
451
- // the report level
452
- if (!parentRefId && diagnosticReport.result) {
453
- for (var i=0, iLen=diagnosticReport.result.length; i<iLen; i++) {
454
- obxIdList.push(diagnosticReport.result[i].reference);
455
- }
456
- }
457
- // obx level
458
- else {
459
- var parentObx = this._findObxById(parentRefId, diagnosticReport.contained);
460
- if (parentObx && parentObx.related) {
461
- for (var i=0, iLen=parentObx.related.length; i<iLen; i++) {
462
- obxIdList.push(parentObx.related[i].target.reference);
463
- }
464
- }
465
- }
466
-
467
- // go through each observation instance
468
- for (var i=0, iLen=obxIdList.length; i<iLen; i++) {
469
- var refId = obxIdList[i];
470
- var obx = this._findObxById(refId, diagnosticReport.contained);
471
- var itemCode = obx.code.coding[0].code;
472
- // first obx that has the same item code, either repeating or non-repeating
473
- if (!repeatingItemInfo[itemCode]) {
474
- var repeatingInfo = this._findTotalRepeatingNum(obxIdList, itemCode, diagnosticReport.contained);
475
- repeatingItemInfo[itemCode] = {
476
- total: repeatingInfo.total,
477
- refIds: repeatingInfo.refIds
478
- };
479
- }
480
- // create structure info for the obx
481
- var repeatingRefIds = repeatingItemInfo[itemCode].refIds;
482
- for (var j=0, jLen=repeatingRefIds.length; j<jLen; j++) {
483
- if (refId === repeatingRefIds[j]) {
484
- var obxInfo = {
485
- code: itemCode,
486
- refId: refId,
487
- index: j,
488
- total: repeatingItemInfo[itemCode].total
489
- };
490
- // check observation instances in the sub level
491
- this._checkRepeatingItems(obxInfo, refId, diagnosticReport);
492
- obxInfoList.push(obxInfo);
493
- }
494
- }
495
- }
496
- parentObxInfo.obxInfoList = obxInfoList;
497
- },
498
-
499
-
500
- /**
501
- * Get structure information of a DiagnosticReport instance
502
- * @param diagnosticReport a DiagnosticReport instance
503
- * @returns {{}} a Diagnostic Report data structure object
504
- * @private
505
- */
506
- _getReportStructure : function(diagnosticReport) {
507
- var reportStructure = {
508
- obxInfoList: []
509
- };
510
-
511
- if (diagnosticReport) {
512
- this._checkRepeatingItems(reportStructure, null, diagnosticReport);
513
- }
514
- return reportStructure;
515
- },
516
-
517
-
518
- /**
519
- * Find a matching repeating item
520
- * @param parentItem a parent item
521
- * @param itemCode code of a repeating (or non-repeating) item
522
- * @param index index of the item in the sub item array of the parent item
523
- * @returns {{}} a matching item
524
- * @private
525
- */
526
- _findTheMatchingItemByCodeAndIndex : function(parentItem, itemCode, index) {
527
- var item = null;
528
- var idx = 0;
529
- if (parentItem.items) {
530
- for(var i=0, iLen=parentItem.items.length; i<iLen; i++) {
531
- var subItem = parentItem.items[i];
532
- if (itemCode === subItem.questionCode) {
533
- if ((subItem.dataType === "CNE" || subItem.dataType === "CWE") &&
534
- subItem.answerCardinality && (subItem.answerCardinality.max ==="*" || parseInt(subItem.answerCardinality.max)>1) ) {
535
- item = subItem;
536
- break;
537
-
538
- }
539
- else if (idx === index) {
540
- item = subItem;
541
- break;
542
- }
543
- else {
544
- idx += 1;
545
- }
546
- }
547
- }
548
- }
549
- return item;
550
- },
551
-
552
-
553
- /**
554
- * Add repeating items
555
- * @param parentItem a parent item
556
- * @param itemCode code of a repeating item
557
- * @param total total number of the repeating item with the same code
558
- * @private
559
- */
560
- _addRepeatingItems : function(parentItem, itemCode, total) {
561
- // find the first (and the only one) item
562
- var item = null;
563
- if (parentItem.items) {
564
- for(var i=0, iLen=parentItem.items.length; i<iLen; i++) {
565
- if (itemCode === parentItem.items[i].questionCode) {
566
- item = parentItem.items[i];
567
- break;
568
- }
569
- }
570
- // insert new items unless it is a CNE/CWE and has multiple answers.
571
- if (item && !((item.dataType === "CNE" || item.dataType ==="CWE") &&
572
- item.answerCardinality &&
573
- (item.answerCardinality.max === "*" || parseInt(item.answerCardinality.max) > 1))) {
574
- while(total > 1) {
575
- var newItem = LForms.Util.deepCopy(item);
576
- parentItem.items.splice(i, 0, newItem);
577
- total -= 1;
578
- }
579
- }
580
- }
581
- },
582
-
583
-
584
- /**
585
- * Merge Observation instances into items on the same level
586
- * @param parentObxInfo structural information of a parent item
587
- * @param parentItem a parent item
588
- * @param diagnosticReport a DiagnosticReport instance
589
- * @private
590
- */
591
- _processObxAndItem : function(parentObxInfo, parentItem, diagnosticReport) {
592
- for(var i=0, iLen=parentObxInfo.obxInfoList.length; i<iLen; i++) {
593
-
594
- var obxInfo = parentObxInfo.obxInfoList[i];
595
- var obx = this._findObxById(obxInfo.refId, diagnosticReport.contained);
596
- if (obx) {
597
- // first repeating obx
598
- if (obxInfo.total > 1 && obxInfo.index === 0) {
599
- // add repeating items in form data
600
- this._addRepeatingItems(parentItem, obxInfo.code, obxInfo.total);
601
- }
602
-
603
- var item = this._findTheMatchingItemByCodeAndIndex(parentItem, obxInfo.code, obxInfo.index);
604
- this._setupItemValueAndUnit(obx, item);
605
-
606
- // process items on sub level
607
- if (obxInfo.obxInfoList && obxInfo.obxInfoList.length>0) {
608
- this._processObxAndItem(obxInfo, item, diagnosticReport);
609
- }
610
- }
611
- }
612
- },
613
-
614
- /**
615
- * Convert a FHIR Bundle resource that includes a DiagnosticReport resource and associated Observation resources
616
- * to a DiagnosticReport resource with contained Observation resources
617
- * @param bundleDr a Bundle that includes a DiagnosticReport resource and associated Observation resources.
618
- * Only "searchset" type is allowed.
619
- * @returns {{}} a DiagnosticReport resource with contained Observation resources
620
- */
621
- _convertFromBundleToContained: function (bundleDr) {
622
-
623
- var containedDr;
624
- // "searchset" is the only supported type at this point.
625
- if (bundleDr && bundleDr.type === "searchset") {
626
- var entry = bundleDr.entry;
627
- // find the DiagnosticReport in the bundle
628
- for (var i=0, iLen=entry.length; i<iLen; i++) {
629
- if (entry[i].resource.resourceType === "DiagnosticReport") {
630
- containedDr = entry[i].resource;
631
- // change reference ids in result
632
- for (var j=0, jLen=containedDr.result.length; j<jLen; j++) {
633
- var ref = containedDr.result[j];
634
- if (ref.reference && ref.reference.match(new RegExp(this._OBX_REF_PREFIX))) {
635
- ref.reference = ref.reference.slice(this._OBX_REF_PREFIX.length);
636
- }
637
- }
638
- containedDr.contained =[];
639
- break;
640
- }
641
- }
642
- // if DiagnosticReport is found
643
- if (containedDr) {
644
- // Move all Observation resource into "contained" field of the DiagnosticReport resource
645
- for (var i=0, iLen=entry.length; i<iLen; i++) {
646
- if (entry[i].resource.resourceType === "Observation") {
647
- var obx = entry[i].resource;
648
- // change reference ids in related
649
- if (obx.related) {
650
- for (var j=0, jLen=obx.related.length; j<jLen; j++) {
651
- var related = obx.related[j];
652
- if (related.target && related.target.reference &&
653
- related.target.reference.match(new RegExp(this._OBX_REF_PREFIX))) {
654
- related.target.reference = related.target.reference.slice(this._OBX_REF_PREFIX.length);
655
- }
656
- }
657
- }
658
- containedDr.contained.push(obx)
659
- }
660
- }
661
- }
662
- }
663
-
664
- return containedDr;
665
- },
666
-
667
-
668
- /**
669
- * Merge a DiagnosticReport instance into an LForms form definition or LFormsData object
670
- * @param formData an LForms form definition or LFormsData object.
671
- * @param diagnosticReport a DiagnosticReport resource with contained Observation resources,
672
- * or a Bundle that includes a DiagnosticReport resource and associated Observation resources
673
- * @param bundleType, optional, the FHIR Bundle type if inBundle is true.
674
- * @returns {{}} an updated LForms form definition, with answer data
675
- */
676
- mergeDiagnosticReportToLForms : function(formData, diagnosticReport) {
677
-
678
- if (!(formData instanceof LForms.LFormsData)) {
679
- // get the default settings in case they are missing in the form data
680
- // not to set item values by default values for saved forms with user data
681
- formData.hasSavedData = true;
682
- formData = (new LForms.LFormsData(formData)).getFormData();
683
- }
684
-
685
- var inBundle = diagnosticReport && diagnosticReport.resourceType === "Bundle";
686
-
687
- // move Observation resources in Bundle to be in "contained" in DiagnosticReport resource
688
- // as a base data structure for converting
689
- var dr = inBundle ? this._convertFromBundleToContained(diagnosticReport) : diagnosticReport;
690
-
691
- var reportStructure = this._getReportStructure(dr);
692
-
693
- this._processObxAndItem(reportStructure, formData, dr);
694
-
695
- // date
696
- if (dr.effectiveDateTime && formData.templateOptions.formHeaderItems) {
697
- var whenDone = new LForms.Util.dateToString(dr.effectiveDateTime);
698
- if (whenDone) {
699
- formData.templateOptions.formHeaderItems[0].value = whenDone;
700
- }
701
- }
702
- return formData;
703
- }
704
-
705
- };
706
-
707
- export default dr;