fhir-react 0.2.4 → 0.3.3

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/.github/workflows/publish_npmjs.yml +20 -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 +48 -4
  6. package/build/bootstrap-reboot.min.css +2 -22
  7. package/build/index.js +38 -3
  8. package/build/style.css +31 -459
  9. package/package.json +15 -5
  10. package/src/assets/common/chevron-right.svg +3 -0
  11. package/src/assets/containers/AllergyIntolerance/allergy-intolerance.svg +9 -0
  12. package/src/assets/containers/Appointment/appointment.svg +14 -0
  13. package/src/assets/containers/CarePlan/care-plan.svg +10 -0
  14. package/src/assets/containers/CareTeam/care-team.svg +10 -0
  15. package/src/assets/containers/Claim/claim.svg +6 -0
  16. package/src/assets/containers/ClaimResponse/claim-response.svg +7 -0
  17. package/src/assets/containers/Condition/condition.svg +11 -0
  18. package/src/assets/containers/Device/device.svg +8 -0
  19. package/src/assets/containers/DiagnosticReport/diagnostic-report.svg +14 -0
  20. package/src/assets/containers/DocumentReference/document-reference.svg +10 -0
  21. package/src/assets/containers/Encounter/encounter.svg +10 -0
  22. package/src/assets/containers/ExplanationOfBenefit/explanation-of-benefit.svg +3 -0
  23. package/src/assets/containers/FamilyMemberHistory/family-member-history.svg +7 -0
  24. package/src/assets/containers/Goal/goal.svg +11 -0
  25. package/src/assets/containers/Immunization/immunization.svg +7 -0
  26. package/src/assets/containers/List/list.svg +3 -0
  27. package/src/assets/containers/Location/location.svg +4 -0
  28. package/src/assets/containers/Medication/medication.svg +5 -0
  29. package/src/assets/containers/MedicationAdministration/medication-administration.svg +6 -0
  30. package/src/assets/containers/MedicationKnowledge/medication-knowledge.svg +11 -0
  31. package/src/assets/containers/MedicationStatement/medication-statement.svg +5 -0
  32. package/src/assets/containers/Observation/observation.svg +12 -0
  33. package/src/assets/containers/Practitioner/practitioner.svg +5 -0
  34. package/src/assets/containers/Procedure/procedure.svg +9 -0
  35. package/src/assets/containers/Questionnaire/questionnaire.svg +6 -0
  36. package/src/assets/containers/QuestionnaireResponse/questionnaire-response.svg +6 -0
  37. package/src/assets/containers/QustionnaireResponse/questionnaire-response.svg +6 -0
  38. package/src/assets/containers/ResearchStudy/research-study.svg +9 -0
  39. package/src/assets/containers/ResourceCategory/resource-placeholder.svg +3 -0
  40. package/src/components/containers/Accordion/Accordion.js +80 -0
  41. package/src/components/containers/Accordion/Accordion.stories.js +76 -0
  42. package/src/components/containers/Accordion/index.js +3 -0
  43. package/src/components/containers/ResourceContainer/ResourceContainer.css +0 -1
  44. package/src/components/containers/ResourceContainer/ResourceContainer.js +1 -1
  45. package/src/components/datatypes/AccountBalance/AccountBalance.js +33 -0
  46. package/src/components/datatypes/AccountBalance/index.js +3 -0
  47. package/src/components/datatypes/Annotation/Annotation.js +1 -1
  48. package/src/components/datatypes/Date/Date.js +14 -4
  49. package/src/components/datatypes/DatePeriod/DatePeriod.js +38 -0
  50. package/src/components/datatypes/DatePeriod/index.js +3 -0
  51. package/src/components/datatypes/HeaderIcon/HeaderIcon.js +31 -0
  52. package/src/components/datatypes/HeaderIcon/index.js +3 -0
  53. package/src/components/datatypes/HumanName/HumanName.js +6 -21
  54. package/src/components/datatypes/Reference/Reference.js +3 -6
  55. package/src/components/resources/AdverseEvent/AdverseEvent.test.js +2 -2
  56. package/src/components/resources/AllergyIntolerance/AllergyIntolerance.test.js +4 -4
  57. package/src/components/resources/Appointment/Appointment.js +91 -65
  58. package/src/components/resources/Appointment/Appointment.test.js +3 -3
  59. package/src/components/resources/Bundle/Bundle.js +2 -2
  60. package/src/components/resources/Bundle/Bundle.stories.js +78 -12
  61. package/src/components/resources/Bundle/Bundle.test.js +3 -0
  62. package/src/components/resources/CarePlan/CarePlan.test.js +4 -4
  63. package/src/components/resources/CareTeam/CareTeam.js +13 -14
  64. package/src/components/resources/CareTeam/CareTeam.test.js +4 -4
  65. package/src/components/resources/Claim/Claim.test.js +6 -6
  66. package/src/components/resources/ClaimResponse/ClaimResponse.test.js +6 -6
  67. package/src/components/resources/Condition/Condition.js +64 -47
  68. package/src/components/resources/Condition/Condition.stories.js +41 -8
  69. package/src/components/resources/Condition/Condition.test.js +20 -14
  70. package/src/components/resources/DiagnosticReport/DiagnosticReport.test.js +5 -7
  71. package/src/components/resources/DocumentReference/DocumentReference.js +1 -1
  72. package/src/components/resources/DocumentReference/DocumentReference.test.js +3 -3
  73. package/src/components/resources/Encounter/Encounter.js +66 -36
  74. package/src/components/resources/Encounter/EncounterParticipants.js +2 -2
  75. package/src/components/resources/ExplanationOfBenefit/CareTeam.js +2 -2
  76. package/src/components/resources/ExplanationOfBenefit/Diagnosis.js +15 -5
  77. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.js +285 -203
  78. package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.test.js +86 -64
  79. package/src/components/resources/ExplanationOfBenefit/Items.js +2 -2
  80. package/src/components/resources/ExplanationOfBenefit/PriceLabel.js +20 -0
  81. package/src/components/resources/ExplanationOfBenefit/Related.js +3 -3
  82. package/src/components/resources/ExplanationOfBenefit/SupportingInfo.js +32 -6
  83. package/src/components/resources/ExplanationOfBenefit/TotalGraph.js +68 -0
  84. package/src/components/resources/ExplanationOfBenefitGraph/ExplanationOfBenefitGraph.js +89 -0
  85. package/src/components/resources/ExplanationOfBenefitGraph/ExplanationOfBenefitGraph.stories.js +78 -0
  86. package/src/components/resources/ExplanationOfBenefitGraph/ExplanationOfBenefitGraph.test.js +51 -0
  87. package/src/components/resources/ExplanationOfBenefitGraph/index.js +3 -0
  88. package/src/components/resources/Goal/Goal.test.js +1 -1
  89. package/src/components/resources/Immunization/Immunization.js +125 -94
  90. package/src/components/resources/Immunization/Immunization.stories.js +23 -4
  91. package/src/components/resources/Immunization/Immunization.test.js +17 -12
  92. package/src/components/resources/List/List.test.js +3 -3
  93. package/src/components/resources/MedicationAdministration/MedicationAdministration.test.js +7 -7
  94. package/src/components/resources/MedicationDispense/MedicationDispense.test.js +2 -2
  95. package/src/components/resources/MedicationRequest/MedicationRequest.test.js +4 -4
  96. package/src/components/resources/Observation/Observation.js +72 -54
  97. package/src/components/resources/Observation/Observation.test.js +6 -18
  98. package/src/components/resources/Observation/ObservationGraph.js +159 -55
  99. package/src/components/resources/Observation/ObservationGraph.test.js +47 -26
  100. package/src/components/resources/Patient/Patient.js +77 -87
  101. package/src/components/resources/Patient/Patient.test.js +1 -1
  102. package/src/components/resources/Practitioner/Practitioner.js +80 -60
  103. package/src/components/resources/Practitioner/Practitioner.test.js +4 -4
  104. package/src/components/resources/Procedure/Procedure.js +99 -87
  105. package/src/components/resources/Procedure/Procedure.stories.js +8 -6
  106. package/src/components/resources/Procedure/Procedure.test.js +11 -8
  107. package/src/components/resources/Questionnaire/Questionnaire.test.js +3 -3
  108. package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.test.js +5 -5
  109. package/src/components/resources/ReferralRequest/ReferralRequest.test.js +2 -2
  110. package/src/components/resources/ResearchStudy/ResearchStudy.test.js +1 -1
  111. package/src/components/resources/ResourceCategory/ResourceCategory.js +55 -0
  112. package/src/components/resources/ResourceCategory/ResourceCategory.stories.js +29 -0
  113. package/src/components/resources/ResourceCategory/ResourceCategory.test.js +101 -0
  114. package/src/components/resources/ResourceCategory/index.js +3 -0
  115. package/src/components/supportedFhirResourceList.js +2 -0
  116. package/src/components/ui/_header.scss +3 -0
  117. package/src/components/ui/bootstrap-reboot.min.css +2 -22
  118. package/src/components/ui/index.js +191 -29
  119. package/src/constants/badge-status.jsx +98 -0
  120. package/src/fixtures/dstu2/resources/condition/condition.svg +35 -0
  121. package/src/fixtures/dstu2/resources/immunization/immunization.svg +10 -0
  122. package/src/fixtures/example-icons.jsx +169 -0
  123. package/src/fixtures/r4/resources/explanationOfBenefit/c4bbExample.json +18 -2
  124. package/src/index.js +7 -1
  125. package/src/style.scss +176 -0
  126. package/src/utils/formatDate.js +21 -0
  127. package/src/utils/formatDate.test.js +22 -0
  128. package/src/utils/getBadgeColor.js +6 -0
  129. package/src/utils/getBadgeColor.test.js +14 -0
  130. package/src/utils/isUrl.js +9 -0
  131. package/src/utils/isUrl.test.js +12 -0
  132. package/src/utils.js +7 -0
  133. package/webpack.config.js +10 -1
  134. package/src/components/datatypes/HumanName/HumanName.css +0 -15
  135. package/src/components/datatypes/Reference/Reference.css +0 -8
  136. package/src/components/resources/Observation/ObservationGraph.css +0 -51
  137. package/src/components/resources/Patient/Patient.css +0 -19
  138. package/src/components/ui/index.css +0 -123
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import _get from 'lodash/get';
4
+ import _isEmpty from 'lodash/isEmpty';
4
5
  import md5 from 'md5';
