Skip to content

Commit

Permalink
feat: Add encounter care team to ecr viewer (#2988)
Browse files Browse the repository at this point in the history
* fix: update fhir-converter service to point to branch

* feat: add encounter care team table

* fix: unique ids

* test: update snapshot

* fix: plumb through date

* fix: remove status

* test: update snapshots

* fix: make metadata optional

* test: table value logic

* test: add snapshot for table

* fix: cleanup

* fix: handle missing name

* test: update snapshot

* Update containers/fhir-converter/Dockerfile
  • Loading branch information
mcmcgrath13 authored Dec 9, 2024
1 parent f414c65 commit 71feb4c
Show file tree
Hide file tree
Showing 17 changed files with 476 additions and 33 deletions.
1 change: 1 addition & 0 deletions containers/ecr-viewer/src/app/api/fhirPath.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ facilityZipCode: "Bundle.entry.resource.where(resourceType = 'Location')[0].addr

compositionEncounterRef: "Bundle.entry.resource.where(resourceType = 'Composition').encounter.reference"
encounterIndividualRef: "Encounter.participant.where(type.coding.code = 'ATND').individual.reference"
encounterParticipants: "Encounter.participant"

rrDetails: "Bundle.entry.resource.where(meta.profile = 'http://hl7.org/fhir/us/ecr/StructureDefinition/rr-reportability-information-observation')"
rckmsTriggerSummaries: "Bundle.entry.resource.where(meta.profile = 'http://hl7.org/fhir/us/ecr/StructureDefinition/rr-reportability-information-observation').extension.where(url = 'http://hl7.org/fhir/us/ecr/StructureDefinition/us-ph-determination-of-reportability-rule-extension').valueString"
Expand Down
67 changes: 65 additions & 2 deletions containers/ecr-viewer/src/app/services/evaluateFhirDataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,22 @@ import {
} from "fhir/r4";
import { evaluate } from "@/app/view-data/utils/evaluate";
import * as dateFns from "date-fns";
import { PathMappings, evaluateData } from "../view-data/utils/utils";
import { PathMappings, evaluateData, noData } from "../view-data/utils/utils";
import {
TableRow,
formatAddress,
formatContactPoint,
formatName,
formatPhoneNumber,
formatStartEndDate,
formatStartEndDateTime,
} from "./formatService";
import fhirpath_r4_model from "fhirpath/fhir-context/r4";
import { Element } from "fhir/r4";
import { DisplayDataProps } from "@/app/view-data/components/DataDisplay";
import { evaluateTravelHistoryTable } from "./socialHistoryService";
import { Path } from "fhirpath";
import { returnTableFromJson } from "../view-data/components/common";

/**
* Evaluates patient name from the FHIR bundle and formats it into structured data for display.
Expand Down Expand Up @@ -371,6 +374,11 @@ export const evaluateEncounterData = (
title: "Encounter Diagnosis",
value: evaluateEncounterDiagnosis(fhirBundle, mappings),
},
{
title: "Encounter Care Team",
value: evaluateEncounterCareTeamTable(fhirBundle, mappings),
table: true,
},
];
return evaluateData(encounterData);
};
Expand Down Expand Up @@ -440,7 +448,6 @@ export const evaluateFacilityData = (
];
return evaluateData(facilityData);
};

/**
* Evaluates provider data from the FHIR bundle and formats it into structured data for display.
* @param fhirBundle - The FHIR bundle containing provider data.
Expand Down Expand Up @@ -521,6 +528,62 @@ export const evaluateProviderData = (
return evaluateData(providerData);
};

/**
* Evaluates provider data from the FHIR bundle and formats it into structured data for display.
* @param fhirBundle - The FHIR bundle containing provider data.
* @param mappings - The object containing the fhir paths.
* @returns An array of evaluated and formatted provider data.
*/
export const evaluateEncounterCareTeamTable = (
fhirBundle: Bundle,
mappings: PathMappings,
) => {
const encounterRef: string | undefined = evaluate(
fhirBundle,
mappings["compositionEncounterRef"],
)[0];
const encounter: Encounter = evaluateReference(
fhirBundle,
mappings,
encounterRef ?? "",
);
const participants = evaluate(encounter, mappings["encounterParticipants"]);

const tables = participants.map((participant) => {
const role = evaluateValue(participant, "type");
const { start, end } = evaluate(participant, "period")?.[0] ?? {};
const { practitioner } = evaluatePractitionerRoleReference(
fhirBundle,
mappings,
participant.individual.reference,
);

return {
Name: {
value:
formatName(
practitioner?.name?.[0].given,
practitioner?.name?.[0].family,
practitioner?.name?.[0].prefix,
practitioner?.name?.[0].suffix,
) || noData,
},
Role: {
value: role || noData,
},
Dates: {
value: formatStartEndDate(start, end) || noData,
},
} as TableRow;
});

return returnTableFromJson(
{ resultName: "Encounter Care Team", tables: [tables] },
true,
"caption-data-title margin-y-0",
);
};

/**
* Evaluates emergency contact information from the FHIR bundle and formats it into a readable string.
* @param fhirBundle - The FHIR bundle containing patient information.
Expand Down
29 changes: 24 additions & 5 deletions containers/ecr-viewer/src/app/services/formatService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface Metadata {
export interface TableRow {
[key: string]: {
value: any;
metadata: Metadata;
metadata?: Metadata;
};
}

Expand Down Expand Up @@ -253,13 +253,32 @@ export const formatPhoneNumber = (
* @returns A string with the formatted start and end times, each on a new line.
*/
export const formatStartEndDateTime = (
startDateTime: string,
endDateTime: string,
startDateTime: string | undefined,
endDateTime: string | undefined,
) => formatStartEnd(startDateTime, endDateTime, formatDateTime);

/**
* Formats the provided start and end date strings and returns a formatted string
* with both the start and end dates. Each date is labeled and separated by a carriage return
* and newline for clarity in display or further processing.
* @param startDate - The start date-time string to be formatted.
* @param endDate - The end date-time string to be formatted.
* @returns A string with the formatted start and end times, each on a new line.
*/
export const formatStartEndDate = (
startDate: string | undefined,
endDate: string | undefined,
) => formatStartEnd(startDate, endDate, formatDate);

const formatStartEnd = (
start: string | undefined,
end: string | undefined,
formatFn: (dt: string | undefined) => string | undefined,
) => {
const textArray: String[] = [];

const startDateObject = formatDateTime(startDateTime);
const endDateObject = formatDateTime(endDateTime);
const startDateObject = formatFn(start);
const endDateObject = formatFn(end);

if (startDateObject) {
textArray.push(`Start: ${startDateObject}`);
Expand Down
18 changes: 18 additions & 0 deletions containers/ecr-viewer/src/app/tests/components/Encounter.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ describe("Encounter", () => {
title: "Encounter ID",
value: "123456789",
},
{
title: "Encounter Care Team",
table: true,
value: (
<table>
<tr>
<th>Name</th>
<th>Role</th>
<th>Dates</th>
</tr>
<tr>
<td>Test</td>
<td>ATND</td>
<td>Start: 1/2/2023</td>
</tr>
</table>
),
},
];
const facilityData = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,25 @@ exports[`Snapshot test for Accordion Content Given no data, info message for emp
class="section__line_gray"
/>
</div>
<div>
<div
class="grid-row"
>
<div
class="data-title padding-right-1"
>
Encounter Care Team
</div>
<div
class="grid-col maxw7 text-pre-line p-list text-italic text-base"
>
No data
</div>
</div>
<div
class="section__line_gray"
/>
</div>
</div>
</div>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ exports[`Snapshot test for Procedures (Treatment Details) should match snapshot
<div
data-testid="treatment-details"
>
<div>
<div
class="grid-row"
>
<div
class="grid-col-auto width-full text-pre-line"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,9 @@ End: 05/13/2022 9:57 AM UTC
<div
class="margin-top-0"
>
<div>
<div
class="grid-row"
>
<div
class="grid-col-auto width-full text-pre-line"
>
Expand All @@ -301,7 +303,9 @@ End: 05/13/2022 9:57 AM UTC
<div
class="margin-top-0"
>
<div>
<div
class="grid-row"
>
<div
class="grid-col-auto width-full text-pre-line"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,41 @@ exports[`Encounter should match snapshot 1`] = `
class="section__line_gray"
/>
</div>
<div
class="grid-row"
>
<div
class="grid-col-auto width-full text-pre-line"
>
<table>
<tr>
<th>
Name
</th>
<th>
Role
</th>
<th>
Dates
</th>
</tr>
<tr>
<td>
Test
</td>
<td>
ATND
</td>
<td>
Start: 1/2/2023
</td>
</tr>
</table>
</div>
<div
class="section__line_gray"
/>
</div>
</div>
</div>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ exports[`LabInfo when labResults is DisplayDataProps[] should match snapshot tes
<div
data-testid="lab-results"
>
<div>
<div
class="grid-row"
>
<div
class="grid-col-auto width-full text-pre-line"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Evaluate Encounter Care Team should return the correct Encounter care team 1`] = `
<BuildTable
caption="Encounter Care Team"
className="caption-normal-weight margin-bottom-2 caption-data-title margin-y-0"
fixed={false}
headers={
[
<th
className="tableHeader bg-gray-5 minw-10"
scope="col"
>
Name
</th>,
<th
className="tableHeader bg-gray-5 minw-10"
scope="col"
>
Role
</th>,
<th
className="tableHeader bg-gray-5 minw-10"
scope="col"
>
Dates
</th>,
]
}
outerBorder={true}
tableRows={
[
<tr>
<td>
<span
className="no-data text-italic text-base"
>
No data
</span>
</td>
<td>
ATND
</td>
<td>
<span
className="no-data text-italic text-base"
>
No data
</span>
</td>
</tr>,
]
}
/>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
evaluatePatientAddress,
evaluatePatientName,
evaluateDemographicsData,
evaluateEncounterCareTeamTable,
} from "@/app/services/evaluateFhirDataService";
import { Bundle, Patient } from "fhir/r4";
import BundleWithMiscNotes from "@/app/tests/assets/BundleMiscNotes.json";
Expand Down Expand Up @@ -218,6 +219,17 @@ describe("Evaluate Encounter ID", () => {
});
});

describe("Evaluate Encounter Care Team", () => {
it("should return the correct Encounter care team", () => {
const actual = evaluateEncounterCareTeamTable(
BundleWithEcrMetadata as unknown as Bundle,
mappings,
);

expect(actual).toMatchSnapshot();
});
});

describe("Evaluate PractitionerRoleReference", () => {
it("should return the organization and practitioner when practitioner role is found ", () => {
const actual = evaluatePractitionerRoleReference(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const DataTableDisplay: React.FC<{
? true
: item.dividerLine;
return (
<div>
<div className="grid-row">
<div className="grid-col-auto width-full text-pre-line">{item.value}</div>
{item.dividerLine ? (
<div className={`section__line_${themeColor}`} />
Expand Down
Loading

0 comments on commit 71feb4c

Please sign in to comment.