fhir-react 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/.github/workflows/publish_npmjs.yml +18 -0
  2. package/.storybook/config.js +9 -3
  3. package/.storybook/presets.js +1 -0
  4. package/.storybook/preview-head.html +4 -0
  5. package/README.md +86 -55
  6. package/package.json +13 -4
  7. package/src/assets/common/chevron-right.svg +3 -0
  8. package/src/assets/containers/AllergyIntolerance/allergy-intolerance.svg +9 -0
  9. package/src/assets/containers/Appointment/appointment.svg +14 -0
  10. package/src/assets/containers/CarePlan/care-plan.svg +10 -0
  11. package/src/assets/containers/CareTeam/care-team.svg +10 -0
  12. package/src/assets/containers/Claim/claim.svg +6 -0
  13. package/src/assets/containers/ClaimResponse/claim-response.svg +7 -0
  14. package/src/assets/containers/Condition/condition.svg +11 -0
  15. package/src/assets/containers/Device/device.svg +8 -0
  16. package/src/assets/containers/DiagnosticReport/diagnostic-report.svg +14 -0
  17. package/src/assets/containers/DocumentReference/document-reference.svg +10 -0
  18. package/src/assets/containers/Encounter/encounter.svg +10 -0
  19. package/src/assets/containers/ExplanationOfBenefit/explanation-of-benefit.svg +3 -0
  20. package/src/assets/containers/FamilyMemberHistory/family-member-history.svg +7 -0
  21. package/src/assets/containers/Goal/goal.svg +11 -0
  22. package/src/assets/containers/Immunization/immunization.svg +7 -0
  23. package/src/assets/containers/List/list.svg +3 -0
  24. package/src/assets/containers/Location/location.svg +4 -0
  25. package/src/assets/containers/Medication/medication.svg +5 -0
  26. package/src/assets/containers/MedicationAdministration/medication-administration.svg +6 -0
  27. package/src/assets/containers/MedicationKnowledge/medication-knowledge.svg +11 -0
  28. package/src/assets/containers/MedicationStatement/medication-statement.svg +5 -0
  29. package/src/assets/containers/Observation/observation.svg +12 -0
  30. package/src/assets/containers/Practitioner/practitioner.svg +5 -0
  31. package/src/assets/containers/Procedure/procedure.svg +9 -0
  32. package/src/assets/containers/Questionnaire/questionnaire.svg +6 -0
  33. package/src/assets/containers/QuestionnaireResponse/questionnaire-response.svg +6 -0
  34. package/src/assets/containers/QustionnaireResponse/questionnaire-response.svg +6 -0
  35. package/src/assets/containers/ResearchStudy/research-study.svg +9 -0
  36. package/src/assets/containers/ResourceCategory/resource-placeholder.svg +3 -0
  37. package/src/components/containers/Accordion/Accordion.js +80 -0
  38. package/src/components/containers/Accordion/Accordion.stories.js +76 -0
  39. package/src/components/containers/Accordion/index.js +3 -0
  40. package/src/components/containers/ResourceContainer/ResourceContainer.css +0 -1
  41. package/src/components/containers/ResourceContainer/ResourceContainer.js +1 -1
  42. package/src/components/datatypes/AccountBalance/AccountBalance.js +33 -0
  43. package/src/components/datatypes/AccountBalance/index.js +3 -0
  44. package/src/components/datatypes/Annotation/Annotation.js +1 -1
  45. package/src/components/datatypes/Coding/Coding.js +1 -1
  46. package/src/components/datatypes/Date/Date.js +14 -4
  47. package/src/components/datatypes/DatePeriod/DatePeriod.js +38 -0
  48. package/src/components/datatypes/DatePeriod/index.js +3 -0
  49. package/src/components/datatypes/HeaderIcon/HeaderIcon.js +31 -0
  50. package/src/components/datatypes/HeaderIcon/index.js +3 -0
  51. package/src/components/datatypes/HumanName/HumanName.js +6 -21
  52. package/src/components/datatypes/Reference/Reference.js +3 -6
  53. package/src/components/resources/AdverseEvent/AdverseEvent.test.js +2 -2
  54. package/src/components/resources/AllergyIntolerance/AllergyIntolerance.test.js +4 -4
  55. package/src/components/resources/Appointment/Appointment.js +91 -65
  56. package/src/components/resources/Appointment/Appointment.test.js +3 -3
  57. package/src/components/resources/Bundle/Bundle.js +2 -2
  58. package/src/components/resources/Bundle/Bundle.stories.js +78 -12
  59. package/src/components/resources/Bundle/Bundle.test.js +3 -0
  60. package/src/components/resources/CarePlan/CarePlan.test.js +4 -4
  61. package/src/components/resources/CareTeam/CareTeam.js +13 -14
  62. package/src/components/resources/CareTeam/CareTeam.test.js +4 -4
  63. package/src/components/resources/Claim/Claim.test.js +6 -6
  64. package/src/components/resources/ClaimResponse/ClaimResponse.test.js +6 -6
  65. package/src/components/resources/Condition/Condition.js +63 -47
  66. package/src/components/resources/Condition/Condition.stories.js +41 -8
  67. package/src/components/resources/Condition/Condition.test.js +20 -14
  68. package/src/components/resources/DiagnosticReport/DiagnosticReport.test.js +5 -7
  69. package/src/components/resources/DocumentReference/DocumentReference.js +1 -1
  70. package/src/components/resources/DocumentReference/DocumentReference.test.js +3 -3
  71. package/src/components/resources/Encounter/Encounter.js +66 -36
  72. package/src/components/resources/Encounter/EncounterParticipants.js +2 -2
  73. package/src/components/resources/ExplanationOfBenefit/CareTeam.js +2 -2
  74. package/src/components/resources/ExplanationOfBenefit/Diagnosis.js +31 -5
  75. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.js +272 -201
  76. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.stories.js +12 -0
  77. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.test.js +96 -62
  78. package/src/components/resources/ExplanationOfBenefit/Items.js +2 -2
  79. package/src/components/resources/ExplanationOfBenefit/PriceLabel.js +20 -0
  80. package/src/components/resources/ExplanationOfBenefit/Related.js +3 -3
  81. package/src/components/resources/ExplanationOfBenefit/SupportingInfo.js +14 -3
  82. package/src/components/resources/ExplanationOfBenefit/TotalGraph.js +68 -0
  83. package/src/components/resources/ExplanationOfBenefitGraph/ExplanationOfBenefitGraph.js +89 -0
  84. package/src/components/resources/ExplanationOfBenefitGraph/ExplanationOfBenefitGraph.stories.js +78 -0
  85. package/src/components/resources/ExplanationOfBenefitGraph/ExplanationOfBenefitGraph.test.js +51 -0
  86. package/src/components/resources/ExplanationOfBenefitGraph/index.js +3 -0
  87. package/src/components/resources/Goal/Goal.test.js +1 -1
  88. package/src/components/resources/Immunization/Immunization.js +125 -94
  89. package/src/components/resources/Immunization/Immunization.stories.js +23 -4
  90. package/src/components/resources/Immunization/Immunization.test.js +17 -12
  91. package/src/components/resources/List/DrugTierDefinitionExtension.js +139 -0
  92. package/src/components/resources/List/Entries.js +66 -0
  93. package/src/components/resources/List/List.js +262 -0
  94. package/src/components/resources/List/List.stories.js +75 -0
  95. package/src/components/resources/List/List.test.js +95 -0
  96. package/src/components/resources/List/index.js +3 -0
  97. package/src/components/resources/List/utils.js +6 -0
  98. package/src/components/resources/MedicationAdministration/MedicationAdministration.test.js +7 -7
  99. package/src/components/resources/MedicationDispense/MedicationDispense.test.js +2 -2
  100. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.js +217 -0
  101. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.stories.js +78 -0
  102. package/src/components/resources/MedicationKnowledge/MedicationKnowledge.test.js +69 -0
  103. package/src/components/resources/MedicationKnowledge/index.js +3 -0
  104. package/src/components/resources/MedicationKnowledge/utils.js +8 -0
  105. package/src/components/resources/MedicationRequest/MedicationRequest.test.js +4 -4
  106. package/src/components/resources/Observation/Observation.js +72 -54
  107. package/src/components/resources/Observation/Observation.test.js +6 -18
  108. package/src/components/resources/Observation/ObservationGraph.js +159 -55
  109. package/src/components/resources/Observation/ObservationGraph.test.js +47 -26
  110. package/src/components/resources/Patient/Patient.js +79 -97
  111. package/src/components/resources/Patient/Patient.test.js +10 -10
  112. package/src/components/resources/Practitioner/Practitioner.js +80 -60
  113. package/src/components/resources/Practitioner/Practitioner.test.js +4 -4
  114. package/src/components/resources/Procedure/Procedure.js +99 -87
  115. package/src/components/resources/Procedure/Procedure.stories.js +8 -6
  116. package/src/components/resources/Procedure/Procedure.test.js +11 -8
  117. package/src/components/resources/Questionnaire/Questionnaire.test.js +3 -3
  118. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.test.js +5 -5
  119. package/src/components/resources/ReferralRequest/ReferralRequest.test.js +2 -2
  120. package/src/components/resources/ResearchStudy/ResearchStudy.test.js +1 -1
  121. package/src/components/resources/ResourceCategory/ResourceCategory.js +56 -0
  122. package/src/components/resources/ResourceCategory/ResourceCategory.stories.js +29 -0
  123. package/src/components/resources/ResourceCategory/ResourceCategory.test.js +101 -0
  124. package/src/components/resources/ResourceCategory/index.js +3 -0
  125. package/src/components/supportedFhirResourceList.js +4 -0
  126. package/src/components/ui/_header.scss +3 -0
  127. package/src/components/ui/bootstrap-reboot.min.css +2 -22
  128. package/src/components/ui/index.js +191 -29
  129. package/src/constants/badge-status.jsx +98 -0
  130. package/src/fixtures/dstu2/resources/condition/condition.svg +35 -0
  131. package/src/fixtures/dstu2/resources/immunization/immunization.svg +10 -0
  132. package/src/fixtures/dstu2/resources/list/example1.json +49 -0
  133. package/src/fixtures/dstu2/resources/list/example2.json +116 -0
  134. package/src/fixtures/dstu2/resources/list/example3.json +380 -0
  135. package/src/fixtures/example-icons.jsx +169 -0
  136. package/src/fixtures/r4/resources/explanationOfBenefit/c4bbExtendedDiagnosis.json +446 -0
  137. package/src/fixtures/r4/resources/list/example1.json +45 -0
  138. package/src/fixtures/r4/resources/list/example2.json +282 -0
  139. package/src/fixtures/r4/resources/list/example3.json +298 -0
  140. package/src/fixtures/r4/resources/medicationKnowledge/example1.json +42 -0
  141. package/src/fixtures/r4/resources/medicationKnowledge/example2.json +59 -0
  142. package/src/fixtures/r4/resources/medicationKnowledge/example3.json +59 -0
  143. package/src/fixtures/r4/resources/medicationKnowledge/example4.json +59 -0
  144. package/src/fixtures/stu3/resources/list/example1.json +46 -0
  145. package/src/fixtures/stu3/resources/list/example2.json +298 -0
  146. package/src/fixtures/stu3/resources/list/example3.json +115 -0
  147. package/src/index.js +6 -1
  148. package/src/style.scss +176 -0
  149. package/src/utils/formatDate.js +21 -0
  150. package/src/utils/formatDate.test.js +22 -0
  151. package/src/utils/getBadgeColor.js +6 -0
  152. package/src/utils/getBadgeColor.test.js +14 -0
  153. package/src/utils/isUrl.js +9 -0
  154. package/src/utils/isUrl.test.js +12 -0
  155. package/src/utils.js +7 -0
  156. package/build/bootstrap-reboot.min.css +0 -414
  157. package/build/index.js +0 -15
  158. package/build/style.css +0 -459
  159. package/src/components/datatypes/HumanName/HumanName.css +0 -15
  160. package/src/components/datatypes/Reference/Reference.css +0 -8
  161. package/src/components/resources/Observation/ObservationGraph.css +0 -51
  162. package/src/components/resources/Patient/Patient.css +0 -19
  163. package/src/components/ui/index.css +0 -123
