@aehrc/smart-forms-renderer 0.21.2 → 0.22.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 (33) hide show
  1. package/lib/components/FormComponents/DateTimeItems/CustomDateTimeItem/CustomDateTimeItem.js +0 -1
  2. package/lib/components/FormComponents/DateTimeItems/CustomDateTimeItem/CustomDateTimeItem.js.map +1 -1
  3. package/lib/components/FormComponents/DecimalItem/DecimalField.js +1 -1
  4. package/lib/components/FormComponents/DecimalItem/DecimalField.js.map +1 -1
  5. package/lib/components/FormComponents/DecimalItem/DecimalItem.js +2 -2
  6. package/lib/components/FormComponents/DecimalItem/DecimalItem.js.map +1 -1
  7. package/lib/hooks/useRenderingExtensions.d.ts +4 -3
  8. package/lib/hooks/useRenderingExtensions.js +4 -3
  9. package/lib/hooks/useRenderingExtensions.js.map +1 -1
  10. package/lib/hooks/useValidationFeedback.d.ts +1 -1
  11. package/lib/hooks/useValidationFeedback.js +10 -6
  12. package/lib/hooks/useValidationFeedback.js.map +1 -1
  13. package/lib/stores/questionnaireResponseStore.d.ts +3 -4
  14. package/lib/stores/questionnaireResponseStore.js +3 -5
  15. package/lib/stores/questionnaireResponseStore.js.map +1 -1
  16. package/lib/utils/debounce.d.ts +1 -1
  17. package/lib/utils/debounce.js +1 -1
  18. package/lib/utils/itemControl.d.ts +3 -3
  19. package/lib/utils/itemControl.js +14 -8
  20. package/lib/utils/itemControl.js.map +1 -1
  21. package/lib/utils/validateQuestionnaire.d.ts +44 -5
  22. package/lib/utils/validateQuestionnaire.js +278 -42
  23. package/lib/utils/validateQuestionnaire.js.map +1 -1
  24. package/package.json +1 -1
  25. package/src/components/FormComponents/DateTimeItems/CustomDateTimeItem/CustomDateTimeItem.tsx +0 -1
  26. package/src/components/FormComponents/DecimalItem/DecimalField.tsx +1 -0
  27. package/src/components/FormComponents/DecimalItem/DecimalItem.tsx +16 -3
  28. package/src/hooks/useRenderingExtensions.ts +7 -5
  29. package/src/hooks/useValidationFeedback.ts +20 -8
  30. package/src/stores/questionnaireResponseStore.ts +5 -9
  31. package/src/utils/debounce.ts +1 -1
  32. package/src/utils/itemControl.ts +18 -10
  33. package/src/utils/validateQuestionnaire.ts +352 -51
@@ -16,8 +16,50 @@
16
16
  */
17
17
  import { getQrItemsIndex, mapQItemsIndex } from './mapItem';
18
18
  import { isHiddenByEnableWhen } from './qItem';
19
- import { getRegexValidation } from './itemControl';
19
+ import { getRegexString, getRegexValidation, getShortText } from './itemControl';
20
20
  import { structuredDataCapture } from 'fhir-sdc-helpers';
