@aehrc/smart-forms-renderer 0.13.2 → 0.14.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 (109) hide show
  1. package/lib/components/FormComponents/AttachmentItem/AttachmentField.d.ts +13 -0
  2. package/lib/components/FormComponents/AttachmentItem/AttachmentField.js +39 -0
  3. package/lib/components/FormComponents/AttachmentItem/AttachmentField.js.map +1 -0
  4. package/lib/components/FormComponents/AttachmentItem/AttachmentFieldWrapper.d.ts +14 -0
  5. package/lib/components/FormComponents/AttachmentItem/AttachmentFieldWrapper.js +34 -0
  6. package/lib/components/FormComponents/AttachmentItem/AttachmentFieldWrapper.js.map +1 -0
  7. package/lib/components/FormComponents/AttachmentItem/AttachmentFileCollector.d.ts +8 -0
  8. package/lib/components/FormComponents/AttachmentItem/AttachmentFileCollector.js +61 -0
  9. package/lib/components/FormComponents/AttachmentItem/AttachmentFileCollector.js.map +1 -0
  10. package/lib/components/FormComponents/AttachmentItem/AttachmentFileDropBox.d.ts +11 -0
  11. package/lib/components/FormComponents/AttachmentItem/AttachmentFileDropBox.js +49 -0
  12. package/lib/components/FormComponents/AttachmentItem/AttachmentFileDropBox.js.map +1 -0
  13. package/lib/components/FormComponents/AttachmentItem/AttachmentFileDropBox.styles.d.ts +7 -0
  14. package/lib/components/FormComponents/AttachmentItem/AttachmentFileDropBox.styles.js +30 -0
  15. package/lib/components/FormComponents/AttachmentItem/AttachmentFileDropBox.styles.js.map +1 -0
  16. package/lib/components/FormComponents/AttachmentItem/AttachmentItem.d.ts +14 -0
  17. package/lib/components/FormComponents/AttachmentItem/AttachmentItem.js +86 -0
  18. package/lib/components/FormComponents/AttachmentItem/AttachmentItem.js.map +1 -0
  19. package/lib/components/FormComponents/AttachmentItem/AttachmentUrlField.d.ts +10 -0
  20. package/lib/components/FormComponents/AttachmentItem/AttachmentUrlField.js +39 -0
  21. package/lib/components/FormComponents/AttachmentItem/AttachmentUrlField.js.map +1 -0
  22. package/lib/components/FormComponents/ChoiceItems/ChoiceAutocompleteField.d.ts +1 -1
  23. package/lib/components/FormComponents/ChoiceItems/ChoiceAutocompleteField.js +2 -2
  24. package/lib/components/FormComponents/ChoiceItems/ChoiceAutocompleteField.js.map +1 -1
  25. package/lib/components/FormComponents/ChoiceItems/ChoiceCheckboxAnswerValueSetFields.d.ts +2 -1
  26. package/lib/components/FormComponents/ChoiceItems/ChoiceCheckboxAnswerValueSetFields.js +6 -3
  27. package/lib/components/FormComponents/ChoiceItems/ChoiceCheckboxAnswerValueSetFields.js.map +1 -1
  28. package/lib/components/FormComponents/ChoiceItems/ChoiceCheckboxAnswerValueSetItem.js +3 -3
  29. package/lib/components/FormComponents/ChoiceItems/ChoiceCheckboxAnswerValueSetItem.js.map +1 -1
  30. package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.d.ts +2 -1
  31. package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.js +6 -3
  32. package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.js.map +1 -1
  33. package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetItem.js +3 -3
  34. package/lib/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetItem.js.map +1 -1
  35. package/lib/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionFields.js +2 -1
  36. package/lib/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionFields.js.map +1 -1
  37. package/lib/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetFields.d.ts +2 -1
  38. package/lib/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetFields.js +8 -5
  39. package/lib/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetFields.js.map +1 -1
  40. package/lib/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetItem.js +3 -3
  41. package/lib/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetItem.js.map +1 -1
  42. package/lib/components/FormComponents/DateItem/DateField.js +2 -1
  43. package/lib/components/FormComponents/DateItem/DateField.js.map +1 -1
  44. package/lib/components/FormComponents/DateTimeItem/DateTimeField.js +2 -1
  45. package/lib/components/FormComponents/DateTimeItem/DateTimeField.js.map +1 -1
  46. package/lib/components/FormComponents/OpenChoiceItems/OpenChoiceAutocompleteField.js +2 -2
  47. package/lib/components/FormComponents/OpenChoiceItems/OpenChoiceAutocompleteField.js.map +1 -1
  48. package/lib/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerOptionField.js +2 -2
  49. package/lib/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerOptionField.js.map +1 -1
  50. package/lib/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerValueSetField.d.ts +2 -1
  51. package/lib/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerValueSetField.js +7 -4
  52. package/lib/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerValueSetField.js.map +1 -1
  53. package/lib/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerValueSetItem.js +3 -3
  54. package/lib/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerValueSetItem.js.map +1 -1
  55. package/lib/components/FormComponents/SingleItem/SingleItemSwitcher.js +28 -16
  56. package/lib/components/FormComponents/SingleItem/SingleItemSwitcher.js.map +1 -1
  57. package/lib/components/FormComponents/SliderItem/SliderField.js +2 -1
  58. package/lib/components/FormComponents/SliderItem/SliderField.js.map +1 -1
  59. package/lib/components/FormComponents/Textfield.styles.d.ts +1 -0
  60. package/lib/components/FormComponents/Textfield.styles.js +2 -1
  61. package/lib/components/FormComponents/Textfield.styles.js.map +1 -1
  62. package/lib/components/FormComponents/TimeItem/TimeField.js +2 -1
  63. package/lib/components/FormComponents/TimeItem/TimeField.js.map +1 -1
  64. package/lib/hooks/UseFileDrop.d.ts +10 -0
  65. package/lib/hooks/UseFileDrop.js +40 -0
  66. package/lib/hooks/UseFileDrop.js.map +1 -0
  67. package/lib/hooks/useAttachmentUrlValidation.d.ts +2 -0
  68. package/lib/hooks/useAttachmentUrlValidation.js +27 -0
  69. package/lib/hooks/useAttachmentUrlValidation.js.map +1 -0
  70. package/lib/hooks/useValueSetCodings.d.ts +5 -1
  71. package/lib/hooks/useValueSetCodings.js +1 -1
  72. package/lib/hooks/useValueSetCodings.js.map +1 -1
  73. package/lib/utils/fileUtils.d.ts +3 -0
  74. package/lib/utils/fileUtils.js +64 -0
  75. package/lib/utils/fileUtils.js.map +1 -0
  76. package/lib/utils/validateQuestionnaire.d.ts +3 -5
  77. package/lib/utils/validateQuestionnaire.js +8 -5
  78. package/lib/utils/validateQuestionnaire.js.map +1 -1
  79. package/package.json +3 -1
  80. package/src/components/FormComponents/AttachmentItem/AttachmentField.tsx +96 -0
  81. package/src/components/FormComponents/AttachmentItem/AttachmentFieldWrapper.tsx +87 -0
  82. package/src/components/FormComponents/AttachmentItem/AttachmentFileCollector.tsx +101 -0
  83. package/src/components/FormComponents/AttachmentItem/AttachmentFileDropBox.styles.ts +31 -0
  84. package/src/components/FormComponents/AttachmentItem/AttachmentFileDropBox.tsx +66 -0
  85. package/src/components/FormComponents/AttachmentItem/AttachmentItem.tsx +123 -0
  86. package/src/components/FormComponents/AttachmentItem/AttachmentUrlField.tsx +78 -0
  87. package/src/components/FormComponents/ChoiceItems/ChoiceAutocompleteField.tsx +3 -3
  88. package/src/components/FormComponents/ChoiceItems/ChoiceCheckboxAnswerValueSetFields.tsx +6 -4
  89. package/src/components/FormComponents/ChoiceItems/ChoiceCheckboxAnswerValueSetItem.tsx +3 -3
  90. package/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.tsx +7 -4
  91. package/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetItem.tsx +3 -3
  92. package/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionFields.tsx +2 -1
  93. package/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetFields.tsx +9 -6
  94. package/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetItem.tsx +3 -3
  95. package/src/components/FormComponents/DateItem/DateField.tsx +2 -1
  96. package/src/components/FormComponents/DateTimeItem/DateTimeField.tsx +2 -1
  97. package/src/components/FormComponents/OpenChoiceItems/OpenChoiceAutocompleteField.tsx +2 -2
  98. package/src/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerOptionField.tsx +2 -2
  99. package/src/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerValueSetField.tsx +9 -6
  100. package/src/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerValueSetItem.tsx +3 -3
  101. package/src/components/FormComponents/SingleItem/SingleItemSwitcher.tsx +67 -31
  102. package/src/components/FormComponents/SliderItem/SliderField.tsx +2 -1
  103. package/src/components/FormComponents/Textfield.styles.ts +3 -1
  104. package/src/components/FormComponents/TimeItem/TimeField.tsx +2 -1
  105. package/src/hooks/UseFileDrop.ts +53 -0
  106. package/src/hooks/useAttachmentUrlValidation.ts +27 -0
  107. package/src/hooks/useValueSetCodings.ts +10 -2
  108. package/src/utils/fileUtils.ts +66 -0
  109. package/src/utils/validateQuestionnaire.ts +17 -13
