Skip to content

Commit

Permalink
Refactor condition summary (#2231)
Browse files Browse the repository at this point in the history
* add condition to ecr summary

* remove old evaluateEcrSummaryAboutTheConditionDetails

* add snomed to conditionsummary and order based on matching snomed

* add logic to expand only certain headers

* fix condition tag count

* remove the export from numConditionsText

* add border and remove extra dividing line

* fix styling

* fix spacing between the sections

* increase margin for different conditions

* add jsdocs to evaluateRuleSummaries
  • Loading branch information
BobanL authored Jul 26, 2024
1 parent 3d51a0c commit cdf3510
Show file tree
Hide file tree
Showing 8 changed files with 1,491 additions and 306 deletions.
151 changes: 91 additions & 60 deletions containers/ecr-viewer/src/app/services/ecrSummaryService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
import { DisplayDataProps } from "@/app/DataDisplay";
import { returnProblemsTable } from "@/app/view-data/components/common";
import { LabReport, evaluateLabInfoData } from "./labsService";
import { ConditionSummary } from "@/app/view-data/components/EcrSummary";
import React from "react";

/**
* ExtensionConditionCode extends the FHIR Extension interface to include a 'coding' property.
Expand Down Expand Up @@ -106,79 +108,104 @@ export const evaluateEcrSummaryEncounterDetails = (
};

/**
* Evaluates and retrieves condition details from the FHIR bundle using the provided path mappings.
* Finds all unique RCKMS rule summaries in an observation
* @param observation - FHIR Observation
* @returns Set of rule summaries
*/
const evaluateRuleSummaries = (observation: Observation): Set<string> => {
const ruleSummaries = new Set<string>();
observation.extension?.forEach((extension) => {
if (
extension.url ===
"http://hl7.org/fhir/us/ecr/StructureDefinition/us-ph-determination-of-reportability-rule-extension" &&
extension?.valueString?.trim()
) {
ruleSummaries.add(extension.valueString.trim());
}
});
return ruleSummaries;
};

/**
* Evaluates and retrieves all condition details in a bundle.
* @param fhirBundle - The FHIR bundle containing patient data.
* @param fhirPathMappings - Object containing fhir path mappings.
* @param snomedCode - The SNOMED code identifying which Reportable Condition should be displayed.
* @returns An array of condition details objects containing title and value pairs.
* @param snomedCode - The SNOMED code identifying the main snomed code.
* @returns An array of condition summary objects.
*/
export const evaluateEcrSummaryAboutTheConditionDetails = (
export const evaluateEcrSummaryConditionSummary = (
fhirBundle: Bundle,
fhirPathMappings: PathMappings,
snomedCode?: string,
): DisplayDataProps[] => {
): ConditionSummary[] => {
const rrArray: Observation[] = evaluate(
fhirBundle,
fhirPathMappings.rrDetails,
);
let conditionDisplayName: Set<string> = new Set();
let ruleSummary: Set<string> = new Set();
if (snomedCode) {
rrArray.forEach((obs) => {
const coding = obs.valueCodeableConcept?.coding?.find(
(coding) => coding.code === snomedCode,
);
if (coding) {
if (coding.display) {
conditionDisplayName.add(coding.display);
}
obs.extension?.forEach((extension) => {
if (
extension.url ===
"http://hl7.org/fhir/us/ecr/StructureDefinition/us-ph-determination-of-reportability-rule-extension" &&
extension?.valueString?.trim()
) {
ruleSummary.add(extension.valueString.trim());
}
});
}
});
}
if (conditionDisplayName.size === 0) {
const names = evaluate(fhirBundle, fhirPathMappings.rrDisplayNames);
let summaries = evaluate(
fhirBundle,
fhirPathMappings.rckmsTriggerSummaries,
const conditionsList: {
[index: string]: { ruleSummaries: Set<string>; snomedDisplay: string };
} = {};
for (const observation of rrArray) {
const coding = observation?.valueCodeableConcept?.coding?.find(
(coding) => coding.system === "http://snomed.info/sct",
);
conditionDisplayName = new Set([...names]);
ruleSummary = new Set([...summaries]);
if (coding?.code) {
const snomed = coding.code;
if (!conditionsList[snomed]) {
conditionsList[snomed] = {
ruleSummaries: new Set(),
snomedDisplay: coding.display!,
};
}

evaluateRuleSummaries(observation).forEach((ruleSummary) =>
conditionsList[snomed].ruleSummaries.add(ruleSummary),
);
}
}
return [
{
title: "Reportable Condition",
toolTip:
"Condition that caused this eCR to be sent to your jurisdiction.",
value: (
<div className={"p-list"}>
{[...conditionDisplayName].map((displayName) => (
<p key={displayName}>{displayName}</p>
))}
</div>

const conditionSummaries: ConditionSummary[] = [];
for (let conditionsListKey in conditionsList) {
const conditionSummary = {
title: conditionsList[conditionsListKey].snomedDisplay,
snomed: conditionsListKey,
conditionDetails: [
{
title: "RCKMS Rule Summary",
toolTip:
"Reason(s) that this eCR was sent for this condition. Corresponds to your jurisdiction's rules for routing eCRs in RCKMS (Reportable Condition Knowledge Management System).",
value: (
<div className={"p-list"}>
{[...conditionsList[conditionsListKey].ruleSummaries].map(
(summary) => (
<p key={summary}>{summary}</p>
),
)}
</div>
),
},
],
clinicalDetails: evaluateEcrSummaryRelevantClinicalDetails(
fhirBundle,
fhirPathMappings,
conditionsListKey,
),
},
{
title: "RCKMS Rule Summary",
toolTip:
"Reason(s) that this eCR was sent for this condition. Corresponds to your jurisdiction's rules for routing eCRs in RCKMS (Reportable Condition Knowledge Management System).",
value: (
<div className={"p-list"}>
{[...ruleSummary].map((summary) => (
<p key={summary}>{summary}</p>
))}
</div>
labDetails: evaluateEcrSummaryRelevantLabResults(
fhirBundle,
fhirPathMappings,
conditionsListKey,
false,
),
},
];
};

if (conditionSummary.snomed === snomedCode) {
conditionSummaries.unshift(conditionSummary);
} else {
conditionSummaries.push(conditionSummary);
}
}

return conditionSummaries;
};

/**
Expand Down Expand Up @@ -229,12 +256,14 @@ export const evaluateEcrSummaryRelevantClinicalDetails = (
* @param fhirBundle - The FHIR bundle containing patient data.
* @param fhirPathMappings - Object containing fhir path mappings.
* @param snomedCode - String containing the SNOMED code search parameter.
* @param lastDividerLine - Boolean to determine if a divider line should be added to the end of the lab results. Default to true
* @returns An array of lab result details objects containing title and value pairs.
*/
export const evaluateEcrSummaryRelevantLabResults = (
fhirBundle: Bundle,
fhirPathMappings: PathMappings,
snomedCode: string,
lastDividerLine: boolean = true,
): DisplayDataProps[] => {
const noData: string = "No matching lab results found in this eCR";
let resultsArray: DisplayDataProps[] = [];
Expand Down Expand Up @@ -308,7 +337,9 @@ export const evaluateEcrSummaryRelevantLabResults = (
})),
);

resultsArray.push({ dividerLine: true });
if (lastDividerLine) {
resultsArray.push({ dividerLine: true });
}
return resultsArray;
};

Expand Down
Loading

0 comments on commit cdf3510

Please sign in to comment.