21
+ export var ValidationResult;
22
+ (function (ValidationResult) {
23
+ ValidationResult["unknown"] = "unknown";
24
+ ValidationResult["questionnaireNotFound"] = "questionnaireNotFound";
25
+ ValidationResult["questionnaireInactive"] = "questionnaireInactive";
26
+ ValidationResult["questionnaireDraft"] = "questionnaireDraft";
27
+ ValidationResult["questionnaireRetired"] = "questionnaireRetired";
28
+ ValidationResult["invalidLinkId"] = "invalidLinkId";
29
+ ValidationResult["invalidType"] = "invalidType";
30
+ ValidationResult["invalidAnswerType"] = "invalidAnswerType";
31
+ ValidationResult["invalidAnswerOption"] = "invalidAnswerOption";
32
+ ValidationResult["exclusiveAnswerOption"] = "exclusiveAnswerOption";
33
+ ValidationResult["invalidUrlValue"] = "invalidUrlValue";
34
+ ValidationResult["groupShouldNotHaveAnswers"] = "groupShouldNotHaveAnswers";
35
+ ValidationResult["required"] = "required";
36
+ ValidationResult["invariant"] = "invariant";
37
+ ValidationResult["invariantExecution"] = "invariantExecution";
38
+ ValidationResult["repeats"] = "repeats";
39
+ ValidationResult["minCount"] = "minCount";
40
+ ValidationResult["maxCount"] = "maxCount";
41
+ ValidationResult["minValue"] = "minValue";
42
+ ValidationResult["maxValue"] = "maxValue";
43
+ ValidationResult["maxDecimalPlaces"] = "maxDecimalPlaces";
44
+ ValidationResult["minLength"] = "minLength";
45
+ ValidationResult["maxLength"] = "maxLength";
46
+ ValidationResult["invalidNewLine"] = "invalidNewLine";
47
+ ValidationResult["invalidCoding"] = "invalidCoding";
48
+ ValidationResult["tsError"] = "tsError";
49
+ ValidationResult["maxAttachmentSize"] = "maxAttachmentSize";
50
+ ValidationResult["attachmentSizeInconsistent"] = "attachmentSizeInconsistent";
51
+ ValidationResult["invalidAttachmentType"] = "invalidAttachmentType";
52
+ ValidationResult["displayAnswer"] = "displayAnswer";
53
+ ValidationResult["regex"] = "regex";
54
+ ValidationResult["regexTimeout"] = "regexTimeout";
55
+ ValidationResult["invalidRefValue"] = "invalidRefValue";
56
+ ValidationResult["invalidRefResourceType"] = "invalidRefResourceType";
57
+ ValidationResult["invalidRefResourceTypeRestriction"] = "invalidRefResourceTypeRestriction";
58
+ ValidationResult["minValueIncompatUnits"] = "minValueIncompatUnits";
59
+ ValidationResult["maxValueIncompatUnits"] = "maxValueIncompatUnits";
60
+ ValidationResult["invalidUnit"] = "invalidUnit";
61
+ ValidationResult["invalidUnitValueSet"] = "invalidUnitValueSet"; // The unit provided was not in the provided valueset
62
+ })(ValidationResult || (ValidationResult = {}));
21
63
  /**
22
64
  * Recursively go through the questionnaireResponse and check for un-filled required qItems
23
65
  * At the moment item.required for group items are not checked
@@ -26,41 +68,61 @@ import { structuredDataCapture } from 'fhir-sdc-helpers';
26
68
  */
27
69
  export function validateQuestionnaire(params) {
28
70
  var _a;
29
- const { questionnaire, questionnaireResponse, invalidItems, enableWhenIsActivated, enableWhenItems, enableWhenExpressions } = params;
71
+ const { questionnaire, questionnaireResponse, enableWhenIsActivated, enableWhenItems, enableWhenExpressions } = params;
30
72
  if (!questionnaire.item ||
31
73
  questionnaire.item.length === 0 ||
32
74
  !questionnaireResponse.item ||
33
75
  questionnaireResponse.item.length === 0) {
34
- return invalidItems;
76
+ return {};
35
77
  }
36
78
  const qItemsIndexMap = mapQItemsIndex(questionnaire);
37
79
  const topLevelQRItemsByIndex = getQrItemsIndex(questionnaire.item, questionnaireResponse.item, qItemsIndexMap);
80
+ const invalidItems = {};
81
+ let qrItemIndex = 0;
38
82
  for (const [index, topLevelQItem] of questionnaire.item.entries()) {
83
+ let repeatGroupInstances = null;
39
84
  let topLevelQRItem = (_a = topLevelQRItemsByIndex[index]) !== null && _a !== void 0 ? _a : {
40
85
  linkId: topLevelQItem.linkId,
41
86
  text: topLevelQItem.text
42
87
  };
88
+ // topLevelQRItem being an array means this item is a repeat group
89
+ const isRepeatGroup = Array.isArray(topLevelQRItem);
43
90
  if (Array.isArray(topLevelQRItem)) {
91
+ repeatGroupInstances = topLevelQRItem.length;
44
92
  topLevelQRItem = {
45
93
  linkId: topLevelQItem.linkId,
46
94
  text: topLevelQItem.text,
47
95
  item: topLevelQRItem
48
96
  };
49
97
  }
98
+ const locationExpression = `QuestionnaireResponse.item`;
50
99
  validateItemRecursive({
51
100
  qItem: topLevelQItem,
52
101
  qrItem: topLevelQRItem,
53
- invalidItems: invalidItems,
102
+ qrItemIndex,
103
+ locationExpression,
104
+ invalidItems,
54
105
  enableWhenIsActivated,
55
106
  enableWhenItems,
56
- enableWhenExpressions
107
+ enableWhenExpressions,
108
+ isRepeatGroupInstance: false
57
109
  });
110
+ // Increment qrItemIndex
111
+ // If its a repeat group, increment by the number of instances so qrItemIndex is correct once we reach the next item
112
+ if (isRepeatGroup && typeof repeatGroupInstances === 'number') {
113
+ qrItemIndex += repeatGroupInstances;
114
+ }
115
+ else {
116
+ qrItemIndex++;
117
+ }
58
118
  }
59
119
  return invalidItems;
60
120
  }