@@ -1,19 +1,21 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import md5 from 'md5';
4
- import _get from 'lodash/get';
5
- import _has from 'lodash/has';
1
+ import './Practitioner.css';
6
2
 
7
- import HumanName from '../../datatypes/HumanName';
8
- import PatientContact from './PatientContact';
9
- import fhirVersions from '../fhirResourceVersions';
10
- import UnhandledResourceDataStructure from '../UnhandledResourceDataStructure';
3
+ import { Badge, Body, Header, Root } from '../../ui';
4
+
5
+ import Accordion from '../../containers/Accordion/Accordion';
11
6
  import Address from '../../datatypes/Address';
12
- import Telecom from '../../datatypes/Telecom';
13
7
  import Date from '../../datatypes/Date';
14
- import { Root, Header, Title, Body, Value, Badge } from '../../ui';
15
- import './Practitioner.css';
8
+ import HumanName from '../../datatypes/HumanName';
16
9
  import Identifier from '../../datatypes/Identifier';
10
+ import PatientContact from './PatientContact';
11
+ import PropTypes from 'prop-types';
12
+ import React from 'react';
13
+ import Telecom from '../../datatypes/Telecom';
14
+ import UnhandledResourceDataStructure from '../UnhandledResourceDataStructure';
15
+ import _get from 'lodash/get';
16
+ import _has from 'lodash/has';
17
+ import fhirVersions from '../fhirResourceVersions';
18
+ import md5 from 'md5';
17
19
 
