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.
- package/.circleci/config.yml +1 -1
- package/.eslintrc +10 -1
- package/.stylelintrc +6 -2
- package/README.md +19 -1
- package/build/index.js +15 -11
- package/build/style.css +7 -7
- package/package.json +55 -54
- package/src/assets/containers/AdverseEvent/adverse-event.svg +6 -0
- package/src/assets/containers/Generic/generic.svg +3 -0
- package/src/assets/containers/MedicationDispense/medication-dispense.svg +5 -0
- package/src/assets/containers/PractitionerRole/practitioner-role.svg +5 -0
- package/src/assets/containers/ReferralRequest/referral-request.svg +8 -0
- package/src/assets/containers/RelatedPerson/related-person.svg +6 -0
- package/src/components/containers/Accordion/Accordion.js +21 -13
- package/src/components/datatypes/CodeableConcept/CodeableConcept.js +6 -3
- package/src/components/datatypes/Coding/Coding.js +7 -3
- package/src/components/datatypes/Reference/Reference.js +7 -5
- package/src/components/datatypes/Telecom/Telecom.js +2 -3
- package/src/components/resources/AdverseEvent/AdverseEvent.js +81 -42
- package/src/components/resources/AdverseEvent/AdverseEvent.stories.js +12 -2
- package/src/components/resources/AdverseEvent/AdverseEvent.test.js +109 -2
- package/src/components/resources/AllergyIntolerance/AllergyIntolerance.js +7 -1
- package/src/components/resources/AllergyIntolerance/AllergyIntolerance.test.js +36 -1
- package/src/components/resources/Appointment/Appointment.js +2 -1
- package/src/components/resources/Appointment/Appointment.test.js +36 -1
- package/src/components/resources/Bundle/Bundle.css +7 -0
- package/src/components/resources/Bundle/Bundle.js +15 -11
- package/src/components/resources/Bundle/Bundle.stories.js +12 -78
- package/src/components/resources/Bundle/Bundle.test.js +0 -3
- package/src/components/resources/CarePlan/CarePlan.js +2 -1
- package/src/components/resources/CarePlan/CarePlan.test.js +42 -6
- package/src/components/resources/CareTeam/CareTeam.js +72 -50
- package/src/components/resources/CareTeam/CareTeam.stories.js +20 -3
- package/src/components/resources/CareTeam/CareTeam.test.js +109 -1
- package/src/components/resources/CareTeam/CareTeamParticipants.js +1 -1
- package/src/components/resources/Claim/Claim.js +2 -1
- package/src/components/resources/Claim/Claim.test.js +32 -1
- package/src/components/resources/ClaimResponse/AddedItem.js +61 -11
- package/src/components/resources/ClaimResponse/AddedItems.js +5 -9
- package/src/components/resources/ClaimResponse/ClaimResponse.js +137 -83
- package/src/components/resources/ClaimResponse/ClaimResponse.stories.js +15 -2
- package/src/components/resources/ClaimResponse/ClaimResponse.test.js +112 -1
- package/src/components/resources/ClaimResponse/Item.js +44 -9
- package/src/components/resources/ClaimResponse/Items.js +5 -4
- package/src/components/resources/Condition/Condition.js +3 -3
- package/src/components/resources/Condition/Condition.test.js +37 -4
- package/src/components/resources/Coverage/Coverage.js +2 -1
- package/src/components/resources/Coverage/Coverage.test.js +36 -1
- package/src/components/resources/Device/Device.js +2 -1
- package/src/components/resources/Device/Device.test.js +36 -1
- package/src/components/resources/DiagnosticReport/DiagnosticReport.js +7 -2
- package/src/components/resources/DiagnosticReport/DiagnosticReport.test.js +36 -1
- package/src/components/resources/DocumentReference/DocumentReference.js +7 -2
- package/src/components/resources/DocumentReference/DocumentReference.test.js +42 -1
- package/src/components/resources/Encounter/Encounter.js +2 -1
- package/src/components/resources/Encounter/Encounter.test.js +36 -1
- package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.js +2 -0
- package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.test.js +38 -1
- package/src/components/resources/FamilyMemberHistory/FamilyMemberHistory.js +7 -2
- package/src/components/resources/FamilyMemberHistory/FamilyMemberHistory.test.js +36 -1
- package/src/components/resources/Generic/Generic.js +20 -7
- package/src/components/resources/Generic/Generic.stories.js +2 -1
- package/src/components/resources/Generic/Generic.test.js +26 -7
- package/src/components/resources/Goal/Goal.js +2 -3
- package/src/components/resources/Goal/Goal.test.js +32 -1
- package/src/components/resources/Immunization/Immunization.js +2 -2
- package/src/components/resources/Immunization/Immunization.test.js +36 -1
- package/src/components/resources/List/DrugTierDefinitionExtension.js +79 -35
- package/src/components/resources/List/Entries.js +3 -3
- package/src/components/resources/List/List.js +135 -88
- package/src/components/resources/List/List.stories.js +38 -5
- package/src/components/resources/List/List.test.js +105 -1
- package/src/components/resources/Location/Location.js +65 -47
- package/src/components/resources/Location/Location.stories.js +11 -4
- package/src/components/resources/Location/Location.test.js +106 -4
- package/src/components/resources/Medication/Medication.js +2 -1
- package/src/components/resources/Medication/Medication.test.js +36 -1
- package/src/components/resources/MedicationAdministration/MedicationAdministration.js +86 -62
- package/src/components/resources/MedicationAdministration/MedicationAdministration.stories.js +7 -0
- package/src/components/resources/MedicationAdministration/MedicationAdministration.test.js +117 -1
- package/src/components/resources/MedicationDispense/DosageInstruction.js +25 -0
- package/src/components/resources/MedicationDispense/MedicationDispense.js +68 -68
- package/src/components/resources/MedicationDispense/MedicationDispense.stories.js +7 -0
- package/src/components/resources/MedicationDispense/MedicationDispense.test.js +108 -1
- package/src/components/resources/MedicationKnowledge/MedicationKnowledge.js +115 -66
- package/src/components/resources/MedicationKnowledge/MedicationKnowledge.stories.js +6 -0
- package/src/components/resources/MedicationKnowledge/MedicationKnowledge.test.js +110 -1
- package/src/components/resources/MedicationOrder/MedicationOrder.js +2 -3
- package/src/components/resources/MedicationOrder/MedicationOrder.test.js +35 -4
- package/src/components/resources/MedicationRequest/MedicationRequest.js +2 -1
- package/src/components/resources/MedicationRequest/MedicationRequest.test.js +33 -4
- package/src/components/resources/MedicationStatement/MedicationStatement.js +7 -2
- package/src/components/resources/MedicationStatement/MedicationStatement.test.js +36 -1
- package/src/components/resources/Observation/Observation.js +2 -1
- package/src/components/resources/Observation/Observation.test.js +30 -1
- package/src/components/resources/Organization/Organization.js +3 -2
- package/src/components/resources/Organization/Organization.test.js +36 -1
- package/src/components/resources/Patient/Patient.js +2 -0
- package/src/components/resources/Patient/Patient.test.js +31 -2
- package/src/components/resources/Practitioner/Practitioner.js +2 -1
- package/src/components/resources/Practitioner/Practitioner.test.js +36 -1
- package/src/components/resources/PractitionerRole/PractitionerRole.js +50 -29
- package/src/components/resources/PractitionerRole/PractitionerRole.stories.js +7 -0
- package/src/components/resources/PractitionerRole/PractitionerRole.test.js +108 -1
- package/src/components/resources/Procedure/Procedure.js +2 -2
- package/src/components/resources/Procedure/Procedure.test.js +30 -1
- package/src/components/resources/Questionnaire/Group.js +53 -0
- package/src/components/resources/Questionnaire/Items.js +45 -0
- package/src/components/resources/Questionnaire/Questionnaire.css +24 -5
- package/src/components/resources/Questionnaire/Questionnaire.js +31 -170
- package/src/components/resources/Questionnaire/Questionnaire.stories.js +8 -0
- package/src/components/resources/Questionnaire/Questionnaire.test.js +194 -15
- package/src/components/resources/Questionnaire/Questions.js +40 -0
- package/src/components/resources/Questionnaire/getQuestionText.js +20 -0
- package/src/components/resources/QuestionnaireResponse/Answers.js +59 -0
- package/src/components/resources/QuestionnaireResponse/Group.js +70 -0
- package/src/components/resources/QuestionnaireResponse/Items.js +45 -0
- package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.css +33 -8
- package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.js +52 -236
- package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.stories.js +8 -0
- package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.test.js +38 -3
- package/src/components/resources/QuestionnaireResponse/Questions.js +43 -0
- package/src/components/resources/QuestionnaireResponse/getQuestionText.js +22 -0
- package/src/components/resources/ReferralRequest/ReferralRequest.js +65 -40
- package/src/components/resources/ReferralRequest/ReferralRequest.test.js +111 -11
- package/src/components/resources/RelatedPerson/RelatedPerson.js +151 -0
- package/src/components/resources/RelatedPerson/RelatedPerson.stories.js +46 -0
- package/src/components/resources/RelatedPerson/RelatedPerson.test.js +156 -0
- package/src/components/resources/RelatedPerson/index.js +3 -0
- package/src/components/resources/ResearchStudy/ResearchStudy.js +160 -130
- package/src/components/resources/ResearchStudy/ResearchStudy.stories.js +2 -0
- package/src/components/resources/ResearchStudy/ResearchStudy.test.js +108 -1
- package/src/components/ui/index.js +22 -9
- package/src/fixtures/dstu2/resources/relatedPerson/example1.json +79 -0
- package/src/fixtures/example-icons.jsx +42 -0
- package/src/fixtures/r4/resources/relatedPerson/example1.json +64 -0
- package/src/fixtures/stu3/resources/relatedPerson/example1.json +43 -0
- package/src/style.scss +3 -1
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { fireEvent, render } from '@testing-library/react';
|
|
3
|
+
import RelatedPerson from './RelatedPerson';
|
|
4
|
+
import fhirVersions from '../fhirResourceVersions';
|
|
5
|
+
|
|
6
|
+
import example1 from '../../../fixtures/dstu2/resources/relatedPerson/example1.json';
|
|
7
|
+
import example2 from '../../../fixtures/stu3/resources/relatedPerson/example1.json';
|
|
8
|
+
import example3 from '../../../fixtures/r4/resources/relatedPerson/example1.json';
|
|
9
|
+
import fhirIcons from '../../../fixtures/example-icons';
|
|
10
|
+
|
|
11
|
+
describe('should render component correctly', () => {
|
|
12
|
+
it('component without a fhirIcons props should render a default icon', () => {
|
|
13
|
+
const defaultProps = {
|
|
14
|
+
fhirResource: example1,
|
|
15
|
+
fhirVersion: fhirVersions.DSTU2,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const { getByAltText } = render(<RelatedPerson {...defaultProps} />);
|
|
19
|
+
const headerIcon = getByAltText('related person');
|
|
20
|
+
|
|
21
|
+
expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('component with a false as a fhirIcons props should render a placeholder', () => {
|
|
25
|
+
const defaultProps = {
|
|
26
|
+
fhirResource: example1,
|
|
27
|
+
fhirVersion: fhirVersions.DSTU2,
|
|
28
|
+
fhirIcons: false,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const { getByTestId } = render(<RelatedPerson {...defaultProps} />);
|
|
32
|
+
const headerIcon = getByTestId('placeholder');
|
|
33
|
+
|
|
34
|
+
expect(headerIcon).toBeTruthy();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('component with the img as a fhirIcons props should render an img', () => {
|
|
38
|
+
const defaultProps = {
|
|
39
|
+
fhirResource: example1,
|
|
40
|
+
fhirVersion: fhirVersions.DSTU2,
|
|
41
|
+
fhirIcons: (
|
|
42
|
+
<img
|
|
43
|
+
src={require('../assets/containers/RelatedPerson/related-person.svg')}
|
|
44
|
+
alt="related person"
|
|
45
|
+
/>
|
|
46
|
+
),
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const { getByAltText } = render(<RelatedPerson {...defaultProps} />);
|
|
50
|
+
const headerIcon = getByAltText('related person');
|
|
51
|
+
|
|
52
|
+
expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('component with the resources object as a fhirIcons props should render an img', () => {
|
|
56
|
+
const defaultProps = {
|
|
57
|
+
fhirResource: example1,
|
|
58
|
+
fhirVersion: fhirVersions.DSTU2,
|
|
59
|
+
fhirIcons: fhirIcons,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const { getByAltText } = render(<RelatedPerson {...defaultProps} />);
|
|
63
|
+
const headerIcon = getByAltText('related person');
|
|
64
|
+
|
|
65
|
+
expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('component with the url as a fhirIcons props should render an img', () => {
|
|
69
|
+
const avatarSrc =
|
|
70
|
+
'https://www.gravatar.com/avatar/?s=50&r=any&default=identicon&forcedefault=1';
|
|
71
|
+
const defaultProps = {
|
|
72
|
+
fhirResource: example1,
|
|
73
|
+
fhirVersion: fhirVersions.DSTU2,
|
|
74
|
+
fhirIcons: avatarSrc,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const { getByAltText } = render(<RelatedPerson {...defaultProps} />);
|
|
78
|
+
const headerIcon = getByAltText('header icon');
|
|
79
|
+
|
|
80
|
+
expect(headerIcon.getAttribute('src')).toContain(avatarSrc);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should render with DSTU2 source data', () => {
|
|
84
|
+
const defaultProps = {
|
|
85
|
+
fhirResource: example1,
|
|
86
|
+
fhirVersion: fhirVersions.DSTU2,
|
|
87
|
+
};
|
|
88
|
+
const { getByTestId } = render(<RelatedPerson {...defaultProps} />);
|
|
89
|
+
|
|
90
|
+
expect(getByTestId('gender').textContent).toEqual('female');
|
|
91
|
+
expect(getByTestId('address').textContent).toEqual(
|
|
92
|
+
'43, Place du Marché Sainte CatherineParis, 75004 FRA',
|
|
93
|
+
);
|
|
94
|
+
expect(getByTestId('telephone').textContent).toEqual('+33 (237) 998327');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should render with STU3 source data', () => {
|
|
98
|
+
const defaultProps = {
|
|
99
|
+
fhirResource: example2,
|
|
100
|
+
fhirVersion: fhirVersions.STU3,
|
|
101
|
+
};
|
|
102
|
+
const { getByTestId } = render(<RelatedPerson {...defaultProps} />);
|
|
103
|
+
|
|
104
|
+
expect(getByTestId('gender').textContent).toEqual('female');
|
|
105
|
+
expect(getByTestId('birthDate').textContent).toEqual('1963');
|
|
106
|
+
expect(getByTestId('telephone').textContent).toEqual('+31201234567');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should render with R4 source data', () => {
|
|
110
|
+
const defaultProps = {
|
|
111
|
+
fhirResource: example3,
|
|
112
|
+
fhirVersion: fhirVersions.R4,
|
|
113
|
+
};
|
|
114
|
+
const { getByTestId } = render(<RelatedPerson {...defaultProps} />);
|
|
115
|
+
|
|
116
|
+
expect(getByTestId('gender').textContent).toEqual('female');
|
|
117
|
+
expect(getByTestId('birthDate').textContent).toEqual('1973-05-31');
|
|
118
|
+
expect(getByTestId('address').textContent).toEqual('2222 Home Street ');
|
|
119
|
+
expect(getByTestId('telephone').textContent).toEqual('555-555-2003');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should fire custom onClick function', () => {
|
|
123
|
+
const defaultProps = {
|
|
124
|
+
fhirResource: example3,
|
|
125
|
+
fhirVersion: fhirVersions.R4,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const onClick = jest.fn();
|
|
129
|
+
const { getByRole } = render(
|
|
130
|
+
<RelatedPerson {...defaultProps} onClick={onClick} />,
|
|
131
|
+
);
|
|
132
|
+
const accordion = getByRole('button');
|
|
133
|
+
fireEvent.click(accordion);
|
|
134
|
+
|
|
135
|
+
const attribute = accordion.getAttribute('data-bs-toggle');
|
|
136
|
+
expect(attribute).not.toEqual('collapse');
|
|
137
|
+
expect(onClick).toHaveBeenCalled();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should not fire custom onClick function', () => {
|
|
141
|
+
const defaultProps = {
|
|
142
|
+
fhirResource: example3,
|
|
143
|
+
fhirVersion: fhirVersions.R4,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const onClick = 'test';
|
|
147
|
+
const { getByRole } = render(
|
|
148
|
+
<RelatedPerson {...defaultProps} onClick={onClick} />,
|
|
149
|
+
);
|
|
150
|
+
const accordion = getByRole('button');
|
|
151
|
+
fireEvent.click(accordion);
|
|
152
|
+
|
|
153
|
+
const attribute = accordion.getAttribute('data-bs-toggle');
|
|
154
|
+
expect(attribute).toEqual('collapse');
|
|
155
|
+
});
|
|
156
|
+
});
|
|
@@ -13,16 +13,8 @@ import _get from 'lodash/get';
|
|
|
13
13
|
import UnhandledResourceDataStructure from '../UnhandledResourceDataStructure';
|
|
14
14
|
import fhirVersions from '../fhirResourceVersions';
|
|
15
15
|
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
BadgeSecondary,
|
|
19
|
-
Body,
|
|
20
|
-
Header,
|
|
21
|
-
MissingValue,
|
|
22
|
-
Root,
|
|
23
|
-
Title,
|
|
24
|
-
Value,
|
|
25
|
-
} from '../../ui';
|
|
16
|
+
import { Badge, Body, Header, MissingValue, Root, Value } from '../../ui';
|
|
17
|
+
import Accordion from '../../containers/Accordion';
|
|
26
18
|
|
|
27
19
|
const commonDTO = fhirResource => {
|
|
28
20
|
const title = _get(fhirResource, 'title', 'Research Study');
|
|
@@ -102,8 +94,7 @@ const resourceDTO = (fhirVersion, fhirResource) => {
|
|
|
102
94
|
}
|
|
103
95
|
};
|
|
104
96
|
|
|
105
|
-
const ResearchStudy =
|
|
106
|
-
const { fhirResource, fhirVersion } = props;
|
|
97
|
+
const ResearchStudy = ({ fhirResource, fhirVersion, fhirIcons, onClick }) => {
|
|
107
98
|
let fhirResourceData = {};
|
|
108
99
|
try {
|
|
109
100
|
fhirResourceData = resourceDTO(fhirVersion, fhirResource);
|
|
@@ -140,126 +131,165 @@ const ResearchStudy = props => {
|
|
|
140
131
|
const hasComments = comments.length > 0;
|
|
141
132
|
const hasArms = arms.length > 0;
|
|
142
133
|
|
|
134
|
+
const tableData = [
|
|
135
|
+
{
|
|
136
|
+
label: 'Part of another study',
|
|
137
|
+
testId: 'partOf',
|
|
138
|
+
data: partOfReference && <Reference fhirData={partOfReference} />,
|
|
139
|
+
status: partOfReference,
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
label: 'Category',
|
|
143
|
+
testId: 'category',
|
|
144
|
+
data: categoryCoding && <Coding fhirData={categoryCoding} />,
|
|
145
|
+
status: categoryCoding,
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
label: 'Keywords',
|
|
149
|
+
testId: 'keywords',
|
|
150
|
+
data: hasKeywords && <CodeableConcept fhirData={keywordConcepts} />,
|
|
151
|
+
status: hasKeywords,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
label: 'Description',
|
|
155
|
+
testId: 'description',
|
|
156
|
+
data: description && <Markdown fhirData={description} />,
|
|
157
|
+
status: description,
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
label: 'Focus',
|
|
161
|
+
testId: 'focus',
|
|
162
|
+
data: focusCoding && <Coding fhirData={focusCoding} />,
|
|
163
|
+
status: focusCoding,
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
label: 'Enrollment',
|
|
167
|
+
testId: 'enrollment',
|
|
168
|
+
data:
|
|
169
|
+
hasEnrollment &&
|
|
170
|
+
enrollmentReferences.map((enrollmentReference, idx) => (
|
|
171
|
+
<div key={idx} data-testid="enrollmentReference">
|
|
172
|
+
<Reference fhirData={enrollmentReference} />
|
|
173
|
+
</div>
|
|
174
|
+
)),
|
|
175
|
+
status: hasEnrollment,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
label: 'Protocol',
|
|
179
|
+
testId: 'protocol',
|
|
180
|
+
data: protocolReference && <Reference fhirData={protocolReference} />,
|
|
181
|
+
status: protocolReference,
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
label: 'Study paths',
|
|
185
|
+
testId: 'arms',
|
|
186
|
+
data: hasArms && (
|
|
187
|
+
<ul>
|
|
188
|
+
{arms.map((arm, idx) => (
|
|
189
|
+
<li key={idx}>
|
|
190
|
+
<div data-testid="arms.name">{arm.name}</div>
|
|
191
|
+
<Coding fhirData={arm.coding} />
|
|
192
|
+
<div data-testid="arms.description">{arm.description}</div>
|
|
193
|
+
</li>
|
|
194
|
+
))}
|
|
195
|
+
</ul>
|
|
196
|
+
),
|
|
197
|
+
status: hasArms,
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
label: 'Comments',
|
|
201
|
+
testId: 'comments',
|
|
202
|
+
data: hasComments && <Annotation fhirData={comments} />,
|
|
203
|
+
status: hasComments,
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
label: 'Contacts',
|
|
207
|
+
testId: 'contacts',
|
|
208
|
+
data:
|
|
209
|
+
hasContacts &&
|
|
210
|
+
contacts.map((contact, idx) => (
|
|
211
|
+
<div key={idx}>
|
|
212
|
+
<div data-testid="contactsName">{contact.name}</div>
|
|
213
|
+
<div data-testid="contactsTelecom">
|
|
214
|
+
<Telecom fhirData={contact.telecoms} />
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
)),
|
|
218
|
+
status: hasContacts,
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
label: 'Principal investigator',
|
|
222
|
+
testId: 'principalInvestigator',
|
|
223
|
+
data: principalInvestigatorReference && (
|
|
224
|
+
<Reference fhirData={principalInvestigatorReference} />
|
|
225
|
+
),
|
|
226
|
+
status: principalInvestigatorReference,
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
label: 'Sponsor',
|
|
230
|
+
testId: 'sponsor',
|
|
231
|
+
data: sponsorReference && <Reference fhirData={sponsorReference} />,
|
|
232
|
+
status: sponsorReference,
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
label: 'Sites',
|
|
236
|
+
testId: 'sites',
|
|
237
|
+
data:
|
|
238
|
+
hasSites &&
|
|
239
|
+
siteReferences.map((siteReference, idx) => (
|
|
240
|
+
<div key={idx} data-testid="siteReference">
|
|
241
|
+
<Reference fhirData={siteReference} />
|
|
242
|
+
</div>
|
|
243
|
+
)),
|
|
244
|
+
status: hasSites,
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
label: 'Location',
|
|
248
|
+
testId: 'location',
|
|
249
|
+
data: location && <CodeableConcept fhirData={location} />,
|
|
250
|
+
status: location,
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
label: 'Primary Purpose Type',
|
|
254
|
+
testId: 'primaryPurposeType',
|
|
255
|
+
data: primaryPurposeType && (
|
|
256
|
+
<CodeableConcept fhirData={primaryPurposeType} />
|
|
257
|
+
),
|
|
258
|
+
status: primaryPurposeType,
|
|
259
|
+
},
|
|
260
|
+
];
|
|
261
|
+
|
|
143
262
|
return (
|
|
144
263
|
<Root name="ResearchStudy">
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
{
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
{
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
</Value>
|
|
175
|
-
)}
|
|
176
|
-
{description && (
|
|
177
|
-
<Value label="Description" data-testid="description">
|
|
178
|
-
<Markdown fhirData={description} />
|
|
179
|
-
</Value>
|
|
180
|
-
)}
|
|
181
|
-
{focusCoding && (
|
|
182
|
-
<Value label="Focus" data-testid="focus">
|
|
183
|
-
<Coding fhirData={focusCoding} />
|
|
184
|
-
</Value>
|
|
185
|
-
)}
|
|
186
|
-
{hasEnrollment && (
|
|
187
|
-
<Value label="Enrollment" data-testid="enrollment">
|
|
188
|
-
{enrollmentReferences.map((enrollmentReference, idx) => (
|
|
189
|
-
<div key={idx} data-testid="enrollmentReference">
|
|
190
|
-
<Reference fhirData={enrollmentReference} />
|
|
191
|
-
</div>
|
|
192
|
-
))}
|
|
193
|
-
</Value>
|
|
194
|
-
)}
|
|
195
|
-
{protocolReference && (
|
|
196
|
-
<Value label="Protocol" data-testid="protocol">
|
|
197
|
-
<Reference fhirData={protocolReference} />
|
|
198
|
-
</Value>
|
|
199
|
-
)}
|
|
200
|
-
{hasArms && (
|
|
201
|
-
<Value label="Study paths" data-testid="arms">
|
|
202
|
-
<ul>
|
|
203
|
-
{arms.map((arm, idx) => (
|
|
204
|
-
<li key={idx}>
|
|
205
|
-
<div data-testid="arms.name">{arm.name}</div>
|
|
206
|
-
<Coding fhirData={arm.coding} />
|
|
207
|
-
<div data-testid="arms.description">{arm.description}</div>
|
|
208
|
-
</li>
|
|
209
|
-
))}
|
|
210
|
-
</ul>
|
|
211
|
-
</Value>
|
|
212
|
-
)}
|
|
213
|
-
{hasComments && (
|
|
214
|
-
<Value label="Comments" data-testid="comments">
|
|
215
|
-
<Annotation fhirData={comments} />
|
|
216
|
-
</Value>
|
|
217
|
-
)}
|
|
218
|
-
{hasContacts && (
|
|
219
|
-
<Value label="Contacts" data-testid="contacts">
|
|
220
|
-
{contacts.map((contact, idx) => (
|
|
221
|
-
<div key={idx}>
|
|
222
|
-
<div data-testid="contactsName">{contact.name}</div>
|
|
223
|
-
<div data-testid="contactsTelecom">
|
|
224
|
-
<Telecom fhirData={contact.telecoms} />
|
|
225
|
-
</div>
|
|
226
|
-
</div>
|
|
227
|
-
))}
|
|
228
|
-
</Value>
|
|
229
|
-
)}
|
|
230
|
-
{principalInvestigatorReference && (
|
|
231
|
-
<Value
|
|
232
|
-
label="Principal investigator"
|
|
233
|
-
data-testid="principalInvestigator"
|
|
234
|
-
>
|
|
235
|
-
<Reference fhirData={principalInvestigatorReference} />
|
|
236
|
-
</Value>
|
|
237
|
-
)}
|
|
238
|
-
{sponsorReference && (
|
|
239
|
-
<Value label="Sponsor" data-testid="sponsor">
|
|
240
|
-
<Reference fhirData={sponsorReference} />
|
|
241
|
-
</Value>
|
|
242
|
-
)}
|
|
243
|
-
{hasSites && (
|
|
244
|
-
<Value label="Sites" data-testid="sites">
|
|
245
|
-
{siteReferences.map((siteReference, idx) => (
|
|
246
|
-
<div key={idx} data-testid="siteReference">
|
|
247
|
-
<Reference fhirData={siteReference} />
|
|
248
|
-
</div>
|
|
249
|
-
))}
|
|
250
|
-
</Value>
|
|
251
|
-
)}
|
|
252
|
-
{location && (
|
|
253
|
-
<Value label="Location" data-testid="location">
|
|
254
|
-
<CodeableConcept fhirData={location} />
|
|
255
|
-
</Value>
|
|
256
|
-
)}
|
|
257
|
-
{primaryPurposeType && (
|
|
258
|
-
<Value label="Primary Purpose Type" data-testid="primaryPurposeType">
|
|
259
|
-
<CodeableConcept fhirData={primaryPurposeType} />
|
|
260
|
-
</Value>
|
|
261
|
-
)}
|
|
262
|
-
</Body>
|
|
264
|
+
<Accordion
|
|
265
|
+
headerContent={
|
|
266
|
+
<Header
|
|
267
|
+
resourceName="ResearchStudy"
|
|
268
|
+
title={title}
|
|
269
|
+
badges={status && <Badge data-testid="status">{status}</Badge>}
|
|
270
|
+
additionalContent={
|
|
271
|
+
hasPeriod && (
|
|
272
|
+
<Value data-testid="period">
|
|
273
|
+
{period.start ? (
|
|
274
|
+
<DateType fhirData={period.start} isBlack />
|
|
275
|
+
) : (
|
|
276
|
+
<MissingValue />
|
|
277
|
+
)}
|
|
278
|
+
{' - '}
|
|
279
|
+
{period.end ? (
|
|
280
|
+
<DateType fhirData={period.end} isBlack />
|
|
281
|
+
) : (
|
|
282
|
+
<MissingValue />
|
|
283
|
+
)}
|
|
284
|
+
</Value>
|
|
285
|
+
)
|
|
286
|
+
}
|
|
287
|
+
icon={fhirIcons}
|
|
288
|
+
/>
|
|
289
|
+
}
|
|
290
|
+
bodyContent={<Body tableData={tableData} />}
|
|
291
|
+
onClick={onClick}
|
|
292
|
+
/>
|
|
263
293
|
</Root>
|
|
264
294
|
);
|
|
265
295
|
};
|
|
@@ -6,6 +6,7 @@ import fhirVersions from '../fhirResourceVersions';
|
|
|
6
6
|
|
|
7
7
|
import stu3Example1 from '../../../fixtures/stu3/resources/researchStudy/example-1.json';
|
|
8
8
|
import r4Example1 from '../../../fixtures/r4/resources/researchStudy/example1.json';
|
|
9
|
+
import fhirIcons from '../../../fixtures/example-icons';
|
|
9
10
|
|
|
10
11
|
export default {
|
|
11
12
|
title: 'ResearchStudy',
|
|
@@ -17,6 +18,7 @@ export const ExampleOfSTU3 = () => {
|
|
|
17
18
|
<ResearchStudy
|
|
18
19
|
fhirVersion={fhirVersions.STU3}
|
|
19
20
|
fhirResource={fhirResource}
|
|
21
|
+
fhirIcons={fhirIcons}
|
|
20
22
|
/>
|
|
21
23
|
);
|
|
22
24
|
};
|
|
@@ -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 ResearchStudy from './ResearchStudy';
|
|
5
5
|
import fhirVersions from '../fhirResourceVersions';
|
|
@@ -7,8 +7,80 @@ import stu3Example1 from '../../../fixtures/stu3/resources/researchStudy/example
|
|
|
7
7
|
import r4Example1 from '../../../fixtures/r4/resources/researchStudy/example1.json';
|
|
8
8
|
|
|
9
9
|
import { nbspRegex } from '../../../testUtils';
|
|
10
|
+
import fhirIcons from '../../../fixtures/example-icons';
|
|
10
11
|
|
|
11
12
|
describe('should render ResearchStudy component properly', () => {
|
|
13
|
+
it('component without a fhirIcons props should render a default icon', () => {
|
|
14
|
+
const defaultProps = {
|
|
15
|
+
fhirVersion: fhirVersions.STU3,
|
|
16
|
+
fhirResource: stu3Example1,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const { getByAltText } = render(<ResearchStudy {...defaultProps} />);
|
|
20
|
+
const headerIcon = getByAltText('research study');
|
|
21
|
+
|
|
22
|
+
expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('component with a false as a fhirIcons props should render a placeholder', () => {
|
|
26
|
+
const defaultProps = {
|
|
27
|
+
fhirVersion: fhirVersions.STU3,
|
|
28
|
+
fhirResource: stu3Example1,
|
|
29
|
+
fhirIcons: false,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const { getByTestId } = render(<ResearchStudy {...defaultProps} />);
|
|
33
|
+
const headerIcon = getByTestId('placeholder');
|
|
34
|
+
|
|
35
|
+
expect(headerIcon).toBeTruthy();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('component with the img as a fhirIcons props should render an img', () => {
|
|
39
|
+
const defaultProps = {
|
|
40
|
+
fhirVersion: fhirVersions.STU3,
|
|
41
|
+
fhirResource: stu3Example1,
|
|
42
|
+
fhirIcons: (
|
|
43
|
+
<img
|
|
44
|
+
src={require('../assets/containers/ResearchStudy/research-study.svg')}
|
|
45
|
+
alt="finger pointing something in a book"
|
|
46
|
+
/>
|
|
47
|
+
),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const { getByAltText } = render(<ResearchStudy {...defaultProps} />);
|
|
51
|
+
const headerIcon = getByAltText('finger pointing something in a book');
|
|
52
|
+
|
|
53
|
+
expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('component with the resources object as a fhirIcons props should render an img', () => {
|
|
57
|
+
const defaultProps = {
|
|
58
|
+
fhirVersion: fhirVersions.STU3,
|
|
59
|
+
fhirResource: stu3Example1,
|
|
60
|
+
fhirIcons: fhirIcons,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const { getByAltText } = render(<ResearchStudy {...defaultProps} />);
|
|
64
|
+
const headerIcon = getByAltText('finger pointing something in a book');
|
|
65
|
+
|
|
66
|
+
expect(headerIcon.getAttribute('src')).toContain('IMAGE_MOCK');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('component with the url as a fhirIcons props should render an img', () => {
|
|
70
|
+
const avatarSrc =
|
|
71
|
+
'https://www.gravatar.com/avatar/?s=50&r=any&default=identicon&forcedefault=1';
|
|
72
|
+
const defaultProps = {
|
|
73
|
+
fhirVersion: fhirVersions.STU3,
|
|
74
|
+
fhirResource: stu3Example1,
|
|
75
|
+
fhirIcons: avatarSrc,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const { getByAltText } = render(<ResearchStudy {...defaultProps} />);
|
|
79
|
+
const headerIcon = getByAltText('header icon');
|
|
80
|
+
|
|
81
|
+
expect(headerIcon.getAttribute('src')).toContain(avatarSrc);
|
|
82
|
+
});
|
|
83
|
+
|
|
12
84
|
it('with STU3 source data', () => {
|
|
13
85
|
const defaultProps = {
|
|
14
86
|
fhirResource: stu3Example1,
|
|
@@ -82,4 +154,39 @@ describe('should render ResearchStudy component properly', () => {
|
|
|
82
154
|
const status = getByTestId('status').textContent;
|
|
83
155
|
expect(status).toEqual('completed');
|
|
84
156
|
});
|
|
157
|
+
|
|
158
|
+
it('should fire custom onClick function', () => {
|
|
159
|
+
const defaultProps = {
|
|
160
|
+
fhirResource: stu3Example1,
|
|
161
|
+
fhirVersion: fhirVersions.STU3,
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const onClick = jest.fn();
|
|
165
|
+
const { getByRole } = render(
|
|
166
|
+
<ResearchStudy {...defaultProps} onClick={onClick} />,
|
|
167
|
+
);
|
|
168
|
+
const accordion = getByRole('button');
|
|
169
|
+
fireEvent.click(accordion);
|
|
170
|
+
|
|
171
|
+
const attribute = accordion.getAttribute('data-bs-toggle');
|
|
172
|
+
expect(attribute).not.toEqual('collapse');
|
|
173
|
+
expect(onClick).toHaveBeenCalled();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('should not fire custom onClick function', () => {
|
|
177
|
+
const defaultProps = {
|
|
178
|
+
fhirResource: stu3Example1,
|
|
179
|
+
fhirVersion: fhirVersions.STU3,
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const onClick = 'test';
|
|
183
|
+
const { getByRole } = render(
|
|
184
|
+
<ResearchStudy {...defaultProps} onClick={onClick} />,
|
|
185
|
+
);
|
|
186
|
+
const accordion = getByRole('button');
|
|
187
|
+
fireEvent.click(accordion);
|
|
188
|
+
|
|
189
|
+
const attribute = accordion.getAttribute('data-bs-toggle');
|
|
190
|
+
expect(attribute).toEqual('collapse');
|
|
191
|
+
});
|
|
85
192
|
});
|
|
@@ -15,6 +15,8 @@ export const Header = ({
|
|
|
15
15
|
additionalContent,
|
|
16
16
|
rightAdditionalContent,
|
|
17
17
|
children,
|
|
18
|
+
capitalize = false,
|
|
19
|
+
isNoIcon = false,
|
|
18
20
|
}) => {
|
|
19
21
|
const rightItemsClass = 'align-items-center flex-fill d-flex';
|
|
20
22
|
|
|
@@ -31,15 +33,20 @@ export const Header = ({
|
|
|
31
33
|
} d-flex w-100 flex-column flex-sm-row`}
|
|
32
34
|
>
|
|
33
35
|
<div className="d-flex">
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
{!isNoIcon && (
|
|
37
|
+
<div
|
|
38
|
+
className={`fhir-ui__${resourceName}-Header__icon d-flex align-items-center flex-shrink-1 m-half me-2`}
|
|
39
|
+
>
|
|
40
|
+
<HeaderIcon headerIcon={icon} resourceName={resourceName} />
|
|
41
|
+
</div>
|
|
42
|
+
)}
|
|
39
43
|
<div
|
|
40
44
|
className={`fhir-ui__${resourceName}-Header__title flex-fill text-start`}
|
|
41
45
|
>
|
|
42
|
-
<Title
|
|
46
|
+
<Title
|
|
47
|
+
data-testid={titleTestID || 'title'}
|
|
48
|
+
capitalize={capitalize}
|
|
49
|
+
>
|
|
43
50
|
{title || ''}
|
|
44
51
|
</Title>
|
|
45
52
|
</div>
|
|
@@ -77,7 +84,9 @@ export const Header = ({
|
|
|
77
84
|
|
|
78
85
|
export const Title = props => (
|
|
79
86
|
<h4
|
|
80
|
-
className=
|
|
87
|
+
className={`fhir-ui__Title fw-bold fs-4 lh-base mb-0 w-90 title-width-sm ${
|
|
88
|
+
props.capitalize ? 'text-capitalize' : ''
|
|
89
|
+
}`}
|
|
81
90
|
data-testid={props['data-testid'] || 'title'}
|
|
82
91
|
>
|
|
83
92
|
{props.children}
|
|
@@ -175,7 +184,9 @@ export const Data = props => (
|
|
|
175
184
|
);
|
|
176
185
|
|
|
177
186
|
export const Root = props => (
|
|
178
|
-
<div className={`fhir-resource__${props.name}
|
|
187
|
+
<div className={`fhir-resource__${props.name} ${props.className}`}>
|
|
188
|
+
{props.children}
|
|
189
|
+
</div>
|
|
179
190
|
);
|
|
180
191
|
|
|
181
192
|
export const Table = props => (
|
|
@@ -206,7 +217,9 @@ export const TableRow = props => {
|
|
|
206
217
|
|
|
207
218
|
export const TableCell = props => (
|
|
208
219
|
<td
|
|
209
|
-
className={
|
|
220
|
+
className={`${
|
|
221
|
+
props.isAlignTop ? '' : 'align-middle'
|
|
222
|
+
} border-0 ${props.className || ''}`}
|
|
210
223
|
data-testid={props['data-testid']}
|
|
211
224
|
style={props.style}
|
|
212
225
|
>
|