@@ -52,7 +52,7 @@ function OpenChoiceSelectAnswerValueSetItem(props: OpenChoiceSelectAnswerValueSe
52
52
  }
53
53
 
54
54
  // Get codings/options from valueSet
55
- const { codings, serverError } = useValueSetCodings(qItem);
55
+ const { codings, terminologyError } = useValueSetCodings(qItem);
56
56
 
57
57
  // Event handlers
58
58
  function handleValueChange(newValue: Coding | string | null) {
@@ -79,7 +79,7 @@ function OpenChoiceSelectAnswerValueSetItem(props: OpenChoiceSelectAnswerValueSe
79
79
  qItem={qItem}
80
80
  options={codings}
81
81
  valueSelect={valueSelect}
82
- serverError={serverError}
82
+ terminologyError={terminologyError}
83
83
  isTabled={isTabled}
84
84
  readOnly={readOnly}
85
85
  onValueChange={handleValueChange}
@@ -94,7 +94,7 @@ function OpenChoiceSelectAnswerValueSetItem(props: OpenChoiceSelectAnswerValueSe
94
94
  qItem={qItem}
95
95
  options={codings}
96
96
  valueSelect={valueSelect}
97
- serverError={serverError}
97
+ terminologyError={terminologyError}
98
98
  isTabled={isTabled}
99
99
  readOnly={readOnly}
100
100
  onValueChange={handleValueChange}
@@ -39,6 +39,7 @@ import CustomDateItem from '../CustomDateItem/CustomDateItem';
39
39
  import { isSpecificItemControl } from '../../../utils';
40
40
  import SliderItem from '../SliderItem/SliderItem';
41
41
  import IntegerItem from '../IntegerItem/IntegerItem';
42
+ import AttachmentItem from '../AttachmentItem/AttachmentItem';
42
43
 
43
44
  interface SingleItemSwitcherProps
44
45
  extends PropsWithQrItemChangeHandler,
@@ -55,9 +56,11 @@ function SingleItemSwitcher(props: SingleItemSwitcherProps) {
55
56
  props;
56
57
 
57
58
  switch (qItem.type) {
58
- case 'string':
59
+ case 'display':
60
+ return <DisplayItem qItem={qItem} />;
61
+ case 'boolean':
59
62
  return (
60
- <StringItem
63
+ <BooleanItem
61
64
  qItem={qItem}
62
65
  qrItem={qrItem}
63
66
  isRepeated={isRepeated}
@@ -66,9 +69,9 @@ function SingleItemSwitcher(props: SingleItemSwitcherProps) {
66
69
  onQrItemChange={onQrItemChange}
67
70
  />
68
71
  );
69
- case 'boolean':
72
+ case 'decimal':
70
73
  return (
71
- <BooleanItem
74
+ <DecimalItem
72
75
  qItem={qItem}
73
76
  qrItem={qrItem}
74
77
  isRepeated={isRepeated}
@@ -77,9 +80,22 @@ function SingleItemSwitcher(props: SingleItemSwitcherProps) {
77
80
  onQrItemChange={onQrItemChange}
78
81
  />
79
82
  );
80
- case 'time':
83
+ case 'integer':
84
+ if (isSpecificItemControl(qItem, 'slider')) {
85
+ return (
86
+ <SliderItem
87
+ qItem={qItem}
88
+ qrItem={qrItem}
89
+ isRepeated={isRepeated}
90
+ isTabled={isTabled}
91
+ parentIsReadOnly={parentIsReadOnly}
92
+ onQrItemChange={onQrItemChange}
93
+ />
94
+ );
95
+ }
96
+
81
97
  return (
82
- <TimeItem
98
+ <IntegerItem
83
99
  qItem={qItem}
84
100
  qrItem={qrItem}
85
101
  isRepeated={isRepeated}
@@ -110,34 +126,20 @@ function SingleItemSwitcher(props: SingleItemSwitcherProps) {
110
126
  onQrItemChange={onQrItemChange}
111
127
  />
112
128
  );
113
- case 'text':
129
+ case 'time':
114
130
  return (
115
- <TextItem
131
+ <TimeItem
116
132
  qItem={qItem}
117
133
  qrItem={qrItem}
118
134
  isRepeated={isRepeated}
135
+ isTabled={isTabled}
119
136
  parentIsReadOnly={parentIsReadOnly}
120
137
  onQrItemChange={onQrItemChange}
121
138
  />
122
139
  );
123
- case 'display':
124
- return <DisplayItem qItem={qItem} />;
125
- case 'integer':
126
- if (isSpecificItemControl(qItem, 'slider')) {
127
- return (
128
- <SliderItem
129
- qItem={qItem}
130
- qrItem={qrItem}
131
- isRepeated={isRepeated}
132
- isTabled={isTabled}
133
- parentIsReadOnly={parentIsReadOnly}
134
- onQrItemChange={onQrItemChange}
135
- />
136
- );
137
- }
138
-
140
+ case 'string':
139
141
  return (
140
- <IntegerItem
142
+ <StringItem
141
143
  qItem={qItem}
142
144
  qrItem={qrItem}
143
145
  isRepeated={isRepeated}
@@ -146,9 +148,19 @@ function SingleItemSwitcher(props: SingleItemSwitcherProps) {
146
148
  onQrItemChange={onQrItemChange}
147
149
  />
148
150
  );
149
- case 'decimal':
151
+ case 'text':
150
152
  return (
151
- <DecimalItem
153
+ <TextItem
154
+ qItem={qItem}
155
+ qrItem={qrItem}
156
+ isRepeated={isRepeated}
157
+ parentIsReadOnly={parentIsReadOnly}
158
+ onQrItemChange={onQrItemChange}
159
+ />
160
+ );
161
+ case 'url':
162
+ return (
163
+ <UrlItem
152
164
  qItem={qItem}
153
165
  qrItem={qrItem}
154
166
  isRepeated={isRepeated}
@@ -181,9 +193,33 @@ function SingleItemSwitcher(props: SingleItemSwitcherProps) {
181
193
  onQrItemChange={onQrItemChange}
182
194
  />
183
195
  );
184
- case 'url':
196
+ case 'attachment':
185
197
  return (
186
- <UrlItem
198
+ <AttachmentItem
199
+ qItem={qItem}
200
+ qrItem={qrItem}
201
+ isRepeated={isRepeated}
202
+ isTabled={isTabled}
203
+ parentIsReadOnly={parentIsReadOnly}
204
+ onQrItemChange={onQrItemChange}
205
+ />
206
+ );
207
+ case 'reference':
208
+ // FIXME reference item uses the same component as string item currently
209
+ return (
210
+ <StringItem
211
+ qItem={qItem}
212
+ qrItem={qrItem}
213
+ isRepeated={isRepeated}
214
+ isTabled={isTabled}
215
+ parentIsReadOnly={parentIsReadOnly}
216
+ onQrItemChange={onQrItemChange}
217
+ />
218
+ );
219
+ case 'quantity':
220
+ // FIXME quantity item uses the same component as decimal item currently
221
+ return (
222
+ <DecimalItem
187
223
  qItem={qItem}
188
224
  qrItem={qrItem}
189
225
  isRepeated={isRepeated}
@@ -195,8 +231,8 @@ function SingleItemSwitcher(props: SingleItemSwitcherProps) {
195
231
  default:
196
232
  return (
197
233
  <Typography>
198
- Item type not supported yet, or something has went wrong. If your questionnnaire is not a
199
- FHIR R4 resource, there might be issues rendering it.
234
+ Item type <b>{qItem.type}</b> not supported yet, or something has went wrong. If your
235
+ questionnnaire is not a FHIR R4 resource, there might be issues rendering it.
200
236
  </Typography>
201
237
  );
202
238
  }
@@ -22,6 +22,7 @@ import { getSliderMarks } from '../../../utils/slider';
22
22
  import Stack from '@mui/material/Stack';
23
23
  import SliderLabels from './SliderLabels';
24
24
  import SliderDisplayValue from './SliderDisplayValue';
25
+ import { TEXT_FIELD_WIDTH } from '../Textfield.styles';
25
26
 
26
27
  interface SliderFieldProps extends PropsWithIsTabledAttribute {
27
28
  linkId: string;
@@ -54,7 +55,7 @@ function SliderField(props: SliderFieldProps) {
54
55
  const sliderMarks = getSliderMarks(minValue, maxValue, minLabel, maxLabel, stepValue);
55
56
 
56
57
  const sliderSx = {
57
- maxWidth: !isTabled ? 280 : 3000,
58
+ maxWidth: !isTabled ? TEXT_FIELD_WIDTH : 3000,
58
59
  minWidth: 160
59
60
  };
60
61
 
@@ -18,12 +18,14 @@
18
18
  import { styled } from '@mui/material/styles';
19
19
  import TextField from '@mui/material/TextField';
20
20
 
21
+ export const TEXT_FIELD_WIDTH = 320;
22
+
21
23
  // Always use this accompanied by the TextField prop fullWidth
22
24
  export const StandardTextField = styled(TextField, {
23
25
  shouldForwardProp: (prop) => prop !== 'isTabled'
24
26
  })<{ isTabled: boolean }>(({ isTabled }) => ({
25
27
  // Set 280 as the standard width for a field
26
28
  // Set a theoretical infinite maxWidth if field is within a table to fill the table row
27
- maxWidth: !isTabled ? 280 : 3000,
29
+ maxWidth: !isTabled ? TEXT_FIELD_WIDTH : 3000,
28
30
  minWidth: 160
29
31
  }));
@@ -20,6 +20,7 @@ import type { PropsWithIsTabledAttribute } from '../../../interfaces/renderProps
20
20
  import type { Dayjs } from 'dayjs';
21
21
  import { LocalizationProvider, TimePicker as MuiTimePicker } from '@mui/x-date-pickers';
22
22
  import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
23
+ import { TEXT_FIELD_WIDTH } from '../Textfield.styles';
23
24
 
24
25
  interface TimeFieldProps extends PropsWithIsTabledAttribute {
25
26
  value: Dayjs | null;
@@ -39,7 +40,7 @@ function TimeField(props: TimeFieldProps) {
39
40
  value={value}
40
41
  disabled={readOnly}
41
42
  label={displayPrompt}
42
- sx={{ maxWidth: !isTabled ? 280 : 3000, minWidth: 160 }}
43
+ sx={{ maxWidth: !isTabled ? TEXT_FIELD_WIDTH : 3000, minWidth: 160 }}
43
44
  slotProps={{
44
45
  textField: {
45
46
  fullWidth: true
@@ -0,0 +1,53 @@
1
+ /*
2
+ * Copyright 2024 Commonwealth Scientific and Industrial Research
3
+ * Organisation (CSIRO) ABN 41 687 119 230.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import type { ConnectDropTarget, DropTargetMonitor } from 'react-dnd';
19
+ import { useDrop } from 'react-dnd';
20
+ import { NativeTypes } from 'react-dnd-html5-backend';
21
+
22
+ interface UseFileDrop {
23
+ canDrop: boolean;
24
+ isOver: boolean;
25
+ dropTarget: ConnectDropTarget;
26
+ }
27
+
28
+ function UseFileDrop(onDrop: (item: { files: any[] }) => void): UseFileDrop {
29
+ const [{ canDrop, isOver }, drop] = useDrop(
30
+ () => ({
31
+ accept: [NativeTypes.FILE],
32
+ drop(item: { files: any[] }) {
33
+ if (onDrop) {
34
+ onDrop(item);
35
+ }
36
+ },
37
+ canDrop() {
38
+ return true;
39
+ },
40
+ collect: (monitor: DropTargetMonitor) => {
41
+ return {
42
+ isOver: monitor.isOver(),
43
+ canDrop: monitor.canDrop()
44
+ };
45
+ }
46
+ }),
47
+ [onDrop]
48
+ );
49
+
50
+ return { canDrop, isOver, dropTarget: drop };
51
+ }
52
+
53
+ export default UseFileDrop;
@@ -0,0 +1,27 @@
1
+ /*
2
+ * Copyright 2023 Commonwealth Scientific and Industrial Research
3
+ * Organisation (CSIRO) ABN 41 687 119 230.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ function useAttachmentUrlValidation(url: string): boolean {
19
+ try {
20
+ new URL(url);
21
+ return true;
22
+ } catch (error) {
23
+ return false;
24
+ }
25
+ }
26
+
27
+ export default useAttachmentUrlValidation;
@@ -28,7 +28,15 @@ import fhirpath from 'fhirpath';
28
28
  import fhirpath_r4_model from 'fhirpath/fhir-context/r4';
29
29
  import { useQuestionnaireStore, useSmartConfigStore, useTerminologyServerStore } from '../stores';
30
30
 
31
- function useValueSetCodings(qItem: QuestionnaireItem) {
31
+ export interface TerminologyError {
32
+ error: Error | null;
33
+ answerValueSet: string;
34
+ }
35
+
36
+ function useValueSetCodings(qItem: QuestionnaireItem): {
37
+ codings: Coding[];
38
+ terminologyError: TerminologyError;
39
+ } {
32
40
  const patient = useSmartConfigStore.use.patient();
33
41
  const user = useSmartConfigStore.use.user();
34
42
  const encounter = useSmartConfigStore.use.encounter();
@@ -145,7 +153,7 @@ function useValueSetCodings(qItem: QuestionnaireItem) {
145
153
  }
146
154
  }, [qItem]);
147
155
 
148
- return { codings, serverError };
156
+ return { codings, terminologyError: { error: serverError, answerValueSet: valueSetUrl ?? '' } };
149
157
  }
150
158
 
151
159
  export default useValueSetCodings;
@@ -0,0 +1,66 @@
1
+ /*
2
+ * Copyright 2024 Commonwealth Scientific and Industrial Research
3
+ * Organisation (CSIRO) ABN 41 687 119 230.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import type { Attachment } from 'fhir/r4';
19
+
20
+ export function getFileSize(fileSizeString: string) {
21
+ if (fileSizeString.length < 7) {
22
+ return `${Math.round(+fileSizeString / 1024)}kb`;
23
+ }
24
+
25
+ return `${Math.round(+fileSizeString / 1024) / 1000}MB`;
26
+ }
27
+
28
+ const fileToBase64 = (file: File) =>
29
+ new Promise((resolve, reject) => {
30
+ const reader = new FileReader();
31
+ reader.readAsDataURL(file);
32
+ reader.onload = () => resolve(reader.result);
33
+ reader.onerror = reject;
34
+ });
35
+
36
+ export async function createAttachmentAnswer(
37
+ file: File | null,
38
+ url: string,
39
+ fileName: string
40
+ ): Promise<Attachment | null> {
41
+ if (!file || url === '') {
42
+ return null;
43
+ }
44
+
45
+ try {
46
+ const base64Data = (await fileToBase64(file)) as string;
47
+ const attachment: Attachment = {
48
+ contentType: file.type,
49
+ data: base64Data,
50
+ size: file.size
51
+ };
52
+
53
+ if (url) {
54
+ attachment.url = url;
55
+ }
56
+
57
+ if (fileName) {
58
+ attachment.title = fileName;
59
+ }
60
+
61
+ return attachment;
62
+ } catch (error) {
63
+ console.error(error);
64
+ return null;
65
+ }
66
+ }
@@ -15,14 +15,19 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
- import type { QuestionnaireResponse, QuestionnaireResponseItemAnswer } from 'fhir/r4';
19
- import { Questionnaire, QuestionnaireItem, QuestionnaireResponseItem } from 'fhir/r4';
18
+ import type {
19
+ Questionnaire,
20
+ QuestionnaireItem,
21
+ QuestionnaireResponse,
22
+ QuestionnaireResponseItem,
23
+ QuestionnaireResponseItemAnswer
24
+ } from 'fhir/r4';
20
25
  import { getQrItemsIndex, mapQItemsIndex } from './mapItem';
21
- import { EnableWhenExpression, EnableWhenItems } from '../interfaces/enableWhen.interface';
26
+ import type { EnableWhenExpression, EnableWhenItems } from '../interfaces/enableWhen.interface';
22
27
  import { isHidden } from './qItem';
23
28
  import { getRegexValidation } from './itemControl';
24
29
  import { structuredDataCapture } from 'fhir-sdc-helpers';
25
- import { RegexValidation } from '../interfaces/regex.interface';
30
+ import type { RegexValidation } from '../interfaces/regex.interface';
26
31
 
27
32
  export type InvalidType = 'regex' | 'minLength' | 'maxLength' | 'required';
28
33
 
@@ -38,7 +43,6 @@ interface ValidateQuestionnaireParams {
38
43
  /**
39
44
  * Recursively go through the questionnaireResponse and check for un-filled required qItems
40
45
  * At the moment item.required for group items are not checked
41
- * FIXME will eventually be renamed to validate questionnaire
42
46
  *
43
47
  * @author Sean Fong
44
48
  */
@@ -129,7 +133,7 @@ function validateItemRecursive(params: ValidateItemRecursiveParams) {
129
133
 
130
134
  // FIXME repeat groups not working
131
135
  if (qItem.type === 'group' && qItem.repeats) {
132
- return validateRepeatGroup(qItem, qrItem, invalidItems);
136
+ return;
133
137
  }
134
138
 
135
139
  const childQItems = qItem.item;
@@ -227,13 +231,13 @@ function validateSingleItem(
227
231
  return invalidItems;
228
232
  }
229
233
 
230
- function validateRepeatGroup(
231
- qItem: QuestionnaireItem,
232
- qrItems: QuestionnaireResponseItem,
233
- invalidLinkIds: Record<string, InvalidType>
234
- ) {
235
- return;
236
- }
234
+ // function validateRepeatGroup(
235
+ // qItem: QuestionnaireItem,
236
+ // qrItems: QuestionnaireResponseItem,
237
+ // invalidLinkIds: Record<string, InvalidType>
238
+ // ) {
239
+ // return;
240
+ // }
237
241
 
238
242
  function getInputInString(answer: QuestionnaireResponseItemAnswer) {
239
243
  if (answer.valueString) {