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,35 +1,39 @@
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
-
7
1
  import {
8
- Root,
9
- Header,
10
- Title,
11
- Value,
2
+ Badge,
12
3
  Body,
13
- ValueSection,
4
+ Header,
5
+ MissingValue,
6
+ Root,
14
7
  Table,
15
- TableRow,
16
8
  TableCell,
17
- MissingValue,
18
- Badge,
9
+ TableRow,
10
+ Value,
11
+ ValueSection,
19
12
  } from '../../ui';
13
+
14
+ import CareTeam from './CareTeam';
15
+ import CodeableConcept from '../../datatypes/CodeableConcept';
20
16
  import Coding from '../../datatypes/Coding';
17
+ import Quantity from '../../datatypes/Quantity';
21
18
  import Date from '../../datatypes/Date';
22
- import Money from '../../datatypes/Money';
23
- import Reference from '../../datatypes/Reference';
24
- import Period from '../../datatypes/Period';
25
- import TotalSum from './TotalSum';
26
19
  import Diagnosis from './Diagnosis';
27
- import SupportingInfo from './SupportingInfo';
28
- import Items from './Items';
29
20
  import Identifier from '../../datatypes/Identifier/Identifier';
30
- import CareTeam from './CareTeam';
31
- import CodeableConcept from '../../datatypes/CodeableConcept';
21
+ import Items from './Items';
22
+ import Money from '../../datatypes/Money';
23
+ import Period from '../../datatypes/Period';
24
+ import PropTypes from 'prop-types';
25
+ import React from 'react';
26
+ import Reference from '../../datatypes/Reference';
32
27
  import Related from './Related';
28
+ import SupportingInfo from './SupportingInfo';
29
+ import TotalSum from './TotalSum';
30
+ import UnhandledResourceDataStructure from '../UnhandledResourceDataStructure';
31
+ import _get from 'lodash/get';
32
+ import fhirVersions from '../fhirResourceVersions';
33
+ import Accordion from '../../containers/Accordion';
34
+ import TotalGraph from './TotalGraph';
35
+ import PriceLabel from './PriceLabel';
36
+ import { TableHeader } from '../../ui';
33
37
 