5
6
 
6
7
  import HumanName from '../../datatypes/HumanName';
@@ -8,8 +9,8 @@ import Telecom from '../../datatypes/Telecom';
8
9
  import Address from '../../datatypes/Address';
9
10
  import Coding from '../../datatypes/Coding';
10
11
  import Date from '../../datatypes/Date';
11
- import { Root, Header, Body, Value, MissingValue, Badge } from '../../ui';
12
- import './Patient.css';
12
+ import Accordion from '../../containers/Accordion';
13
+ import { Root, Header, MissingValue, Badge, Body } from '../../ui';
13
14
 
14
15
  export function PatientContact(props) {
15
16
  const { fhirData } = props;
@@ -20,7 +21,7 @@ export function PatientContact(props) {
20
21
  <div>
21
22
  <HumanName fhirData={name} />
22
23
  {relationship && (
23
- <small className="fhir-resource__Patient__patientContact-relationship">{` (${relationship})`}</small>
24
+ <small className="text-bold">{` (${relationship})`}</small>
24
25
  )}
25
26
  </div>
26
27
  );
@@ -57,7 +58,8 @@ function Patient(props) {
57
58
  .filter(item => Boolean(_get(item, 'language.coding', null)))
58
59
  .map(item => item.language.coding);
59
60
  communicationLanguage = _get(communicationLanguage, '0', []);
60
- const hasCommunicationLanguage = communicationLanguage.length > 0;
61
+ const hasCommunicationLanguage = !_isEmpty(communicationLanguage);
62
+ const hasPatientPhones = !_isEmpty(patientPhones);
61
63
  const active = _get(fhirResource, 'active', false);
62
64
  const activeStatus = active ? 'active' : 'inactive';
63
65
  const deceasedBoolean = _get(fhirResource, 'deceasedBoolean', false);
@@ -68,92 +70,80 @@ function Patient(props) {
68
70
  return <HumanName fhirData={patientName} primary={index === 0} />;
69
71
  };
70
72
 
73
+ const tableData = [
74
+ {
75
+ label: 'Patient contact',
76
+ testId: 'patientContact',
77
+ data: patientContact && <PatientContact fhirData={patientContact} />,
78
+ status: patientContact,
79
+ },
80
+ {
81
+ label: 'Deceased',
82
+ testId: 'deceasedInfo',
83
+ data: deceasedDate ? <Date fhirData={deceasedDate} /> : 'yes',
84
+ status: !patientSimple && isDeceased,
85
+ },
86
+ {
87
+ label: 'Address',
88
+ testId: 'patientAddress',
89
+ data: patientAddress && <Address fhirData={patientAddress} />,
90
+ status: !patientSimple && patientAddress,
91
+ },
92
+ {
93
+ label: 'Telephone',
94
+ testId: 'patientPhones',
95
+ data: !hasPatientPhones ? (
96
+ <MissingValue />
97
+ ) : (
98
+ patientPhones.map((telecom, index) => (
99
+ <Telecom key={index} fhirData={telecom} />
100
+ ))
101
+ ),
102
+ status: !patientSimple,
103
+ },
104
+ {
105
+ label: 'Communication - language',
106
+ testId: 'communicationLanguage',
107
+ data:
108
+ hasCommunicationLanguage &&
109
+ communicationLanguage.map((item, i) => (
110
+ <Coding key={`item-${i}`} fhirData={item} />
111
+ )),
112
+ status: !patientSimple && hasCommunicationLanguage,
113
+ },
114
+ ];
115
+
71
116
  return (
72
117
  <Root name="Patient">
73
- <Header>
74
- <div className="fhir-resource__Patient__patient-block">
75
- <div>
76
- <img
77
- className="fhir-resource__Patient__patient-avatar"
78
- src={avatarSrc}
79
- alt=""
80
- />
81
- </div>
82
- <div>
83
- <div className="fhir-resource__Patient__patient-block">
84
- <React.Fragment>
85
- <span data-testid={`patientName`}>
86
- {renderName
87
- ? renderName({
88
- patientName,
89
- defaultName,
90
- fhirVersion,
91
- id,
92
- })
93
- : defaultName(patientName, 0)}
94
- </span>
95
- &nbsp;&nbsp;
96
- </React.Fragment>
97
- </div>
98
- <div>
99
- {active && (
100
- <Badge data-testid="activeStatus">{activeStatus}</Badge>
101
- )}
102
- {patientBirthDate && (
103
- <span className="fhir-resource__Patient__BirthDate-block">
104
- <strong>
105
- <span data-testid="patientGender">
106
- {patientGender || 'unknown'}
107
- </span>
108
- {', '}
109
- <span data-testid="patientBirthDate">
110
- {patientBirthDate}
111
- </span>
112
- </strong>
113
- <small> (DOB)</small>
118
+ <Accordion
119
+ headerContent={
120
+ <Header
121
+ resourceName={fhirResource.resourceType}
122
+ additionalContent={
123
+ patientBirthDate && (
124
+ <span className="text-gray-600">
125
+ <span data-testid="patientGender" className="text-capitalize">
126
+ {patientGender || 'unknown'}
127
+ </span>
128
+ {', '}
129
+ <span data-testid="patientBirthDate">{patientBirthDate}</span>
114
130
  </span>
115
- )}
116
- </div>
117
- <div>
118
- {patientContact && <PatientContact fhirData={patientContact} />}
119
- </div>
120
- </div>
121
- </div>
122
- </Header>
123
- {!patientSimple && (
124
- <Body>
125
- {isDeceased && (
126
- <Value label="Deceased" data-testid="deceasedInfo">
127
- {deceasedDate ? <Date fhirData={deceasedDate} /> : 'yes'}
128
- </Value>
129
- )}
130
- {patientAddress && (
131
- <Value label="Address" data-testid="patientAddress">
132
- <Address fhirData={patientAddress} />
133
- </Value>
134
- )}
135
- {patientPhones && (
136
- <Value label="TELEPHONE" data-testid="patientPhones">
137
- {patientPhones.map((telecom, index) => (
138
- <div key={index}>
139
- <Telecom fhirData={telecom} />
140
- </div>
141
- ))}
142
- {patientPhones.length === 0 && <MissingValue />}
143
- </Value>
144
- )}
145
- {hasCommunicationLanguage && (
146
- <Value
147
- label="Communication - language"
148
- data-testid="communicationLanguage"
149
- >
150
- {communicationLanguage.map((item, i) => (
151
- <Coding key={`item-${i}`} fhirData={item} />
152
- ))}
153
- </Value>
154
- )}
155
- </Body>
156
- )}
131
+ )
132
+ }
133
+ icon={avatarSrc}
134
+ badges={
135
+ active && <Badge data-testid="activeStatus">{activeStatus}</Badge>
136
+ }
137
+ title={
138
+ renderName
139
+ ? renderName({ patientName, defaultName, fhirVersion, id })
140
+ : defaultName(patientName, 0)
141
+ }
142
+ titleTestID="patientName"
143
+ />
144
+ }
145
+ bodyContent={<Body tableData={tableData} />}
146
+ />
157
147
  </Root>
158
148
  );
159
149
  }
@@ -87,6 +87,6 @@ describe('should render component correctly', () => {
87
87
  fhirResource: example3PatientR4,
88
88
  };
89
89
  const { getByTestId } = render(<Patient {...defaultProps} />);
90
- expect(getByTestId('deceasedInfo').textContent).toEqual('2015-02-14');
90
+ expect(getByTestId('deceasedInfo').textContent).toEqual('2/14/2015');
91
91
  });
92
92
  });
@@ -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 && 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
  };