18
20
  const commonDTO = fhirResource => {
19
21
  const id = _get(fhirResource, 'id', '');
@@ -26,6 +28,7 @@ const commonDTO = fhirResource => {
26
28
  name: _get(fhirResource, 'contact[0].name'),
27
29
  relationship: _get(fhirResource, 'contact[0].relationship[0].text'),
28
30
  };
31
+
29
32
  return {
30
33
  id,
31
34
  identifier,
@@ -101,56 +104,73 @@ const Practitioner = props => {
101
104
  address,
102
105
  birthDate,
103
106
  } = fhirResourceData;
107
+
108
+ const use = _get(name, 'use');
109
+ const tableData = [
110
+ {
111
+ label: 'Identifiers',
112
+ testId: 'identifier',
113
+ data: identifier && <Identifier fhirData={identifier} />,
114
+ status: identifier,
115
+ },
116
+ {
117
+ label: 'Gender',
118
+ testId: 'gender',
119
+ data: gender,
120
+ status: !!gender,
121
+ },
122
+ {
123
+ label: 'Birth date',
124
+ testId: 'birthDate',
125
+ data: birthDate && <Date fhirData={birthDate} isBlack />,
126
+ status: birthDate,
127
+ },
128
+ {
129
+ label: 'Contact',
130
+ testId: 'contact',
131
+ data: isContactData && (
132
+ <PatientContact
133
+ name={contactData.name}
134
+ relationship={contactData.relationship}
135
+ />
136
+ ),
137
+ status: isContactData,
138
+ },
139
+ {
140
+ label: 'Address',
141
+ testId: 'address',
142
+ data: address && <Address fhirData={address} />,
143
+ status: address,
144
+ },
145
+ {
146
+ label: 'Telephone',
147
+ testId: 'telecom',
148
+ data: telecom && <Telecom fhirData={telecom} />,
149
+ status: telecom,
150
+ },
151
+ ];
152
+
104
153
  return (
105
154
  <Root name="Practitioner">
106
- <Header>
107
- <img
108
- className="fhir-resource__Practitioner__practitioner-avatar"
109
- src={`http://www.gravatar.com/avatar/${md5(
110
- id,
111
- )}?s=30&r=any&default=identicon&forcedefault=1`}
112
- alt=""
113
- />
114
- <Title>
115
- <HumanName fhirData={name} primary={true} />
116
- </Title>
117
- {status && <Badge data-testid="status">{status}</Badge>}
118
- </Header>
119
- <Body>
120
- {identifier && (
121
- <Value label="Identifiers" data-testid="identifier">
122
- <Identifier fhirData={identifier} />
123
- </Value>
124
- )}
125
- {gender && (
126
- <Value label="Gender" data-testid="gender">
127
- {gender}
128
- </Value>
129
- )}
130
- {birthDate && (
131
- <Value label="Birth date" data-testid="birthDate">
132
- <Date fhirData={birthDate} />
133
- </Value>
134
- )}
135
- {isContactData && (
136
- <Value label="Contact" data-testid="contact">
137
- <PatientContact
138
- name={contactData.name}
139
- relationship={contactData.relationship}
140
- />
141
- </Value>
142
- )}
143
- {address && (
144
- <Value label="Address" data-testid="address">
145
- <Address fhirData={address} />
146
- </Value>
147
- )}
148
- {telecom && (
149
- <Value label="Telephone" data-testid="telecom">
150
- <Telecom fhirData={telecom} />
151
- </Value>
152
- )}
153
- </Body>
155
+ <Accordion
156
+ headerContent={
157
+ <Header
158
+ additionalContent={<p className="mb-0">{`(${use})`}</p>}
159
+ badges={status && <Badge data-testid="status">{status}</Badge>}
160
+ icon={
161
+ <img
162
+ className="header-icon__practitioner-avatar rounded-1"
163
+ src={`http://www.gravatar.com/avatar/${md5(
164
+ id,
165
+ )}?s=30&r=any&default=identicon&forcedefault=1`}
166
+ alt=""
167
+ />
168
+ }
169
+ title={<HumanName fhirData={name} isTitle />}
170
+ />
171
+ }
172
+ bodyContent={<Body tableData={tableData} />}
173
+ />
154
174
  </Root>
155
175
  );
156
176
  };
@@ -17,7 +17,7 @@ describe('Practitioner should render component correctly', () => {
17
17
  const { getByTestId } = render(<Practitioner {...defaultProps} />);
18
18
 
19
19
  expect(String(getByTestId('title').textContent).trim()).toEqual(
20
- 'Physician Family Medicine (usual)',
20
+ 'Physician Family Medicine',
21
21
  );
22
22
  expect(getByTestId('gender').textContent).toEqual('male');
23
23
  });
@@ -30,7 +30,7 @@ describe('Practitioner should render component correctly', () => {
30
30
  const { getByTestId } = render(<Practitioner {...defaultProps} />);
31
31
 
32
32
  expect(String(getByTestId('title').textContent).trim()).toEqual(
33
- 'Sameer Sharma M.D. (official)',
33
+ 'Sameer Sharma M.D.',
34
34
  );
35
35
  expect(getByTestId('gender').textContent).toEqual('male');
36
36
  expect(getByTestId('address').textContent).toContain('5815 S Calumet');
@@ -64,12 +64,12 @@ describe('Practitioner should render component correctly', () => {
64
64
  const { getByTestId } = render(<Practitioner {...defaultProps} />);
65
65
 
66
66
  expect(String(getByTestId('title').textContent).trim()).toEqual(
67
- 'Pieter Voigt MD (official)',
67
+ 'Pieter Voigt MD',
68
68
  );
69
69
  expect(getByTestId('gender').textContent).toEqual('male');
70
70
  expect(getByTestId('address').textContent).toContain('Galapagosweg 91');
71
71
  expect(getByTestId('telecom').textContent).toContain('phone0205569336');
72
- expect(getByTestId('birthDate').textContent).toContain('1979-04-29');
72
+ expect(getByTestId('birthDate').textContent).toContain('4/29/1979');
73
73
  });
74
74
 
75
75
  it('component without fhirVersion props', () => {
@@ -1,27 +1,21 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import _get from 'lodash/get';
4
- import _has from 'lodash/has';
1
+ import { Badge, Body, Header, MissingValue, Root } from '../../ui';
5
2
 
3
+ import Accordion from '../../containers/Accordion/Accordion';
6
4
  import Annotation from '../../datatypes/Annotation';
5
+ import CodeableConcept from '../../datatypes/CodeableConcept';
7
6
  import Coding from '../../datatypes/Coding';
8
7
  import Date from '../../datatypes/Date';
8
+ import DatePeriod from '../../datatypes/DatePeriod/DatePeriod';
9
+ import PropTypes from 'prop-types';
10
+ import React from 'react';
9
11
  import Reference from '../../datatypes/Reference';
10
- import CodeableConcept from '../../datatypes/CodeableConcept';
11
- import {
12
- Root,
13
- Header,
14
- Title,
15
- Body,
16
- Value,
17
- Badge,
18
- BadgeSecondary,
19
- MissingValue,
20
- } from '../../ui';
12
+ import _get from 'lodash/get';
13
+ import _has from 'lodash/has';
21
14
  import { isNotEmptyArray } from '../../../utils';
15
+ import { Value } from '../../ui';
22
16
 
23
17
  const Procedure = props => {
24
- const { fhirResource } = props;
18
+ const { fhirResource, fhirIcons } = props;
25
19
  const display =
26
20
  _get(fhirResource, 'code.coding[0].display') ||
27
21
  _get(fhirResource, 'code.text');
@@ -42,79 +36,97 @@ const Procedure = props => {
42
36
  const hasNote = _has(fhirResource, 'note');
43
37
  const note = _get(fhirResource, 'note', []);
44
38
  const outcome = _get(fhirResource, 'outcome');
39
+
40
+ const headerIcon = fhirIcons[_get(fhirResource, 'resourceType')];
41
+ const tableData = [
42
+ {
43
+ label: 'Identification',
44
+ testId: 'hasCoding',
45
+ data: coding && (
46
+ <>
47
+ {coding.map((coding, i) => (
48
+ <Coding key={`item-${i}`} fhirData={coding} />
49
+ ))}
50
+ </>
51
+ ),
52
+ status: hasCoding,
53
+ },
54
+ {
55
+ label: 'Category',
56
+ testId: 'category',
57
+ data: category && <Coding fhirData={category} />,
58
+ status: category,
59
+ },
60
+ {
61
+ label: 'Performed by',
62
+ testId: 'dateRecorded',
63
+ data: performer && (
64
+ <>
65
+ {performer.map((item, i) => (
66
+ <div key={`item-${i}`}>
67
+ {_get(item, 'actor.display', <MissingValue />)}
68
+ </div>
69
+ ))}
70
+ </>
71
+ ),
72
+ status: hasPerformerData,
73
+ },
74
+ {
75
+ label: 'Reason procedure performed',
76
+ testId: 'hasReasonCode',
77
+ data: reasonCode && <Annotation fhirData={reasonCode} />,
78
+ status: hasReasonCode,
79
+ },
80
+ {
81
+ label: 'Location',
82
+ testId: 'location',
83
+ data: locationReference && <Reference fhirData={locationReference} />,
84
+ status: locationReference,
85
+ },
86
+ {
87
+ label: 'Additional information about the procedure',
88
+ testId: 'hasNote',
89
+ data: note && <Annotation fhirData={note} />,
90
+ status: hasNote,
91
+ },
92
+ {
93
+ label: 'The result of procedure',
94
+ testId: '',
95
+ data: outcome && <CodeableConcept fhirData={outcome} />,
96
+ status: isNotEmptyArray(outcome),
97
+ },
98
+ ];
99
+
45
100
  return (
46
101
  <Root name="Procedure">
47
- <Header>
48
- {display && <Title>{display}</Title>}
49
- {status && <Badge data-testid="status">{status}</Badge>}
50
- {hasPerformedDateTime && (
51
- <BadgeSecondary data-testid="performedDateTime">
52
- on <Date fhirData={performedDateTime} />
53
- </BadgeSecondary>
54
- )}
55
- {hasPerformedPeriod && (
56
- <BadgeSecondary>
57
- {'performed '}
58
- {performedPeriodStart ? (
59
- <Date fhirData={performedPeriodStart} />
60
- ) : (
61
- <MissingValue />
62
- )}
63
- {' to '}
64
- {performedPeriodEnd ? (
65
- <Date fhirData={performedPeriodEnd} />
66
- ) : (
67
- <MissingValue />
68
- )}
69
- </BadgeSecondary>
70
- )}
71
- </Header>
72
- <Body>
73
- {hasCoding && (
74
- <Value label="Identification" data-testid="hasCoding">
75
- {coding.map((coding, i) => (
76
- <Coding key={`item-${i}`} fhirData={coding} />
77
- ))}
78
- </Value>
79
- )}
80
- {category && (
81
- <Value label="Category" data-testid="category">
82
- <Coding fhirData={category} />
83
- </Value>
84
- )}
85
- {hasPerformerData && (
86
- <Value label="Performed the procedure">
87
- {performer.map((item, i) => (
88
- <div key={`item-${i}`}>
89
- {_get(item, 'actor.display', <MissingValue />)}
90
- </div>
91
- ))}
92
- </Value>
93
- )}
94
- {hasReasonCode && (
95
- <Value label="Reason procedure performed" data-testid="hasReasonCode">
96
- <Annotation fhirData={reasonCode} />
97
- </Value>
98
- )}
99
- {locationReference && (
100
- <Value label="Location" data-testid="location">
101
- <Reference fhirData={locationReference} />
102
- </Value>
103
- )}
104
- {hasNote && (
105
- <Value
106
- label="Additional information about the procedure"
107
- data-testid="hasNote"
108
- >
109
- <Annotation fhirData={note} />
110
- </Value>
111
- )}
112
- {isNotEmptyArray(outcome) && (
113
- <Value label="The result of procedure">
114
- <CodeableConcept fhirData={outcome} />
115
- </Value>
116
- )}
117
- </Body>
102
+ <Accordion
103
+ headerContent={
104
+ <Header
105
+ resourceName="Procedure"
106
+ additionalContent={
107
+ <>
108
+ {hasPerformedDateTime && (
109
+ <Value label="Start date" data-testid="headerStartDate">
110
+ <Date fhirData={performedDateTime} isBlack />
111
+ </Value>
112
+ )}
113
+ {hasPerformedPeriod && (
114
+ <DatePeriod
115
+ periodBeginLabel="performed"
116
+ periodBeginDate={performedPeriodStart}
117
+ periodEndLabel="to"
118
+ periodEndDate={performedPeriodEnd}
119
+ />
120
+ )}
121
+ </>
122
+ }
123
+ badges={status && <Badge data-testid="status">{status}</Badge>}
124
+ icon={headerIcon}
125
+ title={display}
126
+ />
127
+ }
128
+ bodyContent={<Body tableData={tableData} />}
129
+ />
118
130
  </Root>
119
131
  );
120
132
  };
@@ -11,34 +11,36 @@ import r4Example1 from '../../../fixtures/r4/resources/procedure/example1.json';
11
11
  import r4Example2 from '../../../fixtures/r4/resources/procedure/example2.json';
12
12
  import r4Example3 from '../../../fixtures/r4/resources/procedure/example3.json';
13
13
 
14
+ import fhirIcons from '../../../fixtures/example-icons';
15
+
14
16
  export default { title: 'Procedure' };
15
17
 
16
18
  export const DefaultVisualizationDSTU2 = () => {
17
19
  const fhirResource = object('Resource', example1);
18
- return <Procedure fhirResource={fhirResource} />;
20
+ return <Procedure fhirResource={fhirResource} fhirIcons={fhirIcons} />;
19
21
  };
20
22
 
21
23
  export const ExampleOfSTU3 = () => {
22
24
  const fhirResource = object('Resource', stu3Example1);
23
- return <Procedure fhirResource={fhirResource} />;
25
+ return <Procedure fhirResource={fhirResource} fhirIcons={fhirIcons} />;
24
26
  };
25
27
 
26
28
  export const Example2OfSTU3 = () => {
27
29
  const fhirResource = object('Resource', stu3Example2);
28
- return <Procedure fhirResource={fhirResource} />;
30
+ return <Procedure fhirResource={fhirResource} fhirIcons={fhirIcons} />;
29
31
  };
30
32
 
31
33
  export const Example1OfR4 = () => {
32
34
  const fhirResource = object('Resource', r4Example1);
33
- return <Procedure fhirResource={fhirResource} />;
35
+ return <Procedure fhirResource={fhirResource} fhirIcons={fhirIcons} />;
34
36
  };
35
37
 
36
38
  export const Example2OfR4 = () => {
37
39
  const fhirResource = object('Resource', r4Example2);
38
- return <Procedure fhirResource={fhirResource} />;
40
+ return <Procedure fhirResource={fhirResource} fhirIcons={fhirIcons} />;
39
41
  };
40
42
 
41
43
  export const Example3OfR4 = () => {
42
44
  const fhirResource = object('Resource', r4Example3);
43
- return <Procedure fhirResource={fhirResource} />;
45
+ return <Procedure fhirResource={fhirResource} fhirIcons={fhirIcons} />;
44
46
  };
@@ -1,17 +1,18 @@
1
- import React from 'react';
2
- import { render } from '@testing-library/react';
3
1
  import Procedure from './Procedure';
4
-
2
+ import React from 'react';
5
3
  import dstu2Example1 from '../../../fixtures/dstu2/resources/procedure/example1.json';
6
- import stu3Example1 from '../../../fixtures/stu3/resources/procedure/example1.json';
7
-
8
4
  import r4Example2 from '../../../fixtures/r4/resources/procedure/example2.json';
9
5
  import r4Example3 from '../../../fixtures/r4/resources/procedure/example3.json';
6
+ import { render } from '@testing-library/react';
7
+ import stu3Example1 from '../../../fixtures/stu3/resources/procedure/example1.json';
8
+
9
+ import fhirIcons from '../../../fixtures/example-icons';
10
10
 
11
11
  describe('Procedure should render component correctly', () => {
12
12
  it('should render component correctly with DSTU2 source data', () => {
13
13
  const defaultProps = {
14
14
  fhirResource: dstu2Example1,
15
+ fhirIcons: fhirIcons,
15
16
  };
16
17
  const { getByTestId } = render(<Procedure {...defaultProps} />);
17
18
 
@@ -22,6 +23,7 @@ describe('Procedure should render component correctly', () => {
22
23
  it('should render component correctly with STU3 source data', () => {
23
24
  const defaultProps = {
24
25
  fhirResource: stu3Example1,
26
+ fhirIcons: fhirIcons,
25
27
  };
26
28
  const { getByTestId } = render(<Procedure {...defaultProps} />);
27
29
 
@@ -34,6 +36,7 @@ describe('Procedure should render component correctly', () => {
34
36
  it('should render component that contain extra fields based of STU3 source data', () => {
35
37
  const defaultProps = {
36
38
  fhirResource: stu3Example1,
39
+ fhirIcons: fhirIcons,
37
40
  };
38
41
  const { getByTestId } = render(<Procedure {...defaultProps} />);
39
42
 
@@ -48,6 +51,7 @@ describe('Procedure should render component correctly', () => {
48
51
  it('should render component correctly with R4 source data - example 1', () => {
49
52
  const defaultProps = {
50
53
  fhirResource: r4Example2,
54
+ fhirIcons: fhirIcons,
51
55
  };
52
56
  const { getByTestId, queryByTestId } = render(
53
57
  <Procedure {...defaultProps} />,
@@ -57,9 +61,7 @@ describe('Procedure should render component correctly', () => {
57
61
  'Insertion of intracardiac pacemaker (procedure)',
58
62
  );
59
63
  expect(getByTestId('status').textContent).toEqual('completed');
60
- expect(getByTestId('performedDateTime').textContent).toEqual(
61
- 'on 2015-04-05',
62
- );
64
+ expect(getByTestId('providedDate').textContent).toEqual('4/5/2015');
63
65
  expect(getByTestId('hasCoding').textContent).toContain(
64
66
  'Insertion of intracardiac',
65
67
  );
@@ -77,6 +79,7 @@ describe('Procedure should render component correctly', () => {
77
79
  it('should render component correctly with STU3 source data - example 2', () => {
78
80
  const defaultProps = {
79
81
  fhirResource: r4Example3,
82
+ fhirIcons: fhirIcons,
80
83
  };
81
84
  const { getByTestId, queryByTestId } = render(
82
85
  <Procedure {...defaultProps} />,
@@ -58,7 +58,7 @@ describe('Questionnaire should render component correctly', () => {
58
58
  'Cancer Quality Forum Questionnaire',
59
59
  );
60
60
  expect(getByTestId('status').textContent).toEqual('draft');
61
- expect(getByTestId('dateTime').textContent).toEqual('2012-01');
61
+ expect(getByTestId('dateTime').textContent).toEqual('January 2012');
62
62
 
63
63
  // contain id and test of questions of subgroup
64
64
  expect(String(getByTestId('linkId-1.1').textContent).trim()).toContain(
@@ -119,7 +119,7 @@ describe('Questionnaire should render component correctly', () => {
119
119
  'Cancer Quality Forum Questionnaire',
120
120
  );
121
121
  expect(getByTestId('status').textContent).toEqual('draft');
122
- expect(getByTestId('dateTime').textContent).toEqual('2012-01');
122
+ expect(getByTestId('dateTime').textContent).toEqual('January 2012');
123
123
 
124
124
  // contain id and test of questions of subgroup
125
125
  expect(String(getByTestId('linkId-1.1').textContent).trim()).toContain(
@@ -180,7 +180,7 @@ describe('Questionnaire should render component correctly', () => {
180
180
  'Cancer Quality Forum Questionnaire',
181
181
  );
182
182
  expect(getByTestId('status').textContent).toEqual('draft');
183
- expect(getByTestId('dateTime').textContent).toEqual('2012-01');
183
+ expect(getByTestId('dateTime').textContent).toEqual('January 2012');
184
184
 
185
185
  // contain id and test of questions of subgroup
186
186
  expect(String(getByTestId('linkId-1.1').textContent).trim()).toContain(
@@ -23,7 +23,7 @@ describe('QuestionnaireResponse should render component correctly', () => {
23
23
  'Questionnaire Response',
24
24
  );
25
25
  expect(getByTestId('status').textContent).toEqual('completed');
26
- expect(getByTestId('dateTime').textContent).toEqual('2013-06-18');
26
+ expect(getByTestId('dateTime').textContent).toEqual('6/18/2013');
27
27
  expect(getByTestId('subject').textContent).toEqual('RoelPatient/f201');
28
28
  expect(getByTestId('author').textContent).toEqual('Practitioner/f201');
29
29
 
@@ -34,7 +34,7 @@ describe('QuestionnaireResponse should render component correctly', () => {
34
34
  'What is your gender?Male ',
35
35
  );
36
36
  expect(getByTestId('linkId-2.2').textContent).toEqual(
37
- 'What is your date of birth?1960-03-13 ',
37
+ 'What is your date of birth?3/13/1960 ',
38
38
  );
39
39
  expect(getByTestId('linkId-2.3').textContent).toEqual(
40
40
  'What is your country of birth?The Netherlands ',
@@ -56,7 +56,7 @@ describe('QuestionnaireResponse should render component correctly', () => {
56
56
  'Glasgow Coma Score',
57
57
  );
58
58
  expect(getByTestId('status').textContent).toEqual('completed');
59
- expect(getByTestId('dateTime').textContent).toEqual('2014-12-11');
59
+ expect(getByTestId('dateTime').textContent).toEqual('12/11/2014');
60
60
 
61
61
  expect(getByTestId('linkId-1.1').textContent).toContain('(LA6560-2) ');
62
62
  });
@@ -72,7 +72,7 @@ describe('QuestionnaireResponse should render component correctly', () => {
72
72
  'Questionnaire Response',
73
73
  );
74
74
  expect(getByTestId('status').textContent).toEqual('completed');
75
- expect(getByTestId('dateTime').textContent).toEqual('2013-02-19');
75
+ expect(getByTestId('dateTime').textContent).toEqual('2/19/2013');
76
76
 
77
77
  expect(getByTestId('answer-nameOfChild-0').textContent).toContain(
78
78
  'Cathy Jones',
@@ -90,7 +90,7 @@ describe('QuestionnaireResponse should render component correctly', () => {
90
90
  'Questionnaire Response',
91
91
  );
92
92
  expect(getByTestId('status').textContent).toEqual('completed');
93
- expect(getByTestId('dateTime').textContent).toEqual('2013-06-18');
93
+ expect(getByTestId('dateTime').textContent).toEqual('6/18/2013');
94
94
  expect(getByTestId('subject').textContent).toEqual('RoelPatient/f201');
95
95
  expect(getByTestId('author').textContent).toEqual('Practitioner/f201');
96
96
 
@@ -21,7 +21,7 @@ describe('should render ReferralRequest component properly', () => {
21
21
  expect(getByTestId('typeCoding').textContent).toContain(
22
22
  'Referral for service',
23
23
  );
24
- expect(getByTestId('dateSent').textContent).toContain('2014-02-14');
24
+ expect(getByTestId('dateSent').textContent).toContain('2/14/2014');
25
25
  expect(getByTestId('reason').textContent).toContain(
26
26
  'For consideration of Grommets',
27
27
  );
@@ -46,7 +46,7 @@ describe('should render ReferralRequest component properly', () => {
46
46
  expect(getByTestId('typeCoding').textContent).toContain(
47
47
  'Patient referral to specialist',
48
48
  );
49
- expect(getByTestId('dateSent').textContent).toContain('2014-02-14');
49
+ expect(getByTestId('dateSent').textContent).toContain('2/14/2014');
50
50
  expect(getByTestId('reason').textContent).toContain(
51
51
  'For consideration of Grommets',
52
52
  );
@@ -48,7 +48,7 @@ describe('should render ResearchStudy component properly', () => {
48
48
 
49
49
  expect(title).toEqual('Example study');
50
50
  expect(status).toEqual('completed');
51
- expect(period).toEqual('2015-02-01 - 2015-02-21');
51
+ expect(period).toEqual('2/1/2015 - 2/21/2015');
52
52
  expect(category).toEqual('Gene expression (GENE)');
53
53
  expect(focus).toEqual('Prostate cancer (PRC)');
54
54
  expect(protocol).toEqual('PlanDefinition/pdf1');
@@ -0,0 +1,56 @@
1
+ import { Root, Title } from '../../ui';
2
+ import ChevronRight from '../../../assets/common/chevron-right.svg';
3
+ import HeaderIcon from '../../datatypes/HeaderIcon';
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+
7
+ const ResourceCategory = props => {
8
+ const { title, itemsCount, fhirIcons } = props;
9
+
10
+ const parseNumber = value =>
11
+ /^[1-9]+\d*$/.test(value) ? Number.parseInt(value) : null;
12
+
13
+ const getItemsCountLabel = () =>
14
+ `${parsedItemsCount} ${parsedItemsCount === 1 ? 'item' : 'items'}`;
15
+
16
+ const headerIcon = fhirIcons['ResourceCategoryPlaceholder'];
17
+ const parsedItemsCount = parseNumber(itemsCount);
18
+
19
+ return (
20
+ <Root name="ResourceCategory">
21
+ <button
22
+ type="button"
23
+ className="btn d-flex align-items-center justify-content-between w-100 py-4 px-4 bg-white"
24
+ >
25
+ <div className="d-flex gap-2">
26
+ <HeaderIcon headerIcon={headerIcon} />
27
+ <Title data-testid="title">{title}</Title>
28
+ </div>
29
+ <div className="d-flex gap-2 align-items-center">
30
+ {parsedItemsCount > 0 && (
31
+ <div
32
+ className="d-flex rounded-pill py-1 px-2 bg-gray-200"
33
+ data-testid="itemsCount"
34
+ >
35
+ <small className="fw-bold text-nowrap ">
36
+ {getItemsCountLabel()}
37
+ </small>
38
+ </div>
39
+ )}
40
+ <img
41
+ src={ChevronRight}
42
+ alt="chevron"
43
+ style={{ height: 28, width: 28 }}
44
+ />
45
+ </div>
46
+ </button>
47
+ </Root>
48
+ );
49
+ };
50
+
51
+ ResourceCategory.propTypes = {
52
+ title: PropTypes.string.isRequired,
53
+ itemsCount: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
54
+ };
55
+
56
+ export default ResourceCategory;