fhir-react 0.3.7 → 0.3.10

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 (179) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/.eslintrc +10 -1
  3. package/.storybook/main.js +5 -0
  4. package/.storybook/manager.js +6 -0
  5. package/.storybook/preview.js +7 -0
  6. package/.stylelintrc +6 -2
  7. package/README.md +19 -1
  8. package/build/index.js +15 -11
  9. package/build/style.css +9 -9
  10. package/package.json +59 -57
  11. package/src/assets/containers/AdverseEvent/adverse-event.svg +6 -0
  12. package/src/assets/containers/Generic/generic.svg +3 -0
  13. package/src/assets/containers/MedicationDispense/medication-dispense.svg +5 -0
  14. package/src/assets/containers/PractitionerRole/practitioner-role.svg +5 -0
  15. package/src/assets/containers/ReferralRequest/referral-request.svg +8 -0
  16. package/src/assets/containers/RelatedPerson/related-person.svg +6 -0
  17. package/src/components/containers/Accordion/Accordion.js +44 -13
  18. package/src/components/containers/Accordion/Accordion.stories.js +74 -58
  19. package/src/components/containers/ResourceContainer/ResourceContainer.css +4 -0
  20. package/src/components/containers/ResourceContainer/ResourceContainer.js +28 -37
  21. package/src/components/containers/ResourceContainer/ResourceContainer.stories.js +46 -22
  22. package/src/components/datatypes/CodeableConcept/CodeableConcept.js +6 -3
  23. package/src/components/datatypes/Coding/Coding.js +7 -3
  24. package/src/components/datatypes/Reference/Reference.js +7 -5
  25. package/src/components/datatypes/Telecom/Telecom.js +2 -3
  26. package/src/components/defaultArgTypes.js +12 -0
  27. package/src/components/resources/AdverseEvent/AdverseEvent.js +88 -42
  28. package/src/components/resources/AdverseEvent/AdverseEvent.stories.js +19 -11
  29. package/src/components/resources/AdverseEvent/AdverseEvent.test.js +109 -2
  30. package/src/components/resources/AllergyIntolerance/AllergyIntolerance.js +9 -1
  31. package/src/components/resources/AllergyIntolerance/AllergyIntolerance.stories.js +46 -70
  32. package/src/components/resources/AllergyIntolerance/AllergyIntolerance.test.js +36 -1
  33. package/src/components/resources/Appointment/Appointment.js +9 -1
  34. package/src/components/resources/Appointment/Appointment.stories.js +51 -62
  35. package/src/components/resources/Appointment/Appointment.test.js +36 -1
  36. package/src/components/resources/Binary/Binary.js +2 -1
  37. package/src/components/resources/Binary/Binary.stories.js +27 -21
  38. package/src/components/resources/Bundle/Bundle.css +7 -0
  39. package/src/components/resources/Bundle/Bundle.js +15 -11
  40. package/src/components/resources/Bundle/Bundle.stories.js +59 -115
  41. package/src/components/resources/Bundle/Bundle.test.js +0 -3
  42. package/src/components/resources/CarePlan/CarePlan.js +9 -1
  43. package/src/components/resources/CarePlan/CarePlan.stories.js +44 -54
  44. package/src/components/resources/CarePlan/CarePlan.test.js +42 -6
  45. package/src/components/resources/CareTeam/CareTeam.js +79 -50
  46. package/src/components/resources/CareTeam/CareTeam.stories.js +25 -14
  47. package/src/components/resources/CareTeam/CareTeam.test.js +109 -1
  48. package/src/components/resources/CareTeam/CareTeamParticipants.js +1 -1
  49. package/src/components/resources/Claim/Claim.js +9 -1
  50. package/src/components/resources/Claim/Claim.stories.js +36 -49
  51. package/src/components/resources/Claim/Claim.test.js +32 -1
  52. package/src/components/resources/ClaimResponse/AddedItem.js +61 -11
  53. package/src/components/resources/ClaimResponse/AddedItems.js +5 -9
  54. package/src/components/resources/ClaimResponse/ClaimResponse.js +144 -83
  55. package/src/components/resources/ClaimResponse/ClaimResponse.stories.js +44 -41
  56. package/src/components/resources/ClaimResponse/ClaimResponse.test.js +112 -1
  57. package/src/components/resources/ClaimResponse/Item.js +44 -9
  58. package/src/components/resources/ClaimResponse/Items.js +5 -4
  59. package/src/components/resources/Condition/Condition.js +10 -3
  60. package/src/components/resources/Condition/Condition.stories.js +47 -62
  61. package/src/components/resources/Condition/Condition.test.js +37 -4
  62. package/src/components/resources/Coverage/Coverage.js +9 -1
  63. package/src/components/resources/Coverage/Coverage.stories.js +38 -50
  64. package/src/components/resources/Coverage/Coverage.test.js +36 -1
  65. package/src/components/resources/Device/Device.js +9 -1
  66. package/src/components/resources/Device/Device.stories.js +40 -52
  67. package/src/components/resources/Device/Device.test.js +36 -1
  68. package/src/components/resources/DiagnosticReport/DiagnosticReport.js +9 -2
  69. package/src/components/resources/DiagnosticReport/DiagnosticReport.stories.js +38 -50
  70. package/src/components/resources/DiagnosticReport/DiagnosticReport.test.js +36 -1
  71. package/src/components/resources/DocumentReference/DocumentReference.js +9 -2
  72. package/src/components/resources/DocumentReference/DocumentReference.stories.js +25 -29
  73. package/src/components/resources/DocumentReference/DocumentReference.test.js +42 -1
  74. package/src/components/resources/Encounter/Encounter.js +9 -1
  75. package/src/components/resources/Encounter/Encounter.stories.js +43 -59
  76. package/src/components/resources/Encounter/Encounter.test.js +36 -1
  77. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.js +4 -0
  78. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.stories.js +53 -67
  79. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.test.js +38 -1
  80. package/src/components/resources/ExplanationOfBenefitGraph/ExplanationOfBenefitGraph.stories.js +74 -38
  81. package/src/components/resources/FamilyMemberHistory/FamilyMemberHistory.js +9 -2
  82. package/src/components/resources/FamilyMemberHistory/FamilyMemberHistory.stories.js +22 -28
  83. package/src/components/resources/FamilyMemberHistory/FamilyMemberHistory.test.js +36 -1
  84. package/src/components/resources/Generic/Generic.js +21 -7
  85. package/src/components/resources/Generic/Generic.stories.js +22 -12
  86. package/src/components/resources/Generic/Generic.test.js +26 -7
  87. package/src/components/resources/Goal/Goal.js +9 -3
  88. package/src/components/resources/Goal/Goal.stories.js +35 -49
  89. package/src/components/resources/Goal/Goal.test.js +32 -1
  90. package/src/components/resources/Immunization/Immunization.js +9 -2
  91. package/src/components/resources/Immunization/Immunization.stories.js +38 -51
  92. package/src/components/resources/Immunization/Immunization.test.js +36 -1
  93. package/src/components/resources/List/DrugTierDefinitionExtension.js +79 -35
  94. package/src/components/resources/List/Entries.js +3 -3
  95. package/src/components/resources/List/List.js +137 -88
  96. package/src/components/resources/List/List.stories.js +69 -40
  97. package/src/components/resources/List/List.test.js +105 -1
  98. package/src/components/resources/Location/Location.js +66 -47
  99. package/src/components/resources/Location/Location.stories.js +25 -13
  100. package/src/components/resources/Location/Location.test.js +106 -4
  101. package/src/components/resources/Medication/Medication.js +9 -1
  102. package/src/components/resources/Medication/Medication.stories.js +42 -64
  103. package/src/components/resources/Medication/Medication.test.js +36 -1
  104. package/src/components/resources/MedicationAdministration/MedicationAdministration.js +88 -62
  105. package/src/components/resources/MedicationAdministration/MedicationAdministration.stories.js +34 -41
  106. package/src/components/resources/MedicationAdministration/MedicationAdministration.test.js +117 -1
  107. package/src/components/resources/MedicationDispense/DosageInstruction.js +25 -0
  108. package/src/components/resources/MedicationDispense/MedicationDispense.js +70 -68
  109. package/src/components/resources/MedicationDispense/MedicationDispense.stories.js +41 -52
  110. package/src/components/resources/MedicationDispense/MedicationDispense.test.js +108 -1
  111. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.js +117 -66
  112. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.stories.js +51 -54
  113. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.test.js +110 -1
  114. package/src/components/resources/MedicationOrder/MedicationOrder.js +3 -3
  115. package/src/components/resources/MedicationOrder/MedicationOrder.stories.js +11 -4
  116. package/src/components/resources/MedicationOrder/MedicationOrder.test.js +35 -4
  117. package/src/components/resources/MedicationRequest/MedicationRequest.js +8 -1
  118. package/src/components/resources/MedicationRequest/MedicationRequest.stories.js +27 -30
  119. package/src/components/resources/MedicationRequest/MedicationRequest.test.js +33 -4
  120. package/src/components/resources/MedicationStatement/MedicationStatement.js +9 -2
  121. package/src/components/resources/MedicationStatement/MedicationStatement.stories.js +32 -46
  122. package/src/components/resources/MedicationStatement/MedicationStatement.test.js +36 -1
  123. package/src/components/resources/Observation/Observation.js +3 -1
  124. package/src/components/resources/Observation/Observation.stories.js +39 -33
  125. package/src/components/resources/Observation/Observation.test.js +30 -1
  126. package/src/components/resources/Observation/ObservationGraph.js +1 -1
  127. package/src/components/resources/Organization/Organization.js +10 -2
  128. package/src/components/resources/Organization/Organization.stories.js +40 -52
  129. package/src/components/resources/Organization/Organization.test.js +36 -1
  130. package/src/components/resources/Patient/Patient.js +4 -0
  131. package/src/components/resources/Patient/Patient.stories.js +36 -28
  132. package/src/components/resources/Patient/Patient.test.js +31 -2
  133. package/src/components/resources/Practitioner/Practitioner.js +9 -1
  134. package/src/components/resources/Practitioner/Practitioner.stories.js +39 -52
  135. package/src/components/resources/Practitioner/Practitioner.test.js +36 -1
  136. package/src/components/resources/PractitionerRole/PractitionerRole.js +52 -29
  137. package/src/components/resources/PractitionerRole/PractitionerRole.stories.js +45 -58
  138. package/src/components/resources/PractitionerRole/PractitionerRole.test.js +108 -1
  139. package/src/components/resources/Procedure/Procedure.js +3 -2
  140. package/src/components/resources/Procedure/Procedure.stories.js +33 -25
  141. package/src/components/resources/Procedure/Procedure.test.js +30 -1
  142. package/src/components/resources/Questionnaire/Group.js +53 -0
  143. package/src/components/resources/Questionnaire/Items.js +45 -0
  144. package/src/components/resources/Questionnaire/Questionnaire.css +24 -5
  145. package/src/components/resources/Questionnaire/Questionnaire.js +38 -170
  146. package/src/components/resources/Questionnaire/Questionnaire.stories.js +50 -57
  147. package/src/components/resources/Questionnaire/Questionnaire.test.js +194 -15
  148. package/src/components/resources/Questionnaire/Questions.js +40 -0
  149. package/src/components/resources/Questionnaire/getQuestionText.js +20 -0
  150. package/src/components/resources/QuestionnaireResponse/Answers.js +59 -0
  151. package/src/components/resources/QuestionnaireResponse/Group.js +70 -0
  152. package/src/components/resources/QuestionnaireResponse/Items.js +45 -0
  153. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.css +33 -8
  154. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.js +54 -236
  155. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.stories.js +46 -58
  156. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.test.js +38 -3
  157. package/src/components/resources/QuestionnaireResponse/Questions.js +43 -0
  158. package/src/components/resources/QuestionnaireResponse/getQuestionText.js +22 -0
  159. package/src/components/resources/ReferralRequest/ReferralRequest.js +72 -40
  160. package/src/components/resources/ReferralRequest/ReferralRequest.stories.js +20 -20
  161. package/src/components/resources/ReferralRequest/ReferralRequest.test.js +111 -11
  162. package/src/components/resources/RelatedPerson/RelatedPerson.js +158 -0
  163. package/src/components/resources/RelatedPerson/RelatedPerson.stories.js +42 -0
  164. package/src/components/resources/RelatedPerson/RelatedPerson.test.js +156 -0
  165. package/src/components/resources/RelatedPerson/index.js +3 -0
  166. package/src/components/resources/ResearchStudy/ResearchStudy.js +167 -130
  167. package/src/components/resources/ResearchStudy/ResearchStudy.stories.js +18 -14
  168. package/src/components/resources/ResearchStudy/ResearchStudy.test.js +108 -1
  169. package/src/components/resources/ResourceCategory/ResourceCategory.js +1 -1
  170. package/src/components/resources/ResourceCategory/ResourceCategory.stories.js +40 -27
  171. package/src/components/ui/index.js +48 -31
  172. package/src/fixtures/dstu2/resources/relatedPerson/example1.json +79 -0
  173. package/src/fixtures/example-icons.jsx +42 -0
  174. package/src/fixtures/r4/resources/relatedPerson/example1.json +64 -0
  175. package/src/fixtures/stu3/resources/relatedPerson/example1.json +43 -0
  176. package/src/style.scss +14 -1
  177. package/.storybook/addons.js +0 -1
  178. package/.storybook/config.js +0 -26
  179. package/.storybook/presets.js +0 -1