61
121
  function validateItemRecursive(params) {
62
- var _a, _b;
63
- const { qItem, qrItem, invalidItems, enableWhenIsActivated, enableWhenItems, enableWhenExpressions } = params;
122
+ var _a, _b, _c;
123
+ const { qItem, qrItem, qrItemIndex, invalidItems, enableWhenIsActivated, enableWhenItems, enableWhenExpressions, isRepeatGroupInstance } = params;
124
+ let { locationExpression } = params;
125
+ // If item is hidden by enableWhen, skip validation
64
126
  if (isHiddenByEnableWhen({
65
127
  linkId: qItem.linkId,
66
128
  enableWhenIsActivated,
@@ -69,22 +131,40 @@ function validateItemRecursive(params) {
69
131
  })) {
70
132
  return;
71
133
  }
72
- // FIXME repeat groups not working
134
+ // Validate repeat groups
73
135
  if (qItem.type === 'group' && qItem.repeats) {
74
- return;
136
+ if (!isRepeatGroupInstance) {
137
+ validateRepeatGroupRecursive({
138
+ qItem,
139
+ qrItem,
140
+ qrItemIndex,
141
+ locationExpression,
142
+ invalidItems,
143
+ enableWhenIsActivated,
144
+ enableWhenItems,
145
+ enableWhenExpressions,
146
+ isRepeatGroupInstance: false
147
+ });
148
+ return;
149
+ }
75
150
  }
151
+ locationExpression = `${locationExpression}[${qrItemIndex}]`;
152
+ // Recursively validate groups with child items
76
153
  const childQItems = qItem.item;
77
154
  if (childQItems && childQItems.length > 0) {
78
155
  const childQrItems = (_a = qrItem === null || qrItem === void 0 ? void 0 : qrItem.item) !== null && _a !== void 0 ? _a : [];
79
156
  const indexMap = mapQItemsIndex(qItem);
80
157
  const qrItemsByIndex = getQrItemsIndex(childQItems, childQrItems, indexMap);
158
+ // Check if group is required and has no answers
81
159
  if (qItem.type === 'group' && qItem.required) {
82
160
  if (!qrItem || qrItemsByIndex.length === 0) {
83
- invalidItems[qItem.linkId] = 'required';
161
+ invalidItems[qItem.linkId] = createValidationOperationOutcome(ValidationResult.required, qItem, qrItem, null, locationExpression, (_b = invalidItems[qItem.linkId]) === null || _b === void 0 ? void 0 : _b.issue);
84
162
  }
85
163
  }
164
+ // Loop through child items
86
165
  for (const [index, childQItem] of childQItems.entries()) {
87
- let childQRItem = (_b = qrItemsByIndex[index]) !== null && _b !== void 0 ? _b : {
166
+ const childLocationExpression = `${locationExpression}.item`;
167
+ let childQRItem = (_c = qrItemsByIndex[index]) !== null && _c !== void 0 ? _c : {
88
168
  linkId: childQItem.linkId,
89
169
  text: childQItem.text
90
170
  };
@@ -98,56 +178,70 @@ function validateItemRecursive(params) {
98
178
  validateItemRecursive({
99
179
  qItem: childQItem,
100
180
  qrItem: childQRItem,
181
+ qrItemIndex: index,
182
+ locationExpression: childLocationExpression,
101
183
  invalidItems: invalidItems,
102
184
  enableWhenIsActivated,
103
185
  enableWhenItems,
104
- enableWhenExpressions
186
+ enableWhenExpressions,
187
+ isRepeatGroupInstance: false
105
188
  });
106
189
  }
107
190
  }
108
- validateSingleItem(qItem, qrItem, invalidItems);
191
+ // Validate the item, note that this can be either a group or a non-group
192
+ validateSingleItem(qItem, qrItem, invalidItems, locationExpression);
109
193
  }
110
- function validateSingleItem(qItem, qrItem, invalidItems) {
194
+ function validateRepeatGroupRecursive(params) {
195
+ var _a;
196
+ const { qItem, qrItem, qrItemIndex, locationExpression, invalidItems, enableWhenIsActivated, enableWhenItems, enableWhenExpressions } = params;
197
+ if (!qItem.item || qItem.item.length === 0 || !qrItem.item || qrItem.item.length === 0) {
198
+ return;
199
+ }
200
+ // Get repeat group answers
201
+ const repeatGroupAnswers = (_a = qrItem.item) !== null && _a !== void 0 ? _a : [];
202
+ for (const [index, repeatGroupAnswer] of repeatGroupAnswers.entries()) {
203
+ // Because the item is a repeat group and might have multiple answer instances, we need to increment the qItemIndex by the instanceIndex
204
+ const updatedQrItemIndex = qrItemIndex + index;
205
+ validateItemRecursive({
206
+ qItem: qItem,
207
+ qrItem: repeatGroupAnswer,
208
+ qrItemIndex: updatedQrItemIndex,
209
+ locationExpression: locationExpression,
210
+ invalidItems: invalidItems,
211
+ enableWhenIsActivated,
212
+ enableWhenItems,
213
+ enableWhenExpressions,
214
+ isRepeatGroupInstance: true
215
+ });
216
+ }
217
+ }
218
+ function validateSingleItem(qItem, qrItem, invalidItems, locationExpression) {
111
219
  var _a, _b;
112
- // Validate item.required
220
+ // Validate item.required first before every other validation check
113
221
  if (qItem.type !== 'display') {
114
222
  if (qItem.required && !qrItem.answer) {
115
- invalidItems[qItem.linkId] = 'required';
223
+ invalidItems[qItem.linkId] = createValidationOperationOutcome(ValidationResult.required, qItem, qrItem, null, locationExpression, (_a = invalidItems[qItem.linkId]) === null || _a === void 0 ? void 0 : _a.issue);
116
224
  return invalidItems;
117
225
  }
118
226
  }
119
227
  // Validate regex, maxLength and minLength
120
228
  if (qrItem.answer) {
121
- for (const answer of qrItem.answer) {
229
+ for (const [i, answer] of qrItem.answer.entries()) {
230
+ // Your code here, you can use 'index' and 'answer' as needed
122
231
  if (answer.valueString || answer.valueInteger || answer.valueDecimal || answer.valueUri) {
123
- const invalidInputType = getInputInvalidType(getInputInString(answer), getRegexValidation(qItem), (_a = structuredDataCapture.getMinLength(qItem)) !== null && _a !== void 0 ? _a : null, (_b = qItem.maxLength) !== null && _b !== void 0 ? _b : null);
124
- if (!invalidInputType) {
125
- continue;
232
+ const invalidInputType = getInputInvalidType(getInputInString(answer), getRegexValidation(qItem), structuredDataCapture.getMinLength(qItem), qItem.maxLength, structuredDataCapture.getMaxDecimalPlaces(qItem));
233
+ if (invalidInputType) {
234
+ invalidItems[qItem.linkId] = createValidationOperationOutcome(invalidInputType, qItem, qrItem, i, locationExpression, (_b = invalidItems[qItem.linkId]) === null || _b === void 0 ? void 0 : _b.issue);
126
235
  }
127
- // Assign invalid type and break - stop checking other answers if is a repeat item
128
- switch (invalidInputType) {
129
- case 'regex':
130
- invalidItems[qItem.linkId] = 'regex';
131
- break;
132
- case 'minLength':
133
- invalidItems[qItem.linkId] = 'minLength';
134
- break;
135
- case 'maxLength':
136
- invalidItems[qItem.linkId] = 'maxLength';
137
- break;
138
- }
139
- break;
140
236
  }
141
237
  }
142
- // Reached the end of the loop and no invalid input type found
143
- // If a required item is filled, remove the required invalid type
144
- if (qItem.required && invalidItems[qItem.linkId] && invalidItems[qItem.linkId] === 'required') {
145
- delete invalidItems[qItem.linkId];
146
- }
147
238
  }
148
239
  return invalidItems;
149
240
  }
150
241
  function getInputInString(answer) {
242
+ if (!answer) {
243
+ return '';
244
+ }
151
245
  if (answer.valueString) {
152
246
  return answer.valueString;
153
247
  }
@@ -162,18 +256,160 @@ function getInputInString(answer) {
162
256
  }
163
257
  return '';
164
258
  }
165
- export function getInputInvalidType(input, regexValidation, minLength, maxLength) {
259
+ export function getInputInvalidType(input, regexValidation, minLength, maxLength, maxDecimalPlaces) {
260
+ var _a, _b;
166
261
  if (input) {
167
262
  if (regexValidation && !regexValidation.expression.test(input)) {
168
- return 'regex';
263
+ return ValidationResult.regex;
169
264
  }
170
265
  if (minLength && input.length < minLength) {
171
- return 'minLength';
266
+ return ValidationResult.minLength;
172
267
  }
173
268
  if (maxLength && input.length > maxLength) {
174
- return 'maxLength';
269
+ return ValidationResult.maxLength;
270
+ }
271
+ if (maxDecimalPlaces) {
272
+ const decimalPlaces = (_b = (_a = input.split('.')[1]) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
273
+ if (decimalPlaces > maxDecimalPlaces) {
274
+ return ValidationResult.maxDecimalPlaces;
275
+ }
175
276
  }
176
277
  }
177
278
  return null;
178
279
  }
280
+ function createValidationOperationOutcome(error, qItem, qrItem, answerIndex, locationExpression, existingOperationOutcomeIssues = []) {
281
+ return {
282
+ resourceType: 'OperationOutcome',
283
+ issue: existingOperationOutcomeIssues.concat(createValidationOperationOutcomeIssue(error, qItem, qrItem, answerIndex, locationExpression))
284
+ };
285
+ }
286
+ function createValidationOperationOutcomeIssue(error, qItem, qrItem, answerIndex, locationExpression) {
287
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
288
+ const errorCodeSystem = 'http://fhir.forms-lab.com/CodeSystem/errors';
289
+ let detailsText = '';
290
+ let fieldDisplayText = (_d = (_c = (_b = (_a = qrItem === null || qrItem === void 0 ? void 0 : qrItem.text) !== null && _a !== void 0 ? _a : getShortText(qItem)) !== null && _b !== void 0 ? _b : qItem === null || qItem === void 0 ? void 0 : qItem.text) !== null && _c !== void 0 ? _c : qItem.linkId) !== null && _d !== void 0 ? _d : qrItem.linkId;
291
+ if (!fieldDisplayText && fieldDisplayText.endsWith(':')) {
292
+ fieldDisplayText = fieldDisplayText.substring(0, fieldDisplayText.length - 1);
293
+ }
294
+ answerIndex = answerIndex !== null && answerIndex !== void 0 ? answerIndex : 0;
295
+ // create operationOutcomeIssue based on error
296
+ switch (error) {
297
+ case ValidationResult.required: {
298
+ if (qItem.type === 'group') {
299
+ detailsText = `${fieldDisplayText}: Mandatory group does not have answer(s)`;
300
+ }
301
+ else {
302
+ detailsText = `${fieldDisplayText}: Mandatory field does not have an answer`;
303
+ }
304
+ return {
305
+ severity: 'error',
306
+ code: 'required',
307
+ expression: [locationExpression],
308
+ details: {
309
+ coding: [
310
+ {
311
+ system: errorCodeSystem,
312
+ code: error,
313
+ display: 'Required'
314
+ }
315
+ ],
316
+ text: detailsText
317
+ }
318
+ };
319
+ }
320
+ case ValidationResult.regex: {
321
+ detailsText = `${fieldDisplayText}: The value '${getInputInString((_e = qrItem.answer) === null || _e === void 0 ? void 0 : _e[answerIndex])}' does not match the defined format.`;
322
+ if (structuredDataCapture.getEntryFormat(qItem)) {
323
+ detailsText += ` ${structuredDataCapture.getEntryFormat(qItem)}`;
324
+ }
325
+ return {
326
+ severity: 'error',
327
+ code: 'invalid',
328
+ expression: [locationExpression],
329
+ details: {
330
+ coding: [
331
+ {
332
+ system: errorCodeSystem,
333
+ code: error,
334
+ display: 'Invalid format'
335
+ }
336
+ ],
337
+ text: detailsText
338
+ },
339
+ diagnostics: (_f = getRegexString(qItem)) !== null && _f !== void 0 ? _f : undefined
340
+ };
341
+ }
342
+ case ValidationResult.minLength: {
343
+ detailsText = `${fieldDisplayText}: Expected the minimum value ${structuredDataCapture.getMinLength(qItem)} characters, received '${getInputInString((_g = qrItem.answer) === null || _g === void 0 ? void 0 : _g[answerIndex])}'`;
344
+ return {
345
+ severity: 'error',
346
+ code: 'business-rule',
347
+ expression: [locationExpression],
348
+ details: {
349
+ coding: [
350
+ {
351
+ system: errorCodeSystem,
352
+ code: error,
353
+ display: 'Too short'
354
+ }
355
+ ],
356
+ text: detailsText
357
+ }
358
+ };
359
+ }
360
+ case ValidationResult.maxLength: {
361
+ detailsText = `${fieldDisplayText}: Exceeded maximum of ${qItem.maxLength} characters, received '${getInputInString((_h = qrItem.answer) === null || _h === void 0 ? void 0 : _h[answerIndex])}'`;
362
+ return {
363
+ severity: 'error',
364
+ code: 'business-rule',
365
+ expression: [locationExpression],
366
+ details: {
367
+ coding: [
368
+ {
369
+ system: errorCodeSystem,
370
+ code: error,
371
+ display: 'Too long'
372
+ }
373
+ ],
374
+ text: detailsText
375
+ }
376
+ };
377
+ }
378
+ case ValidationResult.maxDecimalPlaces: {
379
+ detailsText = `${fieldDisplayText}: Exceeded maximum decimal places ${structuredDataCapture.getMaxDecimalPlaces(qItem)}, received '${getInputInString((_j = qrItem.answer) === null || _j === void 0 ? void 0 : _j[answerIndex])}'`;
380
+ return {
381
+ severity: 'error',
382
+ code: 'business-rule',
383
+ expression: [locationExpression],
384
+ details: {
385
+ coding: [
386
+ {
387
+ system: errorCodeSystem,
388
+ code: error,
389
+ display: 'Too precise'
390
+ }
391
+ ],
392
+ text: detailsText
393
+ }
394
+ };
395
+ }
396
+ // mark unknown issues as fatal
397
+ default: {
398
+ return {
399
+ severity: 'error',
400
+ code: 'unknown',
401
+ expression: [locationExpression],
402
+ details: {
403
+ coding: [
404
+ {
405
+ system: errorCodeSystem,
406
+ code: 'unknown',
407
+ display: 'Unknown'
408
+ }
409
+ ]
410
+ }
411
+ };
412
+ }
413
+ }
414
+ }
179
415
  //# sourceMappingURL=validateQuestionnaire.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validateQuestionnaire.js","sourceRoot":"","sources":["../../src/utils/validateQuestionnaire.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validateQuestionnaire.js","sourceRoot":"","sources":["../../src/utils/validateQuestionnaire.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aehrc/smart-forms-renderer",
3
- "version": "0.21.2",
3
+ "version": "0.22.0",
4
4
  "description": "FHIR Structured Data Captured (SDC) rendering engine for Smart Forms",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -78,7 +78,6 @@ function CustomDateTimeItem(props: CustomDateTimeItemProps) {
78
78
  if (tempDateTime.includes('T')) {
79
79
  valueDate = tempDateTime.split('T')[0];
80
80
  dateTimeDayJs = dayjs(tempDateTime);
81
- console.log(dateTimeDayJs);
82
81
  } else {
83
82
  valueDate = tempDateTime;
84
83
  }
@@ -68,6 +68,7 @@ function DecimalField(props: DecimalFieldProps) {
68
68
  </InputAdornment>
69
69
  )
70
70
  }}
71
+ helperText={feedback}
71
72
  data-test="q-item-decimal-field"
72
73
  />
73
74
  );
@@ -57,8 +57,15 @@ function DecimalItem(props: DecimalItemProps) {
57
57
 
58
58
  const readOnly = useReadOnly(qItem, parentIsReadOnly);
59
59
  const precision = getDecimalPrecision(qItem);
60
- const { displayUnit, displayPrompt, entryFormat, regexValidation, minLength, maxLength } =
61
- useRenderingExtensions(qItem);
60
+ const {
61
+ displayUnit,
62
+ displayPrompt,
63
+ entryFormat,
64
+ regexValidation,
65
+ minLength,
66
+ maxLength,
67
+ maxDecimalPlaces
68
+ } = useRenderingExtensions(qItem);
62
69
 
63
70
  // Init input value
64
71
  let valueDecimal = 0.0;
@@ -77,7 +84,13 @@ function DecimalItem(props: DecimalItemProps) {
77
84
  const [input, setInput] = useStringInput(initialInput);
78
85
 
79
86
  // Perform validation checks
80
- const feedback = useValidationFeedback(input, regexValidation, minLength, maxLength);
87
+ const feedback = useValidationFeedback(
88
+ input,
89
+ regexValidation,
90
+ minLength,
91
+ maxLength,
92
+ maxDecimalPlaces
93
+ );
81
94
 
82
95
  // Process calculated expressions
83
96
  const { calcExpUpdated } = useDecimalCalculatedExpression({
@@ -35,9 +35,10 @@ interface RenderingExtensions {
35
35
  readOnly: boolean;
36
36
  entryFormat: string;
37
37
  required: boolean;
38
- regexValidation: RegexValidation | null;
39
- minLength: number | null;
40
- maxLength: number | null;
38
+ regexValidation?: RegexValidation;
39
+ minLength?: number;
40
+ maxLength?: number;
41
+ maxDecimalPlaces?: number;
41
42
  }
42
43
 
43
44
  function useRenderingExtensions(qItem: QuestionnaireItem): RenderingExtensions {
@@ -51,8 +52,9 @@ function useRenderingExtensions(qItem: QuestionnaireItem): RenderingExtensions {
51
52
  entryFormat: structuredDataCapture.getEntryFormat(qItem) ?? '',
52
53
  required: qItem.required ?? false,
53
54
  regexValidation: getRegexValidation(qItem),
54
- minLength: structuredDataCapture.getMinLength(qItem) ?? null,
55
- maxLength: qItem.maxLength ?? null
55
+ minLength: structuredDataCapture.getMinLength(qItem),
56
+ maxLength: qItem.maxLength,
57
+ maxDecimalPlaces: structuredDataCapture.getMaxDecimalPlaces(qItem)
56
58
  }),
57
59
  [qItem]
58
60
  );
@@ -16,34 +16,46 @@
16
16
  */
17
17
 
18
18
  import type { RegexValidation } from '../interfaces/regex.interface';
19
- import { getInputInvalidType } from '../utils/validateQuestionnaire';
19
+ import { getInputInvalidType, ValidationResult } from '../utils/validateQuestionnaire';
20
20
 
21
21
  function useValidationFeedback(
22
22
  input: string,
23
- regexValidation: RegexValidation | null,
24
- minLength: number | null,
25
- maxLength: number | null
23
+ regexValidation?: RegexValidation,
24
+ minLength?: number,
25
+ maxLength?: number,
26
+ maxDecimalPlaces?: number
26
27
  ): string {
27
- const invalidType = getInputInvalidType(input, regexValidation, minLength, maxLength);
28
+ const invalidType = getInputInvalidType(
29
+ input,
30
+ regexValidation,
31
+ minLength,
32
+ maxLength,
33
+ maxDecimalPlaces
34
+ );
28
35
 
29
36
  if (!invalidType) {
30
37
  return '';
31
38
  }
32
39
 
33
- if (invalidType === 'regex' && regexValidation) {
40
+ if (invalidType === ValidationResult.regex && regexValidation) {
34
41
  return `Input should match the specified regex ${regexValidation.expression}`;
35
42
  }
36
43
 
37
44
  // Test min character limit
38
- if (invalidType === 'minLength' && minLength) {
45
+ if (invalidType === ValidationResult.minLength && typeof minLength === 'number') {
39
46
  return `Enter at least ${minLength} characters.`;
40
47
  }
41
48
 
42
49
  // Test max character limit
43
- if (invalidType === 'maxLength' && maxLength) {
50
+ if (invalidType === ValidationResult.maxLength && typeof maxLength === 'number') {
44
51
  return `Input exceeds maximum character limit of ${maxLength}.`;
45
52
  }
46
53
 
54
+ // Test max decimal places limit
55
+ if (invalidType === ValidationResult.maxDecimalPlaces && typeof maxDecimalPlaces === 'number') {
56
+ return `Input exceeds maximum decimal places limit of ${maxDecimalPlaces}.`;
57
+ }
58
+
47
59
  return '';
48
60
  }
49
61
 
@@ -16,13 +16,12 @@
16
16
  */
17
17
 
18
18
  import { createStore } from 'zustand/vanilla';
19
- import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
19
+ import type { OperationOutcome, Questionnaire, QuestionnaireResponse } from 'fhir/r4';
20
20
  import { emptyResponse } from '../utils/emptyResource';
21
21
  import cloneDeep from 'lodash.clonedeep';
22
22
  import type { Diff } from 'deep-diff';
23
23
  import { diff } from 'deep-diff';
24
24
  import { createSelectors } from './selector';
25
- import type { InvalidType } from '../utils/validateQuestionnaire';
26
25
  import { validateQuestionnaire } from '../utils/validateQuestionnaire';
27
26
  import { questionnaireStore } from './questionnaireStore';
28
27
 
@@ -30,7 +29,7 @@ interface QuestionnaireResponseStoreType {
30
29
  sourceResponse: QuestionnaireResponse;
31
30
  updatableResponse: QuestionnaireResponse;
32
31
  formChangesHistory: (Diff<QuestionnaireResponse, QuestionnaireResponse>[] | null)[];
33
- invalidItems: Record<string, InvalidType>;
32
+ invalidItems: Record<string, OperationOutcome>;
34
33
  responseIsValid: boolean;
35
34
  validateQuestionnaire: (
36
35
  questionnaire: Questionnaire,
@@ -55,24 +54,21 @@ export const questionnaireResponseStore = createStore<QuestionnaireResponseStore
55
54
  questionnaire: Questionnaire,
56
55
  updatedResponse: QuestionnaireResponse
57
56
  ) => {
58
- const tempInvalidItems = get().invalidItems;
59
-
60
57
  const enableWhenIsActivated = questionnaireStore.getState().enableWhenIsActivated;
61
58
  const enableWhenItems = questionnaireStore.getState().enableWhenItems;
62
59
  const enableWhenExpressions = questionnaireStore.getState().enableWhenExpressions;
63
60
 
64
- validateQuestionnaire({
61
+ const updatedInvalidItems = validateQuestionnaire({
65
62
  questionnaire,
66
63
  questionnaireResponse: updatedResponse,
67
- invalidItems: tempInvalidItems,
68
64
  enableWhenIsActivated,
69
65
  enableWhenItems,
70
66
  enableWhenExpressions
71
67
  });
72
68
 
73
69
  set(() => ({
74
- invalidItems: tempInvalidItems,
75
- responseIsValid: Object.keys(tempInvalidItems).length === 0
70
+ invalidItems: updatedInvalidItems,
71
+ responseIsValid: Object.keys(updatedInvalidItems).length === 0
76
72
  }));
77
73
  },
78
74
  buildSourceResponse: (questionnaireResponse: QuestionnaireResponse) => {