fhir-react 0.2.3 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish_npmjs.yml +20 -0
- package/.storybook/config.js +9 -3
- package/.storybook/presets.js +1 -0
- package/.storybook/preview-head.html +4 -0
- package/README.md +48 -4
- package/build/bootstrap-reboot.min.css +2 -22
- package/build/index.js +38 -3
- package/build/style.css +31 -459
- package/package.json +15 -5
- package/src/assets/common/chevron-right.svg +3 -0
- package/src/assets/containers/AllergyIntolerance/allergy-intolerance.svg +9 -0
- package/src/assets/containers/Appointment/appointment.svg +14 -0
- package/src/assets/containers/CarePlan/care-plan.svg +10 -0
- package/src/assets/containers/CareTeam/care-team.svg +10 -0
- package/src/assets/containers/Claim/claim.svg +6 -0
- package/src/assets/containers/ClaimResponse/claim-response.svg +7 -0
- package/src/assets/containers/Condition/condition.svg +11 -0
- package/src/assets/containers/Device/device.svg +8 -0
- package/src/assets/containers/DiagnosticReport/diagnostic-report.svg +14 -0
- package/src/assets/containers/DocumentReference/document-reference.svg +10 -0
- package/src/assets/containers/Encounter/encounter.svg +10 -0
- package/src/assets/containers/ExplanationOfBenefit/explanation-of-benefit.svg +3 -0
- package/src/assets/containers/FamilyMemberHistory/family-member-history.svg +7 -0
- package/src/assets/containers/Goal/goal.svg +11 -0
- package/src/assets/containers/Immunization/immunization.svg +7 -0
- package/src/assets/containers/List/list.svg +3 -0
- package/src/assets/containers/Location/location.svg +4 -0
- package/src/assets/containers/Medication/medication.svg +5 -0
- package/src/assets/containers/MedicationAdministration/medication-administration.svg +6 -0
- package/src/assets/containers/MedicationKnowledge/medication-knowledge.svg +11 -0
- package/src/assets/containers/MedicationStatement/medication-statement.svg +5 -0
- package/src/assets/containers/Observation/observation.svg +12 -0
- package/src/assets/containers/Practitioner/practitioner.svg +5 -0
- package/src/assets/containers/Procedure/procedure.svg +9 -0
- package/src/assets/containers/Questionnaire/questionnaire.svg +6 -0
- package/src/assets/containers/QuestionnaireResponse/questionnaire-response.svg +6 -0
- package/src/assets/containers/QustionnaireResponse/questionnaire-response.svg +6 -0
- package/src/assets/containers/ResearchStudy/research-study.svg +9 -0
- package/src/assets/containers/ResourceCategory/resource-placeholder.svg +3 -0
- package/src/components/containers/Accordion/Accordion.js +80 -0
- package/src/components/containers/Accordion/Accordion.stories.js +76 -0
- package/src/components/containers/Accordion/index.js +3 -0
- package/src/components/containers/ResourceContainer/ResourceContainer.css +0 -1
- package/src/components/containers/ResourceContainer/ResourceContainer.js +1 -1
- package/src/components/datatypes/AccountBalance/AccountBalance.js +33 -0
- package/src/components/datatypes/AccountBalance/index.js +3 -0
- package/src/components/datatypes/Annotation/Annotation.js +1 -1
- package/src/components/datatypes/Coding/Coding.js +1 -1
- package/src/components/datatypes/Date/Date.js +14 -4
- package/src/components/datatypes/DatePeriod/DatePeriod.js +38 -0
- package/src/components/datatypes/DatePeriod/index.js +3 -0
- package/src/components/datatypes/HeaderIcon/HeaderIcon.js +31 -0
- package/src/components/datatypes/HeaderIcon/index.js +3 -0
- package/src/components/datatypes/HumanName/HumanName.js +6 -21
- package/src/components/datatypes/Reference/Reference.js +3 -6
- package/src/components/resources/AdverseEvent/AdverseEvent.test.js +2 -2
- package/src/components/resources/AllergyIntolerance/AllergyIntolerance.test.js +4 -4
- package/src/components/resources/Appointment/Appointment.js +91 -65
- package/src/components/resources/Appointment/Appointment.test.js +3 -3
- package/src/components/resources/Bundle/Bundle.js +2 -2
- package/src/components/resources/Bundle/Bundle.stories.js +78 -12
- package/src/components/resources/Bundle/Bundle.test.js +3 -0
- package/src/components/resources/CarePlan/CarePlan.test.js +4 -4
- package/src/components/resources/CareTeam/CareTeam.js +13 -14
- package/src/components/resources/CareTeam/CareTeam.test.js +4 -4
- package/src/components/resources/Claim/Claim.test.js +6 -6
- package/src/components/resources/ClaimResponse/ClaimResponse.test.js +6 -6
- package/src/components/resources/Condition/Condition.js +64 -47
- package/src/components/resources/Condition/Condition.stories.js +41 -8
- package/src/components/resources/Condition/Condition.test.js +20 -14
- package/src/components/resources/DiagnosticReport/DiagnosticReport.test.js +5 -7
- package/src/components/resources/DocumentReference/DocumentReference.js +1 -1
- package/src/components/resources/DocumentReference/DocumentReference.test.js +3 -3
- package/src/components/resources/Encounter/Encounter.js +66 -36
- package/src/components/resources/Encounter/EncounterParticipants.js +2 -2
- package/src/components/resources/ExplanationOfBenefit/CareTeam.js +2 -2
- package/src/components/resources/ExplanationOfBenefit/Diagnosis.js +31 -5
- package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.js +272 -201
- package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.stories.js +12 -0
- package/src/components/resources/ExplanationOfBenefit/ExplanationOfBenefit.test.js +96 -62
- package/src/components/resources/ExplanationOfBenefit/Items.js +2 -2
- package/src/components/resources/ExplanationOfBenefit/PriceLabel.js +20 -0
- package/src/components/resources/ExplanationOfBenefit/Related.js +3 -3
- package/src/components/resources/ExplanationOfBenefit/SupportingInfo.js +14 -3
- package/src/components/resources/ExplanationOfBenefit/TotalGraph.js +68 -0
- package/src/components/resources/ExplanationOfBenefitGraph/ExplanationOfBenefitGraph.js +89 -0
- package/src/components/resources/ExplanationOfBenefitGraph/ExplanationOfBenefitGraph.stories.js +78 -0
- package/src/components/resources/ExplanationOfBenefitGraph/ExplanationOfBenefitGraph.test.js +51 -0
- package/src/components/resources/ExplanationOfBenefitGraph/index.js +3 -0
- package/src/components/resources/Goal/Goal.test.js +1 -1
- package/src/components/resources/Immunization/Immunization.js +125 -94
- package/src/components/resources/Immunization/Immunization.stories.js +23 -4
- package/src/components/resources/Immunization/Immunization.test.js +17 -12
- package/src/components/resources/List/List.test.js +3 -3
- package/src/components/resources/MedicationAdministration/MedicationAdministration.test.js +7 -7
- package/src/components/resources/MedicationDispense/MedicationDispense.test.js +2 -2
- package/src/components/resources/MedicationRequest/MedicationRequest.test.js +4 -4
- package/src/components/resources/Observation/Observation.js +72 -54
- package/src/components/resources/Observation/Observation.test.js +6 -18
- package/src/components/resources/Observation/ObservationGraph.js +159 -55
- package/src/components/resources/Observation/ObservationGraph.test.js +47 -26
- package/src/components/resources/Patient/Patient.js +77 -87
- package/src/components/resources/Patient/Patient.test.js +1 -1
- package/src/components/resources/Practitioner/Practitioner.js +80 -60
- package/src/components/resources/Practitioner/Practitioner.test.js +4 -4
- package/src/components/resources/Procedure/Procedure.js +99 -87
- package/src/components/resources/Procedure/Procedure.stories.js +8 -6
- package/src/components/resources/Procedure/Procedure.test.js +11 -8
- package/src/components/resources/Questionnaire/Questionnaire.test.js +3 -3
- package/src/components/resources/QuestionnaireResponse/QuestionnaireResponse.test.js +5 -5
- package/src/components/resources/ReferralRequest/ReferralRequest.test.js +2 -2
- package/src/components/resources/ResearchStudy/ResearchStudy.test.js +1 -1
- package/src/components/resources/ResourceCategory/ResourceCategory.js +55 -0
- package/src/components/resources/ResourceCategory/ResourceCategory.stories.js +29 -0
- package/src/components/resources/ResourceCategory/ResourceCategory.test.js +101 -0
- package/src/components/resources/ResourceCategory/index.js +3 -0
- package/src/components/supportedFhirResourceList.js +2 -0
- package/src/components/ui/_header.scss +3 -0
- package/src/components/ui/bootstrap-reboot.min.css +2 -22
- package/src/components/ui/index.js +191 -29
- package/src/constants/badge-status.jsx +98 -0
- package/src/fixtures/dstu2/resources/condition/condition.svg +35 -0
- package/src/fixtures/dstu2/resources/immunization/immunization.svg +10 -0
- package/src/fixtures/example-icons.jsx +169 -0
- package/src/fixtures/r4/resources/explanationOfBenefit/c4bbExtendedDiagnosis.json +446 -0
- package/src/index.js +7 -1
- package/src/style.scss +176 -0
- package/src/utils/formatDate.js +21 -0
- package/src/utils/formatDate.test.js +22 -0
- package/src/utils/getBadgeColor.js +6 -0
- package/src/utils/getBadgeColor.test.js +14 -0
- package/src/utils/isUrl.js +9 -0
- package/src/utils/isUrl.test.js +12 -0
- package/src/utils.js +7 -0
- package/webpack.config.js +10 -1
- package/src/components/datatypes/HumanName/HumanName.css +0 -15
- package/src/components/datatypes/Reference/Reference.css +0 -8
- package/src/components/resources/Observation/ObservationGraph.css +0 -51
- package/src/components/resources/Patient/Patient.css +0 -19
- 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
|
|
12
|
-
import '
|
|
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="
|
|
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
|
|
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
|
-
<
|
|
74
|
-
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
|
90
|
+
expect(getByTestId('deceasedInfo').textContent).toEqual('2/14/2015');
|
|
91
91
|
});
|
|
92
92
|
});
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import
|
|
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
|
|
8
|
-
|
|
9
|
-
import
|
|
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
|
|
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
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
<
|
|
48
|
-
{
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
|
|
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
|
};
|