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
@@ -0,0 +1,217 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import _get from 'lodash/get';
4
+ import UnhandledResourceDataStructure from '../UnhandledResourceDataStructure';
5
+ import fhirVersions from '../fhirResourceVersions';
6
+ import { getExtension, isBoolean } from './utils';
7
+
8
+ import {
9
+ Root,
10
+ Header,
11
+ Title,
12
+ Value,
13
+ Body,
14
+ Badge,
15
+ ValueSection,
16
+ } from '../../ui';
17
+ import Reference from '../../datatypes/Reference';
18
+ import CodeableConcept from '../../datatypes/CodeableConcept';
19
+
20
+ const commonDTO = fhirResource => {
21
+ const id = _get(fhirResource, 'id');
22
+ const code = _get(fhirResource, 'code');
23
+ const status = _get(fhirResource, 'status');
24
+ const manufacturer = _get(fhirResource, 'manufacturer');
25
+ const amount = _get(fhirResource, 'amount');
26
+ const synonym = _get(fhirResource, 'synonym');
27
+
28
+ return {
29
+ id,
30
+ code,
31
+ status,
32
+ manufacturer,
33
+ amount,
34
+ synonym,
35
+ };
36
+ };
37
+
38
+ const daVinciPDex = fhirResource => {
39
+ const extension = _get(fhirResource, 'extension', []);
40
+ const hasExtensions = extension.length > 0;
41
+
42
+ if (hasExtensions) {
43
+ const usdfPriorAuthorization = _get(
44
+ getExtension('usdf-PriorAuthorization-extension', extension),
45
+ 'valueBoolean',
46
+ );
47
+ const usdfStepTherapyLimit = _get(
48
+ getExtension('usdf-StepTherapyLimit-extension', extension),
49
+ 'valueBoolean',
50
+ );
51
+ const usdfQuantityLimit = _get(
52
+ getExtension('usdf-QuantityLimit-extension', extension),
53
+ 'valueBoolean',
54
+ );
55
+ const usdfPlanID = _get(
56
+ getExtension('usdf-PlanID-extension', extension),
57
+ 'valueString',
58
+ );
59
+ const usdfDrugTierID = _get(
60
+ getExtension('usdf-DrugTierID-extension', extension),
61
+ 'valueCodeableConcept',
62
+ );
63
+
64
+ return {
65
+ hasExtensions,
66
+ usdfPriorAuthorization,
67
+ usdfStepTherapyLimit,
68
+ usdfQuantityLimit,
69
+ usdfPlanID,
70
+ usdfDrugTierID,
71
+ };
72
+ }
73
+
74
+ return {
75
+ hasExtensions,
76
+ };
77
+ };
78
+
79
+ const resourceDTO = (fhirVersion, fhirResource, withDaVinciPDex) => {
80
+ switch (fhirVersion) {
81
+ case fhirVersions.DSTU2:
82
+ case fhirVersions.STU3: {
83
+ throw Error(
84
+ `${fhirVersion} FHIR version is not supported for this resource.`,
85
+ );
86
+ }
87
+ case fhirVersions.R4: {
88
+ const dto = {
89
+ ...commonDTO(fhirResource),
90
+ };
91
+
92
+ if (withDaVinciPDex) {
93
+ return {
94
+ ...dto,
95
+ ...daVinciPDex(fhirResource),
96
+ };
97
+ }
98
+
99
+ return dto;
100
+ }
101
+ default:
102
+ throw Error('Unrecognized the fhir version property type.');
103
+ }
104
+ };
105
+
106
+ const MedicationKnowledge = props => {
107
+ const { fhirResource, fhirVersion, withDaVinciPDex = false } = props;
108
+ let fhirResourceData = {};
109
+ try {
110
+ fhirResourceData = resourceDTO(fhirVersion, fhirResource, withDaVinciPDex);
111
+ } catch (error) {
112
+ console.warn(error.message);
113
+ return (
114
+ <UnhandledResourceDataStructure resourceName="MedicationKnowledge" />
115
+ );
116
+ }
117
+
118
+ const {
119
+ id,
120
+ code,
121
+ status,
122
+ manufacturer,
123
+ amount,
124
+ synonym,
125
+ hasExtensions,
126
+ usdfPriorAuthorization,
127
+ usdfStepTherapyLimit,
128
+ usdfQuantityLimit,
129
+ usdfPlanID,
130
+ usdfDrugTierID,
131
+ } = fhirResourceData;
132
+
133
+ let amountDisplay = '';
134
+ if (amount && amount.value) {
135
+ amountDisplay = amount.value;
136
+ amountDisplay = amount.unit
137
+ ? `${amountDisplay} ${amount.unit}`
138
+ : amountDisplay;
139
+ }
140
+
141
+ return (
142
+ <Root name="MedicationKnowledge">
143
+ <Header>
144
+ <Title>
145
+ {id ? `Medication knowledge ID: ${id}` : 'Medication knowledge'}{' '}
146
+ {status && <Badge data-testid="status">{status}</Badge>}
147
+ </Title>
148
+ </Header>
149
+ <Body>
150
+ {code && (
151
+ <Value label="Code" data-testid="code">
152
+ <CodeableConcept fhirData={code} />
153
+ </Value>
154
+ )}
155
+ {manufacturer && (
156
+ <Value label="Manufacturer" data-testid="manufacturer">
157
+ <Reference fhirData={manufacturer} />
158
+ </Value>
159
+ )}
160
+ {amountDisplay && (
161
+ <Value label="Amount" data-testid="amount">
162
+ {amountDisplay}
163
+ </Value>
164
+ )}
165
+ {synonym && (
166
+ <Value label="Synonym" data-testid="synonym">
167
+ {synonym}
168
+ </Value>
169
+ )}
170
+
171
+ {hasExtensions && (
172
+ <ValueSection label="USDF extensions" data-testid="usdfExtensions">
173
+ {isBoolean(usdfPriorAuthorization) && (
174
+ <Value
175
+ label="Prior Authorization"
176
+ data-testid="usdfPriorAuthorization"
177
+ >
178
+ {usdfPriorAuthorization === true ? 'yes' : 'no'}
179
+ </Value>
180
+ )}
181
+ {isBoolean(usdfStepTherapyLimit) && (
182
+ <Value
183
+ label="Step Therapy Limit"
184
+ data-testid="usdfStepTherapyLimit"
185
+ >
186
+ {usdfStepTherapyLimit === true ? 'yes' : 'no'}
187
+ </Value>
188
+ )}
189
+ {isBoolean(usdfQuantityLimit) && (
190
+ <Value label="Quantity Limit" data-testid="usdfQuantityLimit">
191
+ {usdfQuantityLimit === true ? 'yes' : 'no'}
192
+ </Value>
193
+ )}
194
+ {usdfPlanID && (
195
+ <Value label="Plan ID" data-testid="usdfPlanID">
196
+ {usdfPlanID}
197
+ </Value>
198
+ )}
199
+ {usdfDrugTierID && (
200
+ <Value label="Drug Tier ID" data-testid="usdfDrugTierID">
201
+ <CodeableConcept fhirData={usdfDrugTierID} />
202
+ </Value>
203
+ )}
204
+ </ValueSection>
205
+ )}
206
+ </Body>
207
+ </Root>
208
+ );
209
+ };
210
+
211
+ MedicationKnowledge.propTypes = {
212
+ fhirResource: PropTypes.shape({}).isRequired,
213
+ fhirVersion: PropTypes.oneOf([fhirVersions.R4]).isRequired,
214
+ withDaVinciPDex: PropTypes.bool,
215
+ };
216
+
217
+ export default MedicationKnowledge;
@@ -0,0 +1,78 @@
1
+ import React from 'react';
2
+ import { object } from '@storybook/addon-knobs';
3
+
4
+ import MedicationKnowledge from './MedicationKnowledge';
5
+ import fhirVersions from '../fhirResourceVersions';
6
+
7
+ import example1R4 from '../../../fixtures/r4/resources/medicationKnowledge/example1.json';
8
+ import example2R4 from '../../../fixtures/r4/resources/medicationKnowledge/example2.json';
9
+ import example3R4 from '../../../fixtures/r4/resources/medicationKnowledge/example3.json';
10
+ import example4R4 from '../../../fixtures/r4/resources/medicationKnowledge/example4.json';
11
+
12
+ export default {
13
+ title: 'MedicationKnowledge',
14
+ };
15
+
16
+ export const DefaultVisualizationR4 = () => {
17
+ const fhirResource = object('Resource', example1R4);
18
+ return (
19
+ <MedicationKnowledge
20
+ fhirVersion={fhirVersions.R4}
21
+ fhirResource={fhirResource}
22
+ />
23
+ );
24
+ };
25
+ export const ExampleR4WithoutDaVinciPDex = () => {
26
+ const fhirResource = object('Resource', example2R4);
27
+ return (
28
+ <MedicationKnowledge
29
+ fhirVersion={fhirVersions.R4}
30
+ fhirResource={fhirResource}
31
+ />
32
+ );
33
+ };
34
+ export const ExampleR4WithDaVinciPDex = () => {
35
+ const fhirResource = object('Resource', example2R4);
36
+ return (
37
+ <MedicationKnowledge
38
+ fhirVersion={fhirVersions.R4}
39
+ fhirResource={fhirResource}
40
+ withDaVinciPDex
41
+ />
42
+ );
43
+ };
44
+ export const Example2R4 = () => {
45
+ const fhirResource = object('Resource', example3R4);
46
+ return (
47
+ <MedicationKnowledge
48
+ fhirVersion={fhirVersions.R4}
49
+ fhirResource={fhirResource}
50
+ />
51
+ );
52
+ };
53
+
54
+ export const Example3R4WithDaVinciPDex = () => {
55
+ const fhirResource = object('Resource', example4R4);
56
+ return (
57
+ <MedicationKnowledge
58
+ fhirVersion={fhirVersions.R4}
59
+ fhirResource={fhirResource}
60
+ withDaVinciPDex
61
+ />
62
+ );
63
+ };
64
+
65
+ export const ExampleWithoutFHIRVersionProperty = () => {
66
+ const fhirResource = object('Resource', example3R4);
67
+ return <MedicationKnowledge fhirResource={fhirResource} />;
68
+ };
69
+
70
+ export const ExampleWithUnsupportedFHIRVersionProperty = () => {
71
+ const fhirResource = object('Resource', example4R4);
72
+ return (
73
+ <MedicationKnowledge
74
+ fhirVersion={fhirVersions.DSTU2}
75
+ fhirResource={fhirResource}
76
+ />
77
+ );
78
+ };
@@ -0,0 +1,69 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+
4
+ import { fhirVersions } from '../../../index';
5
+
6
+ import MedicationKnowledge from './MedicationKnowledge';
7
+
8
+ import example1R4 from '../../../fixtures/r4/resources/medicationKnowledge/example1.json';
9
+ import example2R4 from '../../../fixtures/r4/resources/medicationKnowledge/example2.json';
10
+
11
+ describe('should render MedicationKnowledge component properly', () => {
12
+ it('should render with R4 source data', () => {
13
+ const defaultProps = {
14
+ fhirResource: example1R4,
15
+ fhirVersion: fhirVersions.R4,
16
+ };
17
+
18
+ const { container, getByTestId } = render(
19
+ <MedicationKnowledge {...defaultProps} />,
20
+ );
21
+ expect(container).not.toBeNull();
22
+
23
+ expect(getByTestId('title').textContent).toContain('example');
24
+ expect(getByTestId('status').textContent).toContain('active');
25
+ expect(getByTestId('code').textContent).toContain('Vancomycin');
26
+ expect(getByTestId('manufacturer').textContent).toContain('#org4');
27
+ expect(getByTestId('amount').textContent).toContain('50');
28
+ expect(getByTestId('synonym').textContent).toContain('Vancomycin');
29
+ });
30
+
31
+ it('should render R4 without daVinci PDex profile', () => {
32
+ const defaultProps = {
33
+ fhirResource: example2R4,
34
+ fhirVersion: fhirVersions.R4,
35
+ };
36
+
37
+ const { container, getByTestId, queryByTestId } = render(
38
+ <MedicationKnowledge {...defaultProps} />,
39
+ );
40
+ expect(container).not.toBeNull();
41
+
42
+ expect(getByTestId('code').textContent).toContain('ibuprofen');
43
+ expect(queryByTestId('usdfExtensions')).toBeNull();
44
+ });
45
+
46
+ it('should render R4 with daVinci PDex profile', () => {
47
+ const defaultProps = {
48
+ fhirResource: example2R4,
49
+ fhirVersion: fhirVersions.R4,
50
+ withDaVinciPDex: true,
51
+ };
52
+
53
+ const { container, getByTestId, queryByTestId } = render(
54
+ <MedicationKnowledge {...defaultProps} />,
55
+ );
56
+ expect(container).not.toBeNull();
57
+
58
+ expect(getByTestId('code').textContent).toContain('ibuprofen');
59
+
60
+ expect(queryByTestId('usdfExtensions')).not.toBeNull();
61
+ expect(getByTestId('usdfPriorAuthorization').textContent).toContain('no');
62
+ expect(getByTestId('usdfStepTherapyLimit').textContent).toContain('no');
63
+ expect(getByTestId('usdfQuantityLimit').textContent).toContain('no');
64
+ expect(getByTestId('usdfPlanID').textContent).toContain('Kansas');
65
+ expect(getByTestId('usdfDrugTierID').textContent).toContain(
66
+ '(preferred-generic)',
67
+ );
68
+ });
69
+ });
@@ -0,0 +1,3 @@
1
+ import MedicationKnowledge from './MedicationKnowledge';
2
+
3
+ export default MedicationKnowledge;
@@ -0,0 +1,8 @@
1
+ const getExtension = (key, extensions) => {
2
+ const result = extensions.find(item => item.url && item.url.includes(key));
3
+ return Boolean(result) ? result : null;
4
+ };
5
+
6
+ const isBoolean = value => value === true || value === false;
7
+
8
+ export { getExtension, isBoolean };
@@ -28,7 +28,7 @@ describe('should render MedicationRequest component properly', () => {
28
28
  'Take one tablet',
29
29
  );
30
30
  expect(getByTestId('requester').textContent).toContain('Patrick Pump');
31
- expect(getByTestId('created').textContent).toEqual('2015-03-01');
31
+ expect(getByTestId('created').textContent).toEqual('3/1/2015');
32
32
  expect(getByTestId('intent').textContent).toEqual('order');
33
33
  });