@@ -2,221 +2,17 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import _get from 'lodash/get';
4
4
  import UnhandledResourceDataStructure from '../UnhandledResourceDataStructure';
5
- import {
6
- Root,
7
- Header,
8
- Title,
9
- Badge,
10
- BadgeSecondary,
11
- Body,
12
- Value,
13
- MissingValue,
14
- } from '../../ui';
5
+ import { Root, Header, Badge, Body, Value } from '../../ui';
15
6
  import Date from '../../datatypes/Date';
16
7
  import fhirVersions from '../fhirResourceVersions';
17
8
  import Coding from '../../datatypes/Coding';
18
9
  import Reference from '../../datatypes/Reference/Reference';
19
- import Attachment from '../../datatypes/Attachment';
20
- import Quantity from '../../datatypes/Quantity';
21
10
  import './QuestionnaireResponse.css';
11
+ import Accordion from '../../containers/Accordion';
12
+ import Items from './Items';
22
13
 
23
14
  const DEFAULT_TITLE = 'Questionnaire Response';
24
15
 
25
- const getQuestionText = item => {
26
- let text = _get(item, 'text');
27
- if (!text) {
28
- // DSTU2
29
- const groupConcept = _get(item, 'concept.0');
30
- if (groupConcept) {
31
- text = <Coding fhirData={groupConcept} />;
32
- }
33
- text = text ? text : <MissingValue />;
34
- // STU3
35
- const groupCode = _get(item, 'code.0');
36
- if (!text && groupCode) {
37
- text = <Coding fhirData={groupCode} />;
38
- }
39
- }
40
- return text;
41
- };
42
-
43
- const answerTypes = {
44
- valueString: value => value,
45
- valueDecimal: value => value,
46
- valueInteger: value => value,
47
- valueDate: value => <Date fhirData={value} />,
48
- valueDateTime: value => <Date fhirData={value} />,
49
- valueCoding: value => <Coding fhirData={value} />,
50
- valueAttachment: value => <Attachment fhirData={value} />,
51
- valueQuantity: value => <Quantity fhirData={value} />,
52
- valueBoolean: value => (value ? 'Yes' : 'No'),
53
- };
54
-
55
- const Answers = props => {
56
- const { data, prepareItems } = props;
57
- if (!Array.isArray(data)) {
58
- return null;
59
- }
60
- return (
61
- <div className="fhir-resource__QuestionnaireResponse-questions-list-item-details">
62
- {data.map(answer => {
63
- return Object.keys(answer).map((answerKey, i) => {
64
- const toRender = [];
65
- if (typeof answerTypes[answerKey] === 'function') {
66
- toRender.push(
67
- <div
68
- key={`item-${i}`}
69
- className="fhir-resource__QuestionnaireResponse-questions-list-item-details-el"
70
- data-testid={`${props['data-testid']}-${i}`}
71
- >
72
- {answerTypes[answerKey](answer[answerKey])}{' '}
73
- </div>,
74
- );
75
- }
76
- if (_get(answer, 'item')) {
77
- toRender.push(
78
- <Group
79
- key={`item-answer-${i}`}
80
- data={answer.item}
81
- prepareItems={prepareItems}
82
- />,
83
- );
84
- }
85
- return toRender;
86
- });
87
- })}
88
- </div>
89
- );
90
- };
91
-
92
- const Group = props => {
93
- const { data, prepareItems } = props;
94
- if (!Array.isArray(data) || data.length === 0) {
95
- return null;
96
- }
97
-
98
- return data.map(prepareItems).map((item, i) => {
99
- const title =
100
- _get(item, 'title') ||
101
- _get(item, 'text') ||
102
- _get(item, '_linkId.fhir_comments.0');
103
-
104
- return (
105
- <ul
106
- key={`item-${i}`}
107
- className="fhir-resource__QuestionnaireResponse-list"
108
- >
109
- <li
110
- className="fhir-resource__QuestionnaireResponse-list-title"
111
- data-testid={`linkId-${item.linkId}`}
112
- >
113
- {title || <MissingValue />}
114
- </li>
115
- {item.isGroup && (
116
- <li>
117
- <Group data={item.group} prepareItems={prepareItems} />
118
- </li>
119
- )}
120
- {!item.isGroup && (
121
- <>
122
- {item.question && (
123
- <li>
124
- <Questions
125
- questions={item.question}
126
- prepareItems={prepareItems}
127
- />
128
- </li>
129
- )}
130
- {item.answer && (
131
- <li>
132
- <Answers
133
- data={item.answer}
134
- prepareItems={prepareItems}
135
- data-testid={`answer-${item.linkId}`}
136
- />
137
- </li>
138
- )}
139
- </>
140
- )}
141
- </ul>
142
- );
143
- });
144
- };
145
-
146
- Group.propTypes = {
147
- data: PropTypes.array,
148
- prepareItems: PropTypes.func.isRequired,
149
- };
150
-
151
- const Questions = props => {
152
- const { questions, prepareItems } = props;
153
- if (!Array.isArray(questions) || questions.length === 0) {
154
- return null;
155
- }
156
- return (
157
- <ul className="fhir-resource__QuestionnaireResponse-questions-list">
158
- {questions.map(prepareItems).map((item, i) => {
159
- const text = getQuestionText(item);
160
- const hasGroup = item.isGroup;
161
- const answers = _get(item, 'answer', []);
162
- return (
163
- <li key={`item-${i}`} data-testid={`linkId-${item.linkId}`}>
164
- {text}
165
- {answers && <Answers data={item.answer} />}
166
- {hasGroup && (
167
- <Group data={item.group} prepareItems={prepareItems} />
168
- )}
169
- </li>
170
- );
171
- })}
172
- </ul>
173
- );
174
- };
175
-
176
- Questions.propTypes = {
177
- questions: PropTypes.array,
178
- prepareItems: PropTypes.func.isRequired,
179
- };
180
-
181
- const Items = props => {
182
- const { fhirVersion, data } = props;
183
- if (fhirVersion === fhirVersions.DSTU2) {
184
- const prepareItems = item => {
185
- return {
186
- ...item,
187
- isGroup: !!_get(item, 'group'),
188
- };
189
- };
190
-
191
- if (data.isGroup) {
192
- return <Group data={data.data} prepareItems={prepareItems} />;
193
- }
194
- return (
195
- <Group data={[{ question: data.data }]} prepareItems={prepareItems} />
196
- );
197
- }
198
-
199
- if (fhirVersion === fhirVersions.STU3 || fhirVersion === fhirVersions.R4) {
200
- const prepareItems = item => ({
201
- ...item,
202
- group: !!_get(item, 'item') ? _get(item, 'item') : null,
203
- isGroup: !!_get(item, 'item'),
204
- });
205
- return <Group data={[{ question: data }]} prepareItems={prepareItems} />;
206
- }
207
-
208
- return null;
209
- };
210
-
211
- Items.propTypes = {
212
- data: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
213
- fhirVersion: PropTypes.oneOf([
214
- fhirVersions.DSTU2,
215
- fhirVersions.STU3,
216
- fhirVersions.R4,
217
- ]).isRequired,
218
- };
219
-
220
16
  const commonDTO = fhirResource => {
221
17
  const status = _get(fhirResource, 'status');
222
18
  const dateTime = _get(fhirResource, 'authored');
@@ -275,8 +71,13 @@ const resourceDTO = (fhirVersion, fhirResource) => {
275
71
  }
276
72
  };
277
73
 
278
- const QuestionnaireResponse = props => {
279
- const { fhirResource, fhirVersion } = props;
74
+ const QuestionnaireResponse = ({
75
+ fhirResource,
76
+ fhirVersion,
77
+ fhirIcons,
78
+ onClick,
79
+ rawOnClick,
80
+ }) => {
280
81
  let fhirResourceData = {};
281
82
 
282
83
  try {
@@ -296,34 +97,51 @@ const QuestionnaireResponse = props => {
296
97
  rootItems,
297
98
  } = fhirResourceData;
298
99
 
100
+ const tableData = [
101
+ {
102
+ label: 'Subject',
103
+ testId: 'subject',
104
+ data: subject && <Reference fhirData={subject} />,
105
+ status: subject,
106
+ },
107
+ {
108
+ label: 'Author',
109
+ testId: 'author',
110
+ data: author && <Reference fhirData={author} />,
111
+ status: author,
112
+ },
113
+ ];
114
+
299
115
  return (
300
- <Root name="Questionnaire">
301
- <Header>
302
- <Title>{title || DEFAULT_TITLE}</Title>
303
- {status && <Badge data-testid="status">{status}</Badge>}
304
- {dateTime && (
305
- <BadgeSecondary data-testid="dateTime">
306
- <Date fhirData={dateTime} />
307
- </BadgeSecondary>
308
- )}
309
- </Header>
310
- <Body>
311
- {subject && (
312
- <Value label="Subject" data-testid="subject">
313
- <Reference fhirData={subject} />
314
- </Value>
315
- )}
316
- {author && (
317
- <Value label="Author" data-testid="author">
318
- <Reference fhirData={author} />
319
- </Value>
320
- )}
321
- {rootItems && (
322
- <div className="overflow-auto">
323
- <Items fhirVersion={fhirVersion} data={rootItems} />
324
- </div>
325
- )}
326
- </Body>
116
+ <Root name="QuestionnaireResponse">
117
+ <Accordion
118
+ headerContent={
119
+ <Header
120
+ resourceName="QuestionnaireResponse"
121
+ title={title || DEFAULT_TITLE}
122
+ badges={status && <Badge data-testid="status">{status}</Badge>}
123
+ additionalContent={
124
+ dateTime && (
125
+ <Value label="On" data-testid="dateTime">
126
+ <Date fhirData={dateTime} isBlack />
127
+ </Value>
128
+ )
129
+ }
130
+ icon={fhirIcons}
131
+ />
132
+ }
133
+ bodyContent={
134
+ <Body tableData={tableData}>
135
+ {rootItems && (
136
+ <div className="overflow-auto">
137
+ <Items fhirVersion={fhirVersion} data={rootItems} />
138
+ </div>
139
+ )}
140
+ </Body>
141
+ }
142
+ onClick={onClick}
143
+ rawOnClick={rawOnClick}
144
+ />
327
145
  </Root>
328
146
  );
329
147
  };
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { object } from '@storybook/addon-knobs';
2
+ import { defaultArgTypes } from '../../defaultArgTypes';
3
3
 
4
4
  import QuestionnaireResponse from './QuestionnaireResponse';
5
5
  import fhirVersions from '../fhirResourceVersions';
@@ -14,74 +14,62 @@ import stu3Example2 from '../../../fixtures/stu3/resources/questionnaireResponse
14
14
  import r4Example1 from '../../../fixtures/r4/resources/questionnaireResponse/example1.json';
15
15
  import r4Example2 from '../../../fixtures/r4/resources/questionnaireResponse/example2.json';
16
16
 
17
- export default { title: 'QuestionnaireResponse' };
17
+ import fhirIcons from '../../../fixtures/example-icons';
18
+ import QuestionnaireResponseIcon from '../../../assets/containers/QuestionnaireResponse/questionnaire-response.svg';
18
19
 
19
- export const DefaultVisualizationDSTU2 = () => {
20
- const fhirResource = object('Resource', dstu2Example1);
21
- return (
22
- <QuestionnaireResponse
23
- fhirVersion={fhirVersions.DSTU2}
24
- fhirResource={fhirResource}
25
- />
26
- );
20
+ export default {
21
+ title: 'QuestionnaireResponse',
22
+ component: QuestionnaireResponse,
23
+ argTypes: {
24
+ ...defaultArgTypes,
25
+ },
27
26
  };
28
27
 
29
- export const Example2OfDSTU2 = () => {
30
- const fhirResource = object('Resource', dstu2Example2);
31
- return (
32
- <QuestionnaireResponse
33
- fhirVersion={fhirVersions.DSTU2}
34
- fhirResource={fhirResource}
35
- />
36
- );
28
+ const Template = args => <QuestionnaireResponse {...args} />;
29
+
30
+ export const DefaultVisualizationDSTU2 = Template.bind({});
31
+ DefaultVisualizationDSTU2.args = {
32
+ fhirVersion: fhirVersions.DSTU2,
33
+ fhirResource: dstu2Example1,
34
+ fhirIcons: require('../../../assets/containers/QuestionnaireResponse/questionnaire-response.svg'),
35
+ };
36
+
37
+ export const Example2OfDSTU2 = Template.bind({});
38
+ Example2OfDSTU2.args = {
39
+ fhirVersion: fhirVersions.DSTU2,
40
+ fhirResource: dstu2Example2,
41
+ fhirIcons: QuestionnaireResponseIcon,
37
42
  };
38
43
 
39
- export const Example3OfDSTU2 = () => {
40
- const fhirResource = object('Resource', dstu2Example3);
41
- return (
42
- <QuestionnaireResponse
43
- fhirVersion={fhirVersions.DSTU2}
44
- fhirResource={fhirResource}
45
- />
46
- );
44
+ export const Example3OfDSTU2 = Template.bind({});
45
+ Example3OfDSTU2.args = {
46
+ fhirVersion: fhirVersions.DSTU2,
47
+ fhirResource: dstu2Example3,
48
+ fhirIcons: fhirIcons,
47
49
  };
48
50
 
49
- export const Example1OfSTU3 = () => {
50
- const fhirResource = object('Resource', stu3Example1);
51
- return (
52
- <QuestionnaireResponse
53
- fhirVersion={fhirVersions.STU3}
54
- fhirResource={fhirResource}
55
- />
56
- );
51
+ export const Example1OfSTU3 = Template.bind({});
52
+ Example1OfSTU3.args = {
53
+ fhirVersion: fhirVersions.STU3,
54
+ fhirResource: stu3Example1,
55
+ fhirIcons: false,
57
56
  };
58
57
 
59
- export const Example2OfSTU3 = () => {
60
- const fhirResource = object('Resource', stu3Example2);
61
- return (
62
- <QuestionnaireResponse
63
- fhirVersion={fhirVersions.STU3}
64
- fhirResource={fhirResource}
65
- />
66
- );
58
+ export const Example2OfSTU3 = Template.bind({});
59
+ Example2OfSTU3.args = {
60
+ fhirVersion: fhirVersions.STU3,
61
+ fhirResource: stu3Example2,
62
+ fhirIcons: 'random text',
67
63
  };
68
64
 
69
- export const Example1OfR4 = () => {
70
- const fhirResource = object('Resource', r4Example1);
71
- return (
72
- <QuestionnaireResponse
73
- fhirVersion={fhirVersions.R4}
74
- fhirResource={fhirResource}
75
- />
76
- );
65
+ export const Example1OfR4 = Template.bind({});
66
+ Example1OfR4.args = {
67
+ fhirVersion: fhirVersions.R4,
68
+ fhirResource: r4Example1,
77
69
  };
78
70
 
79
- export const Example2OfR4 = () => {
80
- const fhirResource = object('Resource', r4Example2);
81
- return (
82
- <QuestionnaireResponse
83
- fhirVersion={fhirVersions.R4}
84
- fhirResource={fhirResource}
85
- />
86
- );
71
+ export const Example2OfR4 = Template.bind({});
72
+ Example2OfR4.args = {
73
+ fhirVersion: fhirVersions.R4,
74
+ fhirResource: r4Example2,
87
75
  };
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { render } from '@testing-library/react';
2
+ import { fireEvent, render } from '@testing-library/react';
3
3
 
4
4
  import QuestionnaireResponse from './QuestionnaireResponse';
5
5
  import fhirVersions from '../fhirResourceVersions';
@@ -24,7 +24,7 @@ describe('QuestionnaireResponse should render component correctly', () => {
24
24
  );
25
25
  expect(getByTestId('status').textContent).toEqual('completed');
26
26
  expect(getByTestId('dateTime').textContent).toEqual('6/18/2013');
27
- expect(getByTestId('subject').textContent).toEqual('RoelPatient/f201');
27
+ expect(getByTestId('subject').textContent).toEqual('Roel');
28
28
  expect(getByTestId('author').textContent).toEqual('Practitioner/f201');
29
29
 
30
30
  expect(getByTestId('linkId-1.1').textContent).toEqual(
@@ -91,7 +91,7 @@ describe('QuestionnaireResponse should render component correctly', () => {
91
91
  );
92
92
  expect(getByTestId('status').textContent).toEqual('completed');
93
93
  expect(getByTestId('dateTime').textContent).toEqual('6/18/2013');
94
- expect(getByTestId('subject').textContent).toEqual('RoelPatient/f201');
94
+ expect(getByTestId('subject').textContent).toEqual('Roel');
95
95
  expect(getByTestId('author').textContent).toEqual('Practitioner/f201');
96
96
 
97
97
  expect(getByTestId('linkId-1.1').textContent).toEqual(
@@ -112,4 +112,39 @@ describe('QuestionnaireResponse should render component correctly', () => {
112
112
  'Do you drink alchohol?',
113
113
  );
114
114
  });
115
+
116
+ it('should fire custom onClick function', () => {
117
+ const defaultProps = {
118
+ fhirResource: r4Example1,
119
+ fhirVersion: fhirVersions.R4,
120
+ };
121
+
122
+ const onClick = jest.fn();
123
+ const { getByRole } = render(
124
+ <QuestionnaireResponse {...defaultProps} onClick={onClick} />,
125
+ );
126
+ const accordion = getByRole('button');
127
+ fireEvent.click(accordion);
128
+
129
+ const attribute = accordion.getAttribute('data-bs-toggle');
130
+ expect(attribute).not.toEqual('collapse');
131
+ expect(onClick).toHaveBeenCalled();
132
+ });
133
+
134
+ it('should not fire custom onClick function', () => {
135
+ const defaultProps = {
136
+ fhirResource: r4Example1,
137
+ fhirVersion: fhirVersions.R4,
138
+ };
139
+
140
+ const onClick = 'test';
141
+ const { getByRole } = render(
142
+ <QuestionnaireResponse {...defaultProps} onClick={onClick} />,
143
+ );
144
+ const accordion = getByRole('button');
145
+ fireEvent.click(accordion);
146
+
147
+ const attribute = accordion.getAttribute('data-bs-toggle');
148
+ expect(attribute).toEqual('collapse');
149
+ });
115
150
  });
@@ -0,0 +1,43 @@
1
+ import _get from 'lodash/get';
2
+ import PropTypes from 'prop-types';
3
+ import React from 'react';
4
+ import Group from './Group';
5
+ import Answers from './Answers';
6
+ import { getQuestionText } from './getQuestionText';
7
+
8
+ const Questions = ({ questions, prepareItems }) => {
9
+ if (!Array.isArray(questions) || questions.length === 0) {
10
+ return null;
11
+ }
12
+
13
+ return (
14
+ <ul className="fhir-resource__QuestionnaireResponse-questions-list">
15
+ {questions.map(prepareItems).map((item, i) => {
16
+ const text = getQuestionText(item);
17
+ const hasGroup = item.isGroup;
18
+ const answers = _get(item, 'answer', []);
19
+ return (
20
+ <li
21
+ key={`questionnaire-response-questions-item-${i}`}
22
+ data-testid={`linkId-${item.linkId}`}
23
+ >
24
+ <div className="fhir-resource__QuestionnaireResponse-questions-list-element">
25
+ {text}
26
+ </div>
27
+ {answers && <Answers data={item.answer} />}
28
+ {hasGroup && (
29
+ <Group data={item.group} prepareItems={prepareItems} isChild />
30
+ )}
31
+ </li>
32
+ );
33
+ })}
34
+ </ul>
35
+ );
36
+ };
37
+
38
+ Questions.propTypes = {
39
+ questions: PropTypes.array,
40
+ prepareItems: PropTypes.func.isRequired,
41
+ };
42
+
43
+ export default Questions;
@@ -0,0 +1,22 @@
1
+ import _get from 'lodash/get';
2
+ import Coding from '../../datatypes/Coding';
3
+ import { MissingValue } from '../../ui';
4
+ import React from 'react';
5
+
6
+ export const getQuestionText = item => {
7
+ let text = _get(item, 'text');
8
+ if (!text) {
9
+ // DSTU2
10
+ const groupConcept = _get(item, 'concept.0');
11
+ if (groupConcept) {
12
+ text = <Coding fhirData={groupConcept} />;
13
+ }
14
+ text = text ? text : <MissingValue />;
15
+ // STU3
16
+ const groupCode = _get(item, 'code.0');
17
+ if (!text && groupCode) {
18
+ text = <Coding fhirData={groupCode} />;
19
+ }
20
+ }
21
+ return text;
22
+ };