Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add encounter care team to ecr viewer #2988

Merged
merged 17 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
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
Loading