34
34
  it('should render with STU3 source data in which medicationReference key does not exist', () => {
@@ -59,7 +59,7 @@ describe('should render MedicationRequest component properly', () => {
59
59
  'Take one tablet',
60
60
  );
61
61
  expect(getByTestId('requester').textContent).toContain('Patrick Pump');
62
- expect(getByTestId('created').textContent).toEqual('2015-03-01');
62
+ expect(getByTestId('created').textContent).toEqual('3/1/2015');
63
63
  expect(getByTestId('intent').textContent).toEqual('order');
64
64
  });
65
65
 
@@ -79,7 +79,7 @@ describe('should render MedicationRequest component properly', () => {
79
79
  'Take 4 tablets daily',
80
80
  );
81
81
  expect(getByTestId('requester').textContent).toContain('Patrick Pump');
82
- expect(getByTestId('created').textContent).toEqual('2015-01-15');
82
+ expect(getByTestId('created').textContent).toEqual('1/15/2015');
83
83
  expect(getByTestId('intent').textContent).toEqual('order');
84
84
  });
85
85
 
@@ -101,7 +101,7 @@ describe('should render MedicationRequest component properly', () => {
101
101
  '6 mg PO daily for remission',
102
102
  );
103
103
  expect(getByTestId('requester').textContent).toContain('Patrick Pump');
104
- expect(getByTestId('created').textContent).toEqual('2015-01-15');
104
+ expect(getByTestId('created').textContent).toEqual('1/15/2015');
105
105
  expect(getByTestId('intent').textContent).toEqual('order');
106
106
  });