34
38
  /**
35
39
  * @typedef ExplanationOfBenefitServiceItem
@@ -77,9 +81,10 @@ const stu3DTO = fhirResource => {
77
81
  services.map(serviceItem => {
78
82
  const coding = _get(serviceItem, 'service.coding.0');
79
83
  const servicedDate = _get(serviceItem, 'servicedDate');
84
+ const servicedPeriod = _get(serviceItem, 'servicedPeriod');
80
85
  const quantity = _get(serviceItem, 'quantity.value');
81
86
  const itemCost = _get(serviceItem, 'net');
82
- return { coding, servicedDate, quantity, itemCost };
87
+ return { coding, servicedDate, servicedPeriod, quantity, itemCost };
83
88
  });
84
89
 
85
90
  return {
@@ -123,9 +128,10 @@ const r4DTO = fhirResource => {
123
128
  services.map(serviceItem => {
124
129
  const coding = _get(serviceItem, 'productOrService.coding.0');
125
130
  const servicedDate = _get(serviceItem, 'servicedDate');
131
+ const servicedPeriod = _get(serviceItem, 'servicedPeriod');
126
132
  const quantity = _get(serviceItem, 'quantity.value');
127
133
  const itemCost = _get(serviceItem, 'net');
128
- return { coding, servicedDate, quantity, itemCost };
134
+ return { coding, servicedDate, servicedPeriod, quantity, itemCost };
129
135
  });
130
136
 
131
137
  return {
@@ -275,191 +281,267 @@ const ExplanationOfBenefit = props => {
275
281
  related,
276
282
  } = fhirResourceData;
277
283
 
284
+ const getRowItem = (item, index) =>
285
+ ('isLoaded' in item ? item.isLoaded : item.data) && (
286
+ <div
287
+ key={`details-item-${index}`}
288
+ className="col-12 col-sm-6 col-md-4 text-wrap"
289
+ >
290
+ <Value label={item.label} data-testid={item.testId} dirColumn>
291
+ {item.data}
292
+ </Value>
293
+ </div>
294
+ );
295
+
296
+ const getHeaderPrice = () => {
297
+ if (totalCost) {
298
+ return <PriceLabel totalCost={totalCost} />;
299
+ }
300
+ };
301
+
302
+ const EOBRowData = [
303
+ {
304
+ label: 'Type',
305
+ testId: 'type',
306
+ data:
307
+ hasType &&
308
+ type.map((typeItem, i) => (
309
+ <Coding key={`item-${i}`} fhirData={typeItem} />
310
+ )),
311
+ isLoaded: hasType,
312
+ },
313
+ {
314
+ label: 'Identifier',
315
+ testId: 'identifier',
316
+ data:
317
+ identifier &&
318
+ identifier.map((id, index) => (
319
+ <div key={`identifier-${index}`}>
320
+ <Identifier fhirData={id} />
321
+ </div>
322
+ )),
323
+ isLoaded: identifier,
324
+ },
325
+ {
326
+ label: 'Outcome',
327
+ testId: 'outcome',
328
+ data: outcome,
329
+ },
330
+ {
331
+ label: 'Insurer',
332
+ testId: 'insurer',
333
+ data: <Reference fhirData={insurer} />,
334
+ isLoaded: hasInsurer,
335
+ },
336
+ {
337
+ label: 'Claim provider',
338
+ testId: 'provider',
339
+ data: <Reference fhirData={provider} />,
340
+ isLoaded: provider,
341
+ },
342
+ {
343
+ label: 'Total',
344
+ testId: 'totalSum',
345
+ data: <TotalSum fhirData={total} />,
346
+ isLoaded: hasTotal,
347
+ },
348
+ {
349
+ label: 'Payment',
350
+ testId: 'payment',
351
+ data: <Money fhirData={payment} />,
352
+ isLoaded: payment,
353
+ },
354
+ {
355
+ label: 'Payee',
356
+ testId: 'payee',
357
+ data: (
358
+ <>
359
+ {payeeType && <CodeableConcept fhirData={payeeType} />}
360
+ {payeeParty && <Reference fhirData={payeeParty} />}
361
+ </>
362
+ ),
363
+ isLoaded: payeeType || payeeParty,
364
+ },
365
+ {
366
+ label: 'Billable period',
367
+ testId: 'billablePeriod',
368
+ data: <Period fhirData={billablePeriod} />,
369
+ isLoaded: billablePeriod,
370
+ },
371
+ {
372
+ label: 'Purpose',
373
+ testId: 'purpose',
374
+ data: useCode,
375
+ },
376
+ {
377
+ label: 'Patient',
378
+ testId: 'patient',
379
+ data: <Reference fhirData={patient} />,
380
+ isLoaded: patient,
381
+ },
382
+ {
383
+ label: 'Insurance',
384
+ testId: 'insurance',
385
+ data: <Reference fhirData={insurance} />,
386
+ isLoaded: insurance,
387
+ },
388
+ {
389
+ label: 'Related',
390
+ testId: 'related',
391
+ data: <Related fhirData={related} />,
392
+ isLoaded: related,
393
+ },
394
+ ];
395
+
278
396
  return (
279
397
  <Root name="ExplanationOfBenefit">
280
- <Header>
281
- <Title>{disposition}</Title>
282
- {resourceStatus && <Badge>{resourceStatus}</Badge>}
283
- </Header>
284
- <Body>
285
- {hasType && (
286
- <Value label="Type" data-testid="type">
287
- {type.map((typeItem, i) => (
288
- <Coding key={`item-${i}`} fhirData={typeItem} />
289
- ))}
290
- </Value>
291
- )}
292
- {created && (
293
- <Value label="Created" data-testid="created">
294
- {created}
295
- </Value>
296
- )}
297
- {identifier && (
298
- <Value label="Identifier" data-testid="identifier">
299
- {identifier.map((id, index) => (
300
- <div key={`identifier-${index}`}>
301
- <Identifier fhirData={id} />
398
+ <Accordion
399
+ headerContent={
400
+ <Header
401
+ resourceName="ExplanationOfBenefit"
402
+ title={
403
+ disposition ? disposition : `Explanation Of Benefit (default)`
404
+ }
405
+ badges={getHeaderPrice()}
406
+ rightAdditionalContent={
407
+ resourceStatus && <Badge>{resourceStatus}</Badge>
408
+ }
409
+ additionalContent={
410
+ created &&
411
+ created !== 'undefined' && (
412
+ <Value label="Start date" data-testid="created">
413
+ <Date fhirData={created} isBlack />
414
+ </Value>
415
+ )
416
+ }
417
+ />
418
+ }
419
+ bodyContent={
420
+ <Body>
421
+ <ValueSection
422
+ label="Details"
423
+ data-testid="details"
424
+ className="mt-3"
425
+ >
426
+ <div className="row gy-sm-3">
427
+ {EOBRowData.map((x, index) => getRowItem(x, index))}
302
428
  </div>
303
- ))}
304
- </Value>
305
- )}
306
- {outcome && (
307
- <Value label="Outcome" data-testid="outcome">
308
- {outcome}
309
- </Value>
310
- )}
311
- {hasInsurer && (
312
- <Value label="Insurer" data-testid="insurer">
313
- <Reference fhirData={insurer} />
314
- </Value>
315
- )}
316
- {provider && (
317
- <Value label="Claim provider" data-testid="provider">
318
- <Reference fhirData={provider} />
319
- </Value>
320
- )}
321
- {totalCost && (
322
- <Value label="Total cost" data-testid="totalCost">
323
- <Money fhirData={totalCost} />
324
- </Value>
325
- )}
326
- {totalBenefit && (
327
- <Value label="Total benefit" data-testid="totalBenefit">
328
- <Money fhirData={totalBenefit} />
329
- </Value>
330
- )}
331
- {hasTotal && (
332
- <Value label="Total" data-testid="totalSum">
333
- <TotalSum fhirData={total} />
334
- </Value>
335
- )}
336
- {payment && (
337
- <Value label="Payment" data-testid="payment">
338
- <Money fhirData={payment} />
339
- </Value>
340
- )}
341
- {(payeeType || payeeParty) && (
342
- <Value label="Payee" data-testid="payee">
343
- {payeeType && <CodeableConcept fhirData={payeeType} />}
344
- {payeeParty && <Reference fhirData={payeeParty} />}
345
- </Value>
346
- )}
347
- {billablePeriod && (
348
- <Value label="Billable period" data-testid="billablePeriod">
349
- <Period fhirData={billablePeriod} />
350
- </Value>
351
- )}
352
- {useCode && (
353
- <Value label="Purpose" data-testid="purpose">
354
- {useCode}
355
- </Value>
356
- )}
357
- {patient && (
358
- <Value label="Patient" data-testid="patient">
359
- <Reference fhirData={patient} />
360
- </Value>
361
- )}
362
- {insurance && (
363
- <Value label="Insurance" data-testid="insurance">
364
- <Reference fhirData={insurance} />
365
- </Value>
366
- )}
367
- {related && (
368
- <Value label="Related" data-testid="related">
369
- <Related fhirData={related} />
370
- </Value>
371
- )}
372
- {hasDiagnosis && <Diagnosis fhirData={diagnosis} />}
373
- {hasSupportingInfo && <SupportingInfo fhirData={supportingInfo} />}
429
+ </ValueSection>
430
+ {hasDiagnosis && <Diagnosis fhirData={diagnosis} />}
431
+ {hasSupportingInfo && <SupportingInfo fhirData={supportingInfo} />}
432
+ {totalCost && totalBenefit && (
433
+ <TotalGraph fhirData={{ totalCost, totalBenefit }} />
434
+ )}
374
435
 
375
- {hasServices && (
376
- <ValueSection label="Services" data-testid="hasServices">
377
- <Table>
378
- <thead>
379
- <TableRow>
380
- <TableCell>Service</TableCell>
381
- <TableCell>Service date</TableCell>
382
- <TableCell>Quantity</TableCell>
383
- <TableCell>Item cost</TableCell>
384
- </TableRow>
385
- </thead>
386
- <tbody>
387
- {services.map((serviceItem, i) => {
388
- return (
389
- <TableRow key={`serviceItem-${i}`}>
390
- <TableCell>
391
- <Coding fhirData={serviceItem.coding} />
392
- </TableCell>
393
- <TableCell>
394
- {serviceItem.servicedDate ? (
395
- <Date fhirData={serviceItem.servicedDate} />
396
- ) : (
397
- <MissingValue />
398
- )}
399
- </TableCell>
400
- <TableCell>
401
- {Number.isFinite(Number(serviceItem.quantity)) ? (
402
- serviceItem.quantity
403
- ) : (
404
- <MissingValue />
405
- )}
406
- </TableCell>
407
- <TableCell>
408
- {Number.isFinite(
409
- Number(_get(serviceItem, 'itemCost.value')),
410
- ) ? (
411
- <Money fhirData={serviceItem.itemCost} />
412
- ) : (
413
- <MissingValue />
414
- )}
415
- </TableCell>
436
+ {hasServices && (
437
+ <ValueSection
438
+ label="Services"
439
+ data-testid="hasServices"
440
+ marginTop
441
+ >
442
+ <Table>
443
+ <thead>
444
+ <TableRow>
445
+ <TableHeader>Service</TableHeader>
446
+ <TableHeader>Service date</TableHeader>
447
+ <TableHeader>Quantity</TableHeader>
448
+ <TableHeader>Item cost</TableHeader>
416
449
  </TableRow>
417
- );
418
- })}
419
- </tbody>
420
- </Table>
421
- </ValueSection>
422
- )}
423
- {hasInformation && (
424
- <ValueSection label="Information" data-testid="hasInformation">
425
- <Table>
426
- <thead>
427
- <TableRow>
428
- <TableCell />
429
- <TableCell>Status</TableCell>
430
- </TableRow>
431
- </thead>
432
- <tbody>
433
- {information.map((informationItem, i) => {
434
- const infoTitle = _get(informationItem, 'category.coding.0');
435
- const infoStatus = _get(informationItem, 'code.coding.0');
436
-
437
- return (
438
- <TableRow key={`serviceItem-${i}`}>
439
- <TableCell>
440
- {infoTitle ? (
441
- <Coding fhirData={infoTitle} />
442
- ) : (
443
- <MissingValue />
444
- )}
445
- </TableCell>
446
- <TableCell>
447
- {infoStatus ? (
448
- <Coding fhirData={infoStatus} />
449
- ) : (
450
- <MissingValue />
451
- )}
452
- </TableCell>
450
+ </thead>
451
+ <tbody className="border-top-0">
452
+ {services.map((serviceItem, i) => {
453
+ return (
454
+ <TableRow key={`serviceItem-${i}`}>
455
+ <TableCell data-testid="explanation.service">
456
+ <Coding fhirData={serviceItem.coding} />
457
+ </TableCell>
458
+ <TableCell data-testid="explanation.servicedDate">
459
+ {(serviceItem.servicedDate && (
460
+ <Date fhirData={serviceItem.servicedDate} />
461
+ )) ||
462
+ (serviceItem.servicedPeriod && (
463
+ <Period fhirData={serviceItem.servicedPeriod} />
464
+ )) || <MissingValue />}
465
+ </TableCell>
466
+ <TableCell data-testid="explanation.quantity">
467
+ {Number.isFinite(Number(serviceItem.quantity)) ? (
468
+ serviceItem.quantity
469
+ ) : (
470
+ <MissingValue />
471
+ )}
472
+ </TableCell>
473
+ <TableCell data-testid="explanation.itemCost">
474
+ {Number.isFinite(
475
+ Number(_get(serviceItem, 'itemCost.value')),
476
+ ) ? (
477
+ <Money fhirData={serviceItem.itemCost} />
478
+ ) : (
479
+ <MissingValue />
480
+ )}
481
+ </TableCell>
482
+ </TableRow>
483
+ );
484
+ })}
485
+ </tbody>
486
+ </Table>
487
+ </ValueSection>
488
+ )}
489
+ {hasInformation && (
490
+ <ValueSection
491
+ label="Information"
492
+ data-testid="hasInformation"
493
+ marginTop
494
+ >
495
+ <Table>
496
+ <thead>
497
+ <TableRow>
498
+ <TableHeader />
499
+ <TableHeader>Status</TableHeader>
453
500
  </TableRow>
454
- );
455
- })}
456
- </tbody>
457
- </Table>
458
- </ValueSection>
459
- )}
460
- {hasItems && <Items fhirData={items} />}
461
- {hasCareTeam && <CareTeam fhirData={careTeam} />}
462
- </Body>
501
+ </thead>
502
+ <tbody className="border-top-0">
503
+ {information.map((informationItem, i) => {
504
+ const infoTitle = _get(
505
+ informationItem,
506
+ 'category.coding.0',
507
+ );
508
+ const infoKey = Object.keys(informationItem).filter(
509
+ key => {
510
+ return key !== 'sequence' && key !== 'category';
511
+ },
512
+ );
513
+ const infoStatus = _get(informationItem, infoKey);
514
+ const StatusComponent =
515
+ infoKey.toString() === 'timingDate' ? Date : Quantity;
516
+
517
+ return (
518
+ <TableRow key={`serviceItem-${i}`}>
519
+ <TableCell>
520
+ {infoTitle ? (
521
+ <Coding fhirData={infoTitle} />
522
+ ) : (
523
+ <MissingValue />
524
+ )}
525
+ </TableCell>
526
+ <TableCell>
527
+ {infoStatus ? (
528
+ <StatusComponent fhirData={infoStatus} />
529
+ ) : (
530
+ <MissingValue />
531
+ )}
532
+ </TableCell>
533
+ </TableRow>
534
+ );
535
+ })}
536
+ </tbody>
537
+ </Table>
538
+ </ValueSection>
539
+ )}
540
+ {hasItems && <Items fhirData={items} />}
541
+ {hasCareTeam && <CareTeam fhirData={careTeam} />}
542
+ </Body>
543
+ }
544
+ />
463
545
  </Root>
464
546
  );
465
547
  };