fhir-react 0.3.7 → 0.3.8

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 (138) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/.eslintrc +10 -1
  3. package/.stylelintrc +6 -2
  4. package/README.md +19 -1
  5. package/build/index.js +15 -11
  6. package/build/style.css +7 -7
  7. package/package.json +55 -54
  8. package/src/assets/containers/AdverseEvent/adverse-event.svg +6 -0
  9. package/src/assets/containers/Generic/generic.svg +3 -0
  10. package/src/assets/containers/MedicationDispense/medication-dispense.svg +5 -0
  11. package/src/assets/containers/PractitionerRole/practitioner-role.svg +5 -0
  12. package/src/assets/containers/ReferralRequest/referral-request.svg +8 -0
  13. package/src/assets/containers/RelatedPerson/related-person.svg +6 -0
  14. package/src/components/containers/Accordion/Accordion.js +21 -13
  15. package/src/components/datatypes/CodeableConcept/CodeableConcept.js +6 -3
  16. package/src/components/datatypes/Coding/Coding.js +7 -3
  17. package/src/components/datatypes/Reference/Reference.js +7 -5
  18. package/src/components/datatypes/Telecom/Telecom.js +2 -3
  19. package/src/components/resources/AdverseEvent/AdverseEvent.js +81 -42
  20. package/src/components/resources/AdverseEvent/AdverseEvent.stories.js +12 -2
  21. package/src/components/resources/AdverseEvent/AdverseEvent.test.js +109 -2
  22. package/src/components/resources/AllergyIntolerance/AllergyIntolerance.js +7 -1
  23. package/src/components/resources/AllergyIntolerance/AllergyIntolerance.test.js +36 -1
  24. package/src/components/resources/Appointment/Appointment.js +2 -1
  25. package/src/components/resources/Appointment/Appointment.test.js +36 -1
  26. package/src/components/resources/Bundle/Bundle.css +7 -0
  27. package/src/components/resources/Bundle/Bundle.js +15 -11
  28. package/src/components/resources/Bundle/Bundle.stories.js +12 -78
  29. package/src/components/resources/Bundle/Bundle.test.js +0 -3
  30. package/src/components/resources/CarePlan/CarePlan.js +2 -1
  31. package/src/components/resources/CarePlan/CarePlan.test.js +42 -6
  32. package/src/components/resources/CareTeam/CareTeam.js +72 -50
  33. package/src/components/resources/CareTeam/CareTeam.stories.js +20 -3
  34. package/src/components/resources/CareTeam/CareTeam.test.js +109 -1
  35. package/src/components/resources/CareTeam/CareTeamParticipants.js +1 -1
  36. package/src/components/resources/Claim/Claim.js +2 -1
  37. package/src/components/resources/Claim/Claim.test.js +32 -1
  38. package/src/components/resources/ClaimResponse/AddedItem.js +61 -11
  39. package/src/components/resources/ClaimResponse/AddedItems.js +5 -9
  40. package/src/components/resources/ClaimResponse/ClaimResponse.js +137 -83
  41. package/src/components/resources/ClaimResponse/ClaimResponse.stories.js +15 -2
  42. package/src/components/resources/ClaimResponse/ClaimResponse.test.js +112 -1
  43. package/src/components/resources/ClaimResponse/Item.js +44 -9
  44. package/src/components/resources/ClaimResponse/Items.js +5 -4
  45. package/src/components/resources/Condition/Condition.js +3 -3
  46. package/src/components/resources/Condition/Condition.test.js +37 -4
  47. package/src/components/resources/Coverage/Coverage.js +2 -1
  48. package/src/components/resources/Coverage/Coverage.test.js +36 -1
  49. package/src/components/resources/Device/Device.js +2 -1
  50. package/src/components/resources/Device/Device.test.js +36 -1
  51. package/src/components/resources/DiagnosticReport/DiagnosticReport.js +7 -2
  52. package/src/components/resources/DiagnosticReport/DiagnosticReport.test.js +36 -1
  53. package/src/components/resources/DocumentReference/DocumentReference.js +7 -2
  54. package/src/components/resources/DocumentReference/DocumentReference.test.js +42 -1
  55. package/src/components/resources/Encounter/Encounter.js +2 -1
  56. package/src/components/resources/Encounter/Encounter.test.js +36 -1
  57. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.js +2 -0
  58. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.test.js +38 -1
  59. package/src/components/resources/FamilyMemberHistory/FamilyMemberHistory.js +7 -2
  60. package/src/components/resources/FamilyMemberHistory/FamilyMemberHistory.test.js +36 -1
  61. package/src/components/resources/Generic/Generic.js +20 -7
  62. package/src/components/resources/Generic/Generic.stories.js +2 -1
  63. package/src/components/resources/Generic/Generic.test.js +26 -7
  64. package/src/components/resources/Goal/Goal.js +2 -3
  65. package/src/components/resources/Goal/Goal.test.js +32 -1
  66. package/src/components/resources/Immunization/Immunization.js +2 -2
  67. package/src/components/resources/Immunization/Immunization.test.js +36 -1
  68. package/src/components/resources/List/DrugTierDefinitionExtension.js +79 -35
  69. package/src/components/resources/List/Entries.js +3 -3
  70. package/src/components/resources/List/List.js +135 -88
  71. package/src/components/resources/List/List.stories.js +38 -5
  72. package/src/components/resources/List/List.test.js +105 -1
  73. package/src/components/resources/Location/Location.js +65 -47
  74. package/src/components/resources/Location/Location.stories.js +11 -4
  75. package/src/components/resources/Location/Location.test.js +106 -4
  76. package/src/components/resources/Medication/Medication.js +2 -1
  77. package/src/components/resources/Medication/Medication.test.js +36 -1
  78. package/src/components/resources/MedicationAdministration/MedicationAdministration.js +86 -62
  79. package/src/components/resources/MedicationAdministration/MedicationAdministration.stories.js +7 -0
  80. package/src/components/resources/MedicationAdministration/MedicationAdministration.test.js +117 -1
  81. package/src/components/resources/MedicationDispense/DosageInstruction.js +25 -0
  82. package/src/components/resources/MedicationDispense/MedicationDispense.js +68 -68
  83. package/src/components/resources/MedicationDispense/MedicationDispense.stories.js +7 -0
  84. package/src/components/resources/MedicationDispense/MedicationDispense.test.js +108 -1
  85. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.js +115 -66
  86. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.stories.js +6 -0
  87. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.test.js +110 -1
  88. package/src/components/resources/MedicationOrder/MedicationOrder.js +2 -3
  89. package/src/components/resources/MedicationOrder/MedicationOrder.test.js +35 -4
  90. package/src/components/resources/MedicationRequest/MedicationRequest.js +2 -1
  91. package/src/components/resources/MedicationRequest/MedicationRequest.test.js +33 -4
  92. package/src/components/resources/MedicationStatement/MedicationStatement.js +7 -2
  93. package/src/components/resources/MedicationStatement/MedicationStatement.test.js +36 -1
  94. package/src/components/resources/Observation/Observation.js +2 -1
  95. package/src/components/resources/Observation/Observation.test.js +30 -1
  96. package/src/components/resources/Organization/Organization.js +3 -2
  97. package/src/components/resources/Organization/Organization.test.js +36 -1
  98. package/src/components/resources/Patient/Patient.js +2 -0
  99. package/src/components/resources/Patient/Patient.test.js +31 -2
  100. package/src/components/resources/Practitioner/Practitioner.js +2 -1
  101. package/src/components/resources/Practitioner/Practitioner.test.js +36 -1
  102. package/src/components/resources/PractitionerRole/PractitionerRole.js +50 -29
  103. package/src/components/resources/PractitionerRole/PractitionerRole.stories.js +7 -0
  104. package/src/components/resources/PractitionerRole/PractitionerRole.test.js +108 -1
  105. package/src/components/resources/Procedure/Procedure.js +2 -2
  106. package/src/components/resources/Procedure/Procedure.test.js +30 -1
  107. package/src/components/resources/Questionnaire/Group.js +53 -0
  108. package/src/components/resources/Questionnaire/Items.js +45 -0
  109. package/src/components/resources/Questionnaire/Questionnaire.css +24 -5
  110. package/src/components/resources/Questionnaire/Questionnaire.js +31 -170
  111. package/src/components/resources/Questionnaire/Questionnaire.stories.js +8 -0
  112. package/src/components/resources/Questionnaire/Questionnaire.test.js +194 -15
  113. package/src/components/resources/Questionnaire/Questions.js +40 -0
  114. package/src/components/resources/Questionnaire/getQuestionText.js +20 -0
  115. package/src/components/resources/QuestionnaireResponse/Answers.js +59 -0
  116. package/src/components/resources/QuestionnaireResponse/Group.js +70 -0
  117. package/src/components/resources/QuestionnaireResponse/Items.js +45 -0
  118. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.css +33 -8
  119. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.js +52 -236
  120. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.stories.js +8 -0
  121. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.test.js +38 -3
  122. package/src/components/resources/QuestionnaireResponse/Questions.js +43 -0
  123. package/src/components/resources/QuestionnaireResponse/getQuestionText.js +22 -0
  124. package/src/components/resources/ReferralRequest/ReferralRequest.js +65 -40
  125. package/src/components/resources/ReferralRequest/ReferralRequest.test.js +111 -11
  126. package/src/components/resources/RelatedPerson/RelatedPerson.js +151 -0
  127. package/src/components/resources/RelatedPerson/RelatedPerson.stories.js +46 -0
  128. package/src/components/resources/RelatedPerson/RelatedPerson.test.js +156 -0
  129. package/src/components/resources/RelatedPerson/index.js +3 -0
  130. package/src/components/resources/ResearchStudy/ResearchStudy.js +160 -130
  131. package/src/components/resources/ResearchStudy/ResearchStudy.stories.js +2 -0
  132. package/src/components/resources/ResearchStudy/ResearchStudy.test.js +108 -1
  133. package/src/components/ui/index.js +22 -9
  134. package/src/fixtures/dstu2/resources/relatedPerson/example1.json +79 -0
  135. package/src/fixtures/example-icons.jsx +42 -0
  136. package/src/fixtures/r4/resources/relatedPerson/example1.json +64 -0
  137. package/src/fixtures/stu3/resources/relatedPerson/example1.json +43 -0
  138. package/src/style.scss +3 -1
@@ -4,8 +4,7 @@ import {
4
4
  Header,
5
5
  MissingValue,
6
6
  Root,
7
- Title,
8
- Value,
7
+ ValueSection,
9
8
  } from '../../ui';
10
9
 
11
10
  import CareTeamParticipants from './CareTeamParticipants';
@@ -16,6 +15,7 @@ import React from 'react';
16
15
  import Reference from '../../datatypes/Reference';
17
16
  import _get from 'lodash/get';
18
17
  import fhirVersions from '../fhirResourceVersions';
18
+ import Accordion from '../../containers/Accordion';
19
19
 
20
20
  const commonDTO = fhirResource => {
21
21
  // Default value for title - "Care team"
@@ -83,8 +83,7 @@ const resourceDTO = (fhirVersion, fhirResource) => {
83
83
  }
84
84
  };
85
85
 
86
- const CareTeam = props => {
87
- const { fhirResource, fhirVersion } = props;
86
+ const CareTeam = ({ fhirResource, fhirVersion, fhirIcons, onClick }) => {
88
87
  const {
89
88
  name,
90
89
  status,
@@ -98,54 +97,77 @@ const CareTeam = props => {
98
97
  } = resourceDTO(fhirVersion, fhirResource);
99
98
  const hasParticipants = participants.length > 0;
100
99
 
100
+ const tableData = [
101
+ {
102
+ label: 'Category',
103
+ testId: 'category',
104
+ data: category && <CodableConcept fhirData={category} isCursive />,
105
+ status: category,
106
+ },
107
+ {
108
+ label: 'Subject',
109
+ testId: 'subject',
110
+ data: subject && <Reference fhirData={subject} />,
111
+ status: subject,
112
+ },
113
+ {
114
+ label: 'Encounter',
115
+ testId: 'encounter',
116
+ data: encounter && <Reference fhirData={encounter} />,
117
+ status: encounter,
118
+ },
119
+ {
120
+ label: 'Managing organization',
121
+ testId: 'managingOrganization',
122
+ data: managingOrganization && (
123
+ <Reference fhirData={managingOrganization} />
124
+ ),
125
+ status: managingOrganization,
126
+ },
127
+ {
128
+ label: 'Care Period Start',
129
+ testId: 'periodStart',
130
+ data: periodStart ? (
131
+ <DateType fhirData={periodStart} isBlack />
132
+ ) : (
133
+ <MissingValue />
134
+ ),
135
+ status: periodStart,
136
+ },
137
+ {
138
+ label: 'Care Period End',
139
+ testId: 'periodEnd',
140
+ data: periodEnd ? (
141
+ <DateType fhirData={periodEnd} isBlack />
142
+ ) : (
143
+ <MissingValue />
144
+ ),
145
+ status: periodEnd,
146
+ },
147
+ ];
148
+
101
149
  return (
102
150
  <Root name="CareTeam">
103
- <Header>
104
- {name && <Title>{name}</Title>}
105
- {status && <Badge data-testid="status">{status}</Badge>}
106
- </Header>
107
- <Body>
108
- {category && (
109
- <Value label="Category" data-testid="category">
110
- <CodableConcept fhirData={category} />
111
- </Value>
112
- )}
113
- {subject && (
114
- <Value label="Subject" data-testid="subject">
115
- <Reference fhirData={subject} />
116
- </Value>
117
- )}
118
- {encounter && (
119
- <Value label="Encounter" data-testid="encounter">
120
- <Reference fhirData={encounter} />
121
- </Value>
122
- )}
123
- {managingOrganization && (
124
- <Value
125
- label="Managing organization"
126
- data-testid="managingOrganization"
127
- >
128
- <Reference fhirData={managingOrganization} />
129
- </Value>
130
- )}
131
- {periodStart && (
132
- <Value label="Care Period Start" data-testid="periodStart">
133
- {periodStart ? (
134
- <DateType fhirData={periodStart} />
135
- ) : (
136
- <MissingValue />
137
- )}
138
- </Value>
139
- )}
140
- {periodEnd && (
141
- <Value label="Care Period End" data-testid="periodEnd">
142
- {periodEnd ? <DateType fhirData={periodEnd} /> : <MissingValue />}
143
- </Value>
144
- )}
145
- {hasParticipants && (
146
- <CareTeamParticipants participants={participants} />
147
- )}
148
- </Body>
151
+ <Accordion
152
+ headerContent={
153
+ <Header
154
+ resourceName={'CareTeam'}
155
+ icon={fhirIcons}
156
+ title={name}
157
+ badges={status && <Badge data-testid="status">{status}</Badge>}
158
+ />
159
+ }
160
+ bodyContent={
161
+ <Body tableData={tableData}>
162
+ <ValueSection>
163
+ {hasParticipants && (
164
+ <CareTeamParticipants participants={participants} />
165
+ )}
166
+ </ValueSection>
167
+ </Body>
168
+ }
169
+ onClick={onClick}
170
+ />
149
171
  </Root>
150
172
  );
151
173
  };
@@ -7,6 +7,9 @@ import example_STU3 from '../../../fixtures/stu3/resources/careTeam/example1.jso
7
7
  import example2_STU3 from '../../../fixtures/stu3/resources/careTeam/example2.json';
8
8
  import example_R4 from '../../../fixtures/r4/resources/careTeam/example1.json';
9
9
 
10
+ import fhirIcons from '../../../fixtures/example-icons';
11
+ import CareTeamIcon from '../../../assets/containers/CareTeam/care-team.svg';
12
+
10
13
  export default {
11
14
  title: 'CareTeam',
12
15
  };
@@ -14,18 +17,32 @@ export default {
14
17
  export const ExampleSTU3 = () => {
15
18
  const fhirResource = object('Resource', example_STU3);
16
19
  return (
17
- <CareTeam fhirResource={fhirResource} fhirVersion={fhirVersions.STU3} />
20
+ <CareTeam
21
+ fhirResource={fhirResource}
22
+ fhirVersion={fhirVersions.STU3}
23
+ fhirIcons={CareTeamIcon}
24
+ />
18
25
  );
19
26
  };
20
27
 
21
28
  export const Example2OfSTU3 = () => {
22
29
  const fhirResource = object('Resource', example2_STU3);
23
30
  return (
24
- <CareTeam fhirResource={fhirResource} fhirVersion={fhirVersions.STU3} />
31
+ <CareTeam
32
+ fhirResource={fhirResource}
33
+ fhirVersion={fhirVersions.STU3}
34
+ fhirIcons={fhirIcons}
35
+ />
25
36
  );
26
37
  };
27
38
 
28
39
  export const ExampleR4 = () => {
29
40
  const fhirResource = object('Resource', example_R4);
30
- return <CareTeam fhirResource={fhirResource} fhirVersion={fhirVersions.R4} />;
41
+ return (
42
+ <CareTeam
43
+ fhirResource={fhirResource}
44
+ fhirVersion={fhirVersions.R4}
45
+ fhirIcons={false}
46
+ />
47
+ );
31
48
  };
@@ -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 CareTeam from './CareTeam';
5
5
  import fhirVersions from '../fhirResourceVersions';
@@ -8,7 +8,80 @@ import stu3Example1 from '../../../fixtures/stu3/resources/careTeam/example1.jso
8
8
  import stu3Example2 from '../../../fixtures/stu3/resources/careTeam/example2.json';
9
9
  import r4Example1 from '../../../fixtures/r4/resources/careTeam/example1.json';
10
10
 
11
+ import fhirIcons from '../../../fixtures/example-icons';
12
+
11
13
  describe('should render the CareTeam component properly', () => {
14
+ it('component without a fhirIcons props should render a default icon', () => {
15
+ const defaultProps = {
16
+ fhirVersion: fhirVersions.STU3,
17
+ fhirResource: stu3Example1,
18
+ };
19
+
20
+ const { getByAltText } = render(<CareTeam {...defaultProps} />);
21
+ const headerIcon = getByAltText('care team');
22
+
23
+ expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
24
+ });
25
+
26
+ it('component with a false as a fhirIcons props should render a placeholder', () => {
27
+ const defaultProps = {
28
+ fhirVersion: fhirVersions.STU3,
29
+ fhirResource: stu3Example1,
30
+ fhirIcons: false,
31
+ };
32
+
33
+ const { getByTestId } = render(<CareTeam {...defaultProps} />);
34
+ const headerIcon = getByTestId('placeholder');
35
+
36
+ expect(headerIcon).toBeTruthy();
37
+ });
38
+
39
+ it('component with the img as a fhirIcons props should render an img', () => {
40
+ const defaultProps = {
41
+ fhirVersion: fhirVersions.STU3,
42
+ fhirResource: stu3Example1,
43
+ fhirIcons: (
44
+ <img
45
+ src={require('../assets/containers/CareTeam/care-team.svg')}
46
+ alt="group of people"
47
+ />
48
+ ),
49
+ };
50
+
51
+ const { getByAltText } = render(<CareTeam {...defaultProps} />);
52
+ const headerIcon = getByAltText('group of people');
53
+
54
+ expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
55
+ });
56
+
57
+ it('component with the resources object as a fhirIcons props should render an img', () => {
58
+ const defaultProps = {
59
+ fhirVersion: fhirVersions.STU3,
60
+ fhirResource: stu3Example1,
61
+ fhirIcons: fhirIcons,
62
+ };
63
+
64
+ const { getByAltText } = render(<CareTeam {...defaultProps} />);
65
+ const headerIcon = getByAltText('group of people');
66
+
67
+ expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
68
+ });
69
+
70
+ it('component with the url as a fhirIcons props should render an img', () => {
71
+ const avatarSrc =
72
+ 'https://www.gravatar.com/avatar/?s=50&r=any&default=identicon&forcedefault=1';
73
+ const defaultProps = {
74
+ fhirVersion: fhirVersions.STU3,
75
+ fhirResource: stu3Example1,
76
+ fhirIcons: avatarSrc,
77
+ };
78
+
79
+ const { getByAltText } = render(<CareTeam {...defaultProps} />);
80
+ const headerIcon = getByAltText('header icon');
81
+
82
+ expect(headerIcon.getAttribute('src')).toContain(avatarSrc);
83
+ });
84
+
12
85
  it('should render with STU3 source data', () => {
13
86
  const defaultProps = {
14
87
  fhirResource: stu3Example1,
@@ -117,4 +190,39 @@ describe('should render the CareTeam component properly', () => {
117
190
  );
118
191
  expect(periodEnds).toEqual(['-', '1/1/2013']);
119
192
  });
193
+
194
+ it('should fire custom onClick function', () => {
195
+ const defaultProps = {
196
+ fhirResource: r4Example1,
197
+ fhirVersion: fhirVersions.R4,
198
+ };
199
+
200
+ const onClick = jest.fn();
201
+ const { getByRole } = render(
202
+ <CareTeam {...defaultProps} onClick={onClick} />,
203
+ );
204
+ const accordion = getByRole('button');
205
+ fireEvent.click(accordion);
206
+
207
+ const attribute = accordion.getAttribute('data-bs-toggle');
208
+ expect(attribute).not.toEqual('collapse');
209
+ expect(onClick).toHaveBeenCalled();
210
+ });
211
+
212
+ it('should not fire custom onClick function', () => {
213
+ const defaultProps = {
214
+ fhirResource: r4Example1,
215
+ fhirVersion: fhirVersions.R4,
216
+ };
217
+
218
+ const onClick = 'test';
219
+ const { getByRole } = render(
220
+ <CareTeam {...defaultProps} onClick={onClick} />,
221
+ );
222
+ const accordion = getByRole('button');
223
+ fireEvent.click(accordion);
224
+
225
+ const attribute = accordion.getAttribute('data-bs-toggle');
226
+ expect(attribute).toEqual('collapse');
227
+ });
120
228
  });
@@ -20,7 +20,7 @@ const CareTeamParticipants = props => {
20
20
  <TableHeader>End</TableHeader>
21
21
  </TableRow>
22
22
  </thead>
23
- <tbody>{allParticipants}</tbody>
23
+ <tbody className="border-top-0">{allParticipants}</tbody>
24
24
  </Table>
25
25
  </ValueSection>
26
26
  );
@@ -298,7 +298,7 @@ const resourceDTO = (fhirVersion, fhirResource) => {
298
298
  }
299
299
  };
300
300
 
301
- const Claim = ({ fhirResource, fhirVersion, fhirIcons }) => {
301
+ const Claim = ({ fhirResource, fhirVersion, fhirIcons, onClick }) => {
302
302
  let fhirResourceData = {};
303
303
  try {
304
304
  fhirResourceData = resourceDTO(fhirVersion, fhirResource);
@@ -481,6 +481,7 @@ const Claim = ({ fhirResource, fhirVersion, fhirIcons }) => {
481
481
  {items && <Items items={items} />}
482
482
  </Body>
483
483
  }
484
+ onClick={onClick}
484
485
  />
485
486
  </Root>
486
487
  );
@@ -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 Claim from './Claim';
5
5
  import fhirVersions from '../fhirResourceVersions';
@@ -360,4 +360,35 @@ describe('should render the Claim component properly', () => {
360
360
  expect(quantities).toEqual(['-']);
361
361
  expect(netPrices).toEqual(['135.57 USD']);
362
362
  });
363
+
364
+ it('should fire custom onClick function', () => {
365
+ const defaultProps = {
366
+ fhirResource: r4Example1,
367
+ fhirVersion: fhirVersions.R4,
368
+ };
369
+
370
+ const onClick = jest.fn();
371
+ const { getByRole } = render(<Claim {...defaultProps} onClick={onClick} />);
372
+ const accordion = getByRole('button');
373
+ fireEvent.click(accordion);
374
+
375
+ const attribute = accordion.getAttribute('data-bs-toggle');
376
+ expect(attribute).not.toEqual('collapse');
377
+ expect(onClick).toHaveBeenCalled();
378
+ });
379
+
380
+ it('should not fire custom onClick function', () => {
381
+ const defaultProps = {
382
+ fhirResource: r4Example1,
383
+ fhirVersion: fhirVersions.R4,
384
+ };
385
+
386
+ const onClick = 'test';
387
+ const { getByRole } = render(<Claim {...defaultProps} onClick={onClick} />);
388
+ const accordion = getByRole('button');
389
+ fireEvent.click(accordion);
390
+
391
+ const attribute = accordion.getAttribute('data-bs-toggle');
392
+ expect(attribute).toEqual('collapse');
393
+ });
363
394
  });
@@ -1,27 +1,62 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
 
3
- import { TableCell, TableRow } from '../../ui';
3
+ import { Chevron, TableCell, TableRow } from '../../ui';
4
4
  import Coding from '../../datatypes/Coding';
5
5
  import Money from '../../datatypes/Money';
6
6
  import Item from './Item';
7
7
 
8
- const AddedItem = props => {
9
- const { addedItem, parentSequences, level } = props;
10
-
8
+ const AddedItem = ({
9
+ addedItem,
10
+ parentSequences,
11
+ parentId,
12
+ isCollapse = false,
13
+ }) => {
11
14
  const itemSequences = [...parentSequences, addedItem.sequenceLinkId];
12
15
  const id = itemSequences.join('.');
16
+ const collapseId = parentSequences.length
17
+ ? parentId
18
+ : addedItem.sequenceLinkId;
19
+
20
+ const [rotate, setRotate] = useState(false);
21
+ const handleTableExpand = () => setRotate(!rotate);
22
+
23
+ const isExpandable =
24
+ parentSequences.length === 0 && addedItem.subItems.length !== 0;
13
25
 
14
26
  return (
15
27
  <>
16
- <TableRow>
17
- <TableCell data-testid="addedItems.sequence">{id}</TableCell>
18
- <TableCell data-testid="addedItems.service">
28
+ <TableRow
29
+ className={`${isCollapse ? `collapse item-${parentId}` : ''} ${
30
+ isExpandable ? 'fw-bold table-expandable-row border-top' : ''
31
+ }`}
32
+ data-bs-target={`.item-${collapseId}`}
33
+ data-bs-toggle={'collapse'}
34
+ aria-controls={id}
35
+ aria-expanded="false"
36
+ onClick={handleTableExpand}
37
+ >
38
+ <TableCell
39
+ data-testid="addedItems.sequence"
40
+ className="col-md-2"
41
+ isAlignTop
42
+ >
43
+ {id}
44
+ </TableCell>
45
+ <TableCell
46
+ data-testid="addedItems.service"
47
+ className="col-md-2"
48
+ isAlignTop
49
+ >
19
50
  {addedItem.service && <Coding fhirData={addedItem.service} />}
20
51
  </TableCell>
21
- <TableCell data-testid="addedItems.fee">
52
+ <TableCell data-testid="addedItems.fee" className="col-md-2" isAlignTop>
22
53
  {addedItem.fee && <Money fhirData={addedItem.fee} />}
23
54
  </TableCell>
24
- <TableCell data-testid="addedItems.adjudication">
55
+ <TableCell
56
+ data-testid="addedItems.adjudication"
57
+ className="col-md-2"
58
+ isAlignTop
59
+ >
25
60
  {addedItem.adjudication.map((adjudication, idx) => (
26
61
  <div
27
62
  key={idx}
@@ -36,13 +71,28 @@ const AddedItem = props => {
36
71
  </div>
37
72
  ))}
38
73
  </TableCell>
74
+ {isExpandable ? (
75
+ <TableCell className="col-md-2" isAlignTop>
76
+ <button
77
+ className="fhir-container__Accordion__header-button w-100 p-0 border-0 rounded-1 collapsed text-dark bg-transparent shadow-none "
78
+ type="button"
79
+ >
80
+ <div className={` ${rotate ? ' header-rotate' : ''}`}>
81
+ <Chevron strokeColor={rotate ? '#2a6fd7' : '#6f83a9'} />
82
+ </div>
83
+ </button>
84
+ </TableCell>
85
+ ) : (
86
+ <TableCell style={{ width: '64px' }} className="col-md-2" />
87
+ )}
39
88
  </TableRow>
40
89
  {addedItem.subItems.map((subItem, idx) => (
41
90
  <Item
42
91
  key={idx}
43
92
  addedItem={subItem}
44
- level={level + 1}
45
93
  parentSequences={itemSequences}
94
+ parentId={collapseId}
95
+ isCollapse
46
96
  />
47
97
  ))}
48
98
  </>
@@ -7,24 +7,20 @@ const AddedItems = props => {
7
7
  const { addedItems } = props;
8
8
 
9
9
  return (
10
- <ValueSection label="Added Items" data-testid="addedItems">
10
+ <ValueSection label="Added Items" data-testid="addedItems" marginTop>
11
11
  <Table>
12
12
  <thead>
13
13
  <TableRow>
14
14
  <TableHeader>ID</TableHeader>
15
15
  <TableHeader>Service</TableHeader>
16
16
  <TableHeader>Fee</TableHeader>
17
- <TableHeader expand>Adjudication</TableHeader>
17
+ <TableHeader>Adjudication</TableHeader>
18
+ <TableHeader></TableHeader>
18
19
  </TableRow>
19
20
  </thead>
20
- <tbody>
21
+ <tbody className="border-top-0">
21
22
  {addedItems.map((item, idx) => (
22
- <AddedItem
23
- key={idx}
24
- addedItem={item}
25
- level={0}
26
- parentSequences={[]}
27
- />
23
+ <AddedItem key={idx} addedItem={item} parentSequences={[]} />
28
24
  ))}
29
25
  </tbody>
30
26
  </Table>