107
107
  });
@@ -2,16 +2,17 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
 
4
4
  import _get from 'lodash/get';
5
- import _isFinite from 'lodash/isFinite';
5
+ import _isEmpty from 'lodash/isEmpty';
6
+ import Accordion from '../../containers/Accordion';
6
7
  import Coding from '../../datatypes/Coding';
7
8
  import Date from '../../datatypes/Date';
8
9
  import ObservationGraph from './ObservationGraph';
9
10
  import {
10
11
  Root,
11
12
  Header,
12
- Title,
13
13
  Badge,
14
14
  BadgeSecondary,
15
+ ValueUnit,
15
16
  Body,
16
17
  Value,
17
18
  } from '../../ui';
@@ -23,6 +24,7 @@ const Observation = props => {
23
24
  const codeCodingDisplay = _get(fhirResource, 'code.coding.0.display');
24
25
  const codeText = _get(fhirResource, 'code.text', '');
25
26
  const valueQuantityValue = _get(fhirResource, 'valueQuantity.value', '');
27
+ const issued = _get(fhirResource, 'issued', '');
26
28
  const valueQuantityUnit = _get(fhirResource, 'valueQuantity.unit', '');
27
29
  const status = _get(fhirResource, 'status', '');
28
30
  const valueCodeableConceptText = _get(
@@ -41,68 +43,84 @@ const Observation = props => {
41
43
 
42
44
  let valueQuantityValueNumber = valueQuantityValue;
43
45
 
44
- if (
45
- _isFinite(Number(props.digitsToRoundForQuantity)) &&
46
- valueQuantityValue !== '' &&
47
- _isFinite(Number(valueQuantityValue))
48
- ) {
49
- valueQuantityValueNumber = Number(valueQuantityValue).toFixed(
50
- props.digitsToRoundForQuantity,
51
- );
52
- }
53
-
54
- const valueQuantityString = `${valueQuantityValueNumber}${valueQuantityUnit}`.trim();
55
46
  const subject = _get(fhirResource, 'subject');
47
+ const tableData = [
48
+ {
49
+ label: 'Issued on',
50
+ testId: 'issuedOn',
51
+ data: effectiveDate && <Date fhirData={effectiveDate} isBlack />,
52
+ status: effectiveDate,
53
+ },
54
+ {
55
+ label: 'Subject',
56
+ testId: 'subject',
57
+ data: subject && <Reference fhirData={subject} />,
58
+ status: subject,
59
+ },
60
+ {
61
+ label: 'Coding',
62
+ testId: 'coding',
63
+ data: valueCodeableConceptCoding.map((coding, i) => (
64
+ <Coding fhirData={coding} key={`value-coding-${i}`} />
65
+ )),
66
+ status: !_isEmpty(valueCodeableConceptCoding),
67
+ },
68
+ ];
56
69
 
57
70
  return (
58
71
  <Root name="Observation">
59
- <Header>
60
- <Title>
61
- {codeCodingDisplay || codeText}
62
- {valueQuantityString && (
63
- <>
64
- &nbsp;
65
- <code data-testid="valueQuantity">{valueQuantityString}</code>
66
- </>
67
- )}
68
- </Title>
69
- {status && <Badge data-testid="status">{status}</Badge>}
70
- {(valueCodeableConceptText || valueCodeableConceptCodingDisplay) && (
71
- <BadgeSecondary data-testid="secondaryStatus">
72
- {valueCodeableConceptText || valueCodeableConceptCodingDisplay}
73
- </BadgeSecondary>
74
- )}
75
- </Header>
76
- <Body>
77
- <ObservationGraph
78
- valueQuantity={fhirResource.valueQuantity}
79
- referenceRange={fhirResource.referenceRange}
80
- />
81
- {effectiveDate && (
82
- <Value label="Issued on" data-testid="issuedOn">
83
- <Date fhirData={effectiveDate} />
84
- </Value>
85
- )}
86
- {subject && (
87
- <Value label="Subject" data-testid="subject">
88
- <Reference fhirData={subject} />
89
- </Value>
90
- )}
91
- {valueCodeableConceptCoding.map((coding, i) => (
92
- <Coding fhirData={coding} key={`value-coding-${i}`} />
93
- ))}
94
- </Body>
72
+ <Accordion
73
+ headerContent={
74
+ <Header
75
+ resourceName={fhirResource.resourceType}
76
+ additionalContent={
77
+ issued && (
78
+ <Value label="Start date" data-testid="headerStartDate">
79
+ <Date fhirData={issued} isBlack />
80
+ </Value>
81
+ )
82
+ }
83
+ prefixBadge={
84
+ <ValueUnit
85
+ valueQty={valueQuantityValueNumber}
86
+ valueUnit={valueQuantityUnit}
87
+ />
88
+ }
89
+ additionalBadge={
90
+ (valueCodeableConceptText ||
91
+ valueCodeableConceptCodingDisplay) && (
92
+ <BadgeSecondary data-testid="secondaryStatus">
93
+ {valueCodeableConceptText ||
94
+ valueCodeableConceptCodingDisplay}
95
+ </BadgeSecondary>
96
+ )
97
+ }
98
+ badges={status && <Badge data-testid="status">{status}</Badge>}
99
+ title={codeCodingDisplay || codeText}
100
+ rightAdditionalContent={
101
+ <ObservationGraph
102
+ valueQuantity={fhirResource.valueQuantity}
103
+ referenceRange={fhirResource.referenceRange}
104
+ small
105
+ />
106
+ }
107
+ />
108
+ }
109
+ bodyContent={
110
+ <Body tableData={tableData} reverseContent>
111
+ <ObservationGraph
112
+ valueQuantity={fhirResource.valueQuantity}
113
+ referenceRange={fhirResource.referenceRange}
114
+ />
115
+ </Body>
116
+ }
117
+ />
95
118
  </Root>
96
119
  );
97
120
  };
98
121
 
99
122
  Observation.propTypes = {
100
123
  fhirResource: PropTypes.shape({}).isRequired,
101
- digitsToRoundForQuantity: PropTypes.number,
102
- };
103
-
104
- Observation.defaultProps = {
105
- digitsToRoundForQuantity: 2,
106
124
  };
107
125
 
108
126
  export default Observation;
@@ -62,14 +62,14 @@ describe('should render component correctly', () => {
62
62
  );
63
63
  expect(getByTestId('status').textContent).toEqual('final');
64
64
  expect(getByTestId('secondaryStatus').textContent).toEqual('YES');
65
- expect(getByTestId('issuedOn').textContent).toEqual('2016-05-18');
65
+ expect(getByTestId('issuedOn').textContent).toEqual('5/18/2016');
66
66
  expect(getByTestId('subject').textContent).toContain('Patient/infant');
67
67
  expect(queryByText(/373066001/g)).not.toBeNull();
68
68
  });
69
69
 
70
- test('should round the quantity to default value of digitsToRoundForQuantity props ', () => {
70
+ test('should display not rounded value', () => {
71
71
  const resource = example1ObservationExcessR4;
72
- resource.valueQuantity.value = 6.43534535434;
72
+ resource.valueQuantity.value = 6.443;
73
73
 
74
74
  const defaultProps = {
75
75
  fhirResource: example1ObservationExcessR4,
@@ -77,20 +77,8 @@ describe('should render component correctly', () => {
77
77
  const { getByTestId } = render(<Observation {...defaultProps} />);
78
78
 
79
79
  expect(getByTestId('valueQuantity')).not.toBeNull();
80
- expect(getByTestId('valueQuantity').textContent).toEqual('6.44mmol/l');
81
- });
82
-
83
- test('should round the quantity to specific value of digitsToRoundForQuantity props ', () => {
84
- const resource = example1ObservationExcessR4;
85
- resource.valueQuantity.value = 6.43534535434;
86
-
87
- const defaultProps = {
88
- fhirResource: example1ObservationExcessR4,
89
- digitsToRoundForQuantity: 3,
90
- };
91
- const { getByTestId } = render(<Observation {...defaultProps} />);
92
-
93
- expect(getByTestId('valueQuantity')).not.toBeNull();
94
- expect(getByTestId('valueQuantity').textContent).toEqual('6.435mmol/l');
80
+ expect(getByTestId('valueQuantity').textContent).toEqual('6.443');
81
+ expect(getByTestId('valueQuantityUnit')).not.toBeNull();
82
+ expect(getByTestId('valueQuantityUnit').textContent).toEqual('mmol/l');
95
83
  });
96
84
  });