diff --git a/src/components/Landing/index.js b/src/components/Landing/index.js
index d0daff8db..5a9b64b5d 100644
--- a/src/components/Landing/index.js
+++ b/src/components/Landing/index.js
@@ -547,6 +547,7 @@ export default class Landing extends Component {
report: summary.ReportSummary,
survey: summary.SurveySummary,
}}
+ sectionFlags={sectionFlags}
>
)}
{/* other tab panel as specified here */}
diff --git a/src/components/Landing/utility.js b/src/components/Landing/utility.js
index 6c76ec083..40f7eec2b 100644
--- a/src/components/Landing/utility.js
+++ b/src/components/Landing/utility.js
@@ -26,7 +26,10 @@ export function processEndPoint(endpoint, endpointParams) {
if (!endpoint) return "";
const params = endpointParams ? endpointParams : {};
return endpoint
- .replace(`{process.env.${ENV_VAR_PREFIX}_CONF_API_URL}`, getEnvConfidentialAPIURL())
+ .replace(
+ `{process.env.${ENV_VAR_PREFIX}_CONF_API_URL}`,
+ getEnvConfidentialAPIURL()
+ )
.replace("{process.env.PUBLIC_URL}", getEnv("PUBLIC_URL"))
.replace("{patientId}", params.patientId);
}
@@ -149,7 +152,7 @@ export function getDemoData(section, params) {
}
export function getProcessedSummaryData(summary, summaryMap) {
- const sectionFlags = {};
+ let sectionFlags = {};
const sectionKeys = Object.keys(summaryMap || {});
let flaggedCount = 0;
diff --git a/src/components/Report/components/MedicationList.js b/src/components/Report/components/MedicationList.js
new file mode 100644
index 000000000..7ae797ad4
--- /dev/null
+++ b/src/components/Report/components/MedicationList.js
@@ -0,0 +1,8 @@
+import React, { Component } from "react";
+import Table from "./Table";
+
+export default class MedicationList extends Component {
+ render() {
+ return
;
+ }
+}
diff --git a/src/components/Report/components/Table.js b/src/components/Report/components/Table.js
index 64c74bb48..4696b75c6 100644
--- a/src/components/Report/components/Table.js
+++ b/src/components/Report/components/Table.js
@@ -46,9 +46,12 @@ export default class Table extends Component {
id: headerID,
Header: () => {
if (headerKey.omitHeader) return "";
+ const displayName = header.replace(/_/g, " ");
if (headerKey.header)
- return {header}
;
- return {header};
+ return {displayName}
;
+ return (
+ {displayName}
+ );
},
accessor: (entry) => {
let value = entry[headerKey];
@@ -64,7 +67,9 @@ export default class Table extends Component {
return (
{value
- ? value
+ ? typeof value === "object"
+ ? value.toString()
+ : value
: headerKey.default
? headerKey.default
: entry[headerKey.key]}
diff --git a/src/components/Report/index.js b/src/components/Report/index.js
index a71c75edf..46568337b 100644
--- a/src/components/Report/index.js
+++ b/src/components/Report/index.js
@@ -8,6 +8,7 @@ import SideNav from "../SideNav";
import Version from "../../elements/Version";
import reportSummarySections from "../../config/report_config";
import {
+ dedupArrObjects,
getQuestionnaireDescription,
getQuestionnaireTitle,
isEmptyArray,
@@ -100,6 +101,55 @@ export default class Report extends Component {
);
}
+ getSectionFlags(section) {
+ if (isEmptyArray(section.flags)) return null;
+ const sectionFlags = this.props.sectionFlags;
+ if (!sectionFlags) return null;
+ return dedupArrObjects(
+ section.flags
+ .map((o) => {
+ if (
+ sectionFlags[o.parentKey] &&
+ sectionFlags[o.parentKey][o.dataKey]
+ ) {
+ return sectionFlags[o.parentKey][o.dataKey];
+ }
+ return null;
+ })
+ .filter((o) => !!o)
+ .flat()
+ .map((o) => {
+ return {
+ flagText: o.flagText,
+ flagClass: o.flagClass,
+ };
+ }),
+ "flagText"
+ );
+ }
+ renderFlagIconsInHeader(section) {
+ const flagObj = this.getSectionFlags(section);
+ if (isEmptyArray(flagObj)) return null;
+ return (
+
+ {flagObj.map((o, index) => {
+ return (
+
+
+
+ );
+ })}
+
+ );
+ }
renderSectionBody(summaryData, section) {
const surveySummaryData = reportUtil.getSurveySummaryData(summaryData);
const scoringData = this.getScoringData(surveySummaryData);
@@ -115,6 +165,9 @@ export default class Report extends Component {
bodyDiagramData: bodyDiagramData,
procedureData: procedureData,
referralData: referralData,
+ reportData: reportData,
+ medicationListData: reportUtil.getMedicationListData(reportData),
+ sectionFlags: this.props.sectionFlags,
};
if (section.component) {
return {section.component(propData)}
;
@@ -142,6 +195,7 @@ export default class Report extends Component {
surveyData: matchedData,
})}
{this.renderSubSectionAnchor(item)}
+ {this.renderSubSectionFlags(item)}
);
})}
@@ -169,10 +223,30 @@ export default class Report extends Component {
>
{this.renderSubSectionTitle(item, summaryData)}
{this.renderSubSectionInfo(item, summaryData)}
+ {this.renderFlagIconsInHeader(item)}
);
}
+ renderSubSectionFlags(section) {
+ const flagObj = this.getSectionFlags(section);
+ if (isEmptyArray(flagObj)) return null;
+ return (
+
+ {flagObj.map((o, index) => {
+ return (
+
+
+ {o.flagText}
+
+ );
+ })}
+
+ );
+ }
renderSubSectionTitle(item, summaryData) {
const title = summaryData?.Questionnaire
? getQuestionnaireTitle(summaryData?.Questionnaire)
@@ -297,4 +371,5 @@ export default class Report extends Component {
Report.propTypes = {
summaryData: PropTypes.object,
+ sectionFlags: PropTypes.object,
};
diff --git a/src/components/Report/utility.js b/src/components/Report/utility.js
index fbc8c4070..9d25eb3bf 100644
--- a/src/components/Report/utility.js
+++ b/src/components/Report/utility.js
@@ -21,6 +21,11 @@ export function getReferralData(summaryData) {
if (!summaryData || !summaryData.TreatmentHistory) return null;
return summaryData.TreatmentHistory.Referrals;
}
+export function getMedicationListData(summaryData) {
+ if (!summaryData) return null;
+ if (summaryData.MedicationList) return summaryData.MedicationList;
+ return null;
+}
export function hasReportSummaryData(summaryData) {
if (!summaryData) return false;
let sectionData = [];
diff --git a/src/components/Summary.js b/src/components/Summary.js
index 27b6f16c8..18d7445d4 100644
--- a/src/components/Summary.js
+++ b/src/components/Summary.js
@@ -504,7 +504,11 @@ export default class Summary extends Component {
)}
-
+
);
}
@@ -556,7 +560,11 @@ export default class Summary extends Component {
{panel.alertsData.title}
{alertsContent}
-
+
);
}
diff --git a/src/components/graph/ReportOverviewGraph.js b/src/components/graph/ReportOverviewGraph.js
index 7dab6602b..f63f3c858 100644
--- a/src/components/graph/ReportOverviewGraph.js
+++ b/src/components/graph/ReportOverviewGraph.js
@@ -722,7 +722,7 @@ export default class ReportOverviewGraph extends Component {
const inYears = unit === "year";
const min = arrNum[0];
const max = arrNum[arrNum.length - 1];
- const shouldRotate = (inYears && max >= 10);
+ const shouldRotate = inYears && max >= 10;
const revArrNum = JSON.parse(JSON.stringify(arrNum)).reverse();
const arrDisplayValues = arrNum.map((item, index) => {
const prevItem = revArrNum.find(
diff --git a/src/config/report_config.js b/src/config/report_config.js
index 3221ddd1d..8cd773770 100644
--- a/src/config/report_config.js
+++ b/src/config/report_config.js
@@ -9,6 +9,7 @@ import ResponsesSummary from "../components/Report/components/ResponsesSummary";
import RankedResponses from "../components/Report/components/RankedResponses";
import Procedures from "../components/Report/components/Procedures";
import Referrals from "../components/Report/components/Referrals";
+import MedicationList from "../components/Report/components/MedicationList";
const iconProps = {
width: 35,
@@ -27,6 +28,7 @@ export const STOP_DATA_KEY = "PAINTRACKER-STOP";
export const TRT_DATA_KEY = "PAINTRACKER-TRT";
export const PROCECURE_DATA_KEY = "PROCEDURE_HISTORY";
export const REFERRAL_DATA_KEY = "REFERRAL_HISTORY";
+export const MEDICATION_LIST_DATA_KEY = "MedicationList";
const reportConfig = [
{
@@ -391,10 +393,6 @@ const reportConfig = [
),
},
+ {
+ dataKey: MEDICATION_LIST_DATA_KEY,
+ dataKeySource: "ReportSummary",
+ title: "Medications",
+ flags: [
+ {
+ parentKey: "PDMPMedications",
+ dataKey: "PDMPMedications"
+ }
+ ],
+ component: (props) => (
+
+ ),
+ },
{
dataKey: TRT_DATA_KEY,
title: "Patient-reported Treatments Questionnaire",
diff --git a/src/cql/r4/Report_LogicLibrary.cql b/src/cql/r4/Report_LogicLibrary.cql
index 4994061d3..3b127bd18 100644
--- a/src/cql/r4/Report_LogicLibrary.cql
+++ b/src/cql/r4/Report_LogicLibrary.cql
@@ -1,11 +1,15 @@
library ReportLogicLibrary version '1.0.0'
using FHIR version '4.0.0'
+// The FHIRHelpers library provides common functions for simplifying interaction w/ the FHIR R4 data model.
+include FHIRHelpers version '4.0.0' called FHIRHelpers
// -----------------------------------------------------------------------------
// PATIENT INFORMATION
// -----------------------------------------------------------------------------
context Patient
+//system url identifier used to identify resources, e.g. MedicationRequest, from PDMP
+define UWMC_SYSTEM_VALUE: 'http://www.uwmedicine.org/medication_id'
// ## Re-usable functions ##
// Returns the first-found display text for a CodeableConcept, looking first at the `text` attribute, then the
@@ -46,14 +50,20 @@ define ReferralCodeList: {
// REPORT LOGIC, e.g. Procedure, Condition, ServiceRequest
//------------------------------------------------------------------------------
+define function GetEncounterLocation(enc_id String):
+ First(([Encounter] E where E.id = enc_id) P return P.location.location.display.value)
+
define ProcedureHistory:
([Procedure] ProcList
where ProcList.status.value = 'completed' and not (ReferralCodeList contains ConceptCode(ProcList.code))) P
- let performDate: (P.performed as FHIR.dateTime).value
+ let
+ performDate: (P.performed as FHIR.dateTime).value,
+ encounterReference: if P.encounter is not null and P.encounter.reference is not null then P.encounter.reference.value else null
return {
Name: ConceptText(P.code),
Date: performDate,
DateText: DateTimeText(P.performed as FHIR.dateTime),
+ Location: if encounterReference is not null then GetEncounterLocation(Split(encounterReference, '/')[1]) else null,
CPT_CODE: ConceptCode(P.code)
}
sort by Date desc
@@ -61,18 +71,38 @@ define ProcedureHistory:
define ReferralHistory:
([Procedure] ProcList
where ProcList.status.value = 'completed' and (ReferralCodeList contains ConceptCode(ProcList.code))) P
- let performDate: (P.performed as FHIR.dateTime).value
+ let
+ performDate: (P.performed as FHIR.dateTime).value,
+ encounterReference: if P.encounter is not null and P.encounter.reference is not null then P.encounter.reference.value else null
return {
Name: ConceptText(P.code),
Date: performDate,
DateText: DateTimeText(P.performed as FHIR.dateTime),
+ Location: if encounterReference is not null then GetEncounterLocation(Split(encounterReference, '/')[1]) else null,
CPT_CODE: ConceptCode(P.code)
}
sort by Date desc
+define MedicationList:
+ [MedicationRequest] M
+ // within 2 years
+ where M.identifier[0].system = UWMC_SYSTEM_VALUE
+ and M.authoredOn.value <= Today()
+ and M.authoredOn.value >= (Today() - 2 year)
+ return {
+ Name: ConceptText(M.medication as FHIR.CodeableConcept),
+ Start: DateTimeText(M.authoredOn),
+ Dosage: M.dosageInstruction.text.value,
+ Quantity: if M.dispenseRequest is not null and M.dispenseRequest.quantity is not null then M.dispenseRequest.quantity.value.value else null,
+ Prescriber: M.requester.display.value,
+ Authored: M.authoredOn.value
+ }
+ sort by Authored desc
+
define Summary: {
TreatmentHistory: {
Procedures: ProcedureHistory,
Referrals: ReferralHistory
- }
+ },
+ MedicationList: MedicationList
}
diff --git a/src/cql/r4/Report_LogicLibrary.json b/src/cql/r4/Report_LogicLibrary.json
index 5c8e555b9..7a7dca498 100644
--- a/src/cql/r4/Report_LogicLibrary.json
+++ b/src/cql/r4/Report_LogicLibrary.json
@@ -22,6 +22,13 @@
"version" : "4.0.0"
} ]
},
+ "includes" : {
+ "def" : [ {
+ "localIdentifier" : "FHIRHelpers",
+ "path" : "FHIRHelpers",
+ "version" : "4.0.0"
+ } ]
+ },
"contexts" : {
"def" : [ {
"name" : "Patient"
@@ -38,6 +45,15 @@
"type" : "Retrieve"
}
}
+ }, {
+ "name" : "UWMC_SYSTEM_VALUE",
+ "context" : "Patient",
+ "accessLevel" : "Public",
+ "expression" : {
+ "valueType" : "{urn:hl7-org:elm-types:r1}String",
+ "value" : "http://www.uwmedicine.org/medication_id",
+ "type" : "Literal"
+ }
}, {
"name" : "ConceptText",
"context" : "Patient",
@@ -208,6 +224,155 @@
"type" : "Literal"
} ]
}
+ }, {
+ "name" : "GetEncounterLocation",
+ "context" : "Patient",
+ "accessLevel" : "Public",
+ "type" : "FunctionDef",
+ "expression" : {
+ "type" : "First",
+ "source" : {
+ "type" : "Query",
+ "source" : [ {
+ "alias" : "P",
+ "expression" : {
+ "type" : "Query",
+ "source" : [ {
+ "alias" : "E",
+ "expression" : {
+ "dataType" : "{http://hl7.org/fhir}Encounter",
+ "type" : "Retrieve"
+ }
+ } ],
+ "relationship" : [ ],
+ "where" : {
+ "type" : "Equal",
+ "operand" : [ {
+ "name" : "ToString",
+ "libraryName" : "FHIRHelpers",
+ "type" : "FunctionRef",
+ "operand" : [ {
+ "path" : "id",
+ "scope" : "E",
+ "type" : "Property"
+ } ]
+ }, {
+ "name" : "enc_id",
+ "type" : "OperandRef"
+ } ]
+ }
+ }
+ } ],
+ "relationship" : [ ],
+ "return" : {
+ "expression" : {
+ "type" : "Query",
+ "source" : [ {
+ "alias" : "$this",
+ "expression" : {
+ "type" : "Query",
+ "source" : [ {
+ "alias" : "$this",
+ "expression" : {
+ "type" : "Query",
+ "source" : [ {
+ "alias" : "$this",
+ "expression" : {
+ "path" : "location",
+ "scope" : "P",
+ "type" : "Property"
+ }
+ } ],
+ "where" : {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "path" : "location",
+ "type" : "Property",
+ "source" : {
+ "name" : "$this",
+ "type" : "AliasRef"
+ }
+ }
+ }
+ },
+ "return" : {
+ "distinct" : false,
+ "expression" : {
+ "path" : "location",
+ "type" : "Property",
+ "source" : {
+ "name" : "$this",
+ "type" : "AliasRef"
+ }
+ }
+ }
+ }
+ } ],
+ "where" : {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "path" : "display",
+ "type" : "Property",
+ "source" : {
+ "name" : "$this",
+ "type" : "AliasRef"
+ }
+ }
+ }
+ },
+ "return" : {
+ "distinct" : false,
+ "expression" : {
+ "path" : "display",
+ "type" : "Property",
+ "source" : {
+ "name" : "$this",
+ "type" : "AliasRef"
+ }
+ }
+ }
+ }
+ } ],
+ "where" : {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "name" : "$this",
+ "type" : "AliasRef"
+ }
+ }
+ }
+ },
+ "return" : {
+ "distinct" : false,
+ "expression" : {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "name" : "$this",
+ "type" : "AliasRef"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "operand" : [ {
+ "name" : "enc_id",
+ "operandTypeSpecifier" : {
+ "name" : "{urn:hl7-org:elm-types:r1}String",
+ "type" : "NamedTypeSpecifier"
+ }
+ } ]
}, {
"name" : "ProcedureHistory",
"context" : "Patient",
@@ -283,6 +448,59 @@
}
}
}
+ }, {
+ "identifier" : "encounterReference",
+ "expression" : {
+ "type" : "If",
+ "condition" : {
+ "type" : "And",
+ "operand" : [ {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "path" : "encounter",
+ "scope" : "P",
+ "type" : "Property"
+ }
+ }
+ }, {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "path" : "reference",
+ "type" : "Property",
+ "source" : {
+ "path" : "encounter",
+ "scope" : "P",
+ "type" : "Property"
+ }
+ }
+ }
+ } ]
+ },
+ "then" : {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "path" : "reference",
+ "type" : "Property",
+ "source" : {
+ "path" : "encounter",
+ "scope" : "P",
+ "type" : "Property"
+ }
+ }
+ },
+ "else" : {
+ "asType" : "{urn:hl7-org:elm-types:r1}String",
+ "type" : "As",
+ "operand" : {
+ "type" : "Null"
+ }
+ }
+ }
} ],
"relationship" : [ ],
"return" : {
@@ -324,6 +542,57 @@
}
} ]
}
+ }, {
+ "name" : "Location",
+ "value" : {
+ "type" : "If",
+ "condition" : {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "name" : "encounterReference",
+ "type" : "QueryLetRef"
+ }
+ }
+ },
+ "then" : {
+ "name" : "GetEncounterLocation",
+ "type" : "FunctionRef",
+ "operand" : [ {
+ "type" : "Indexer",
+ "operand" : [ {
+ "type" : "Split",
+ "stringToSplit" : {
+ "name" : "encounterReference",
+ "type" : "QueryLetRef"
+ },
+ "separator" : {
+ "valueType" : "{urn:hl7-org:elm-types:r1}String",
+ "value" : "/",
+ "type" : "Literal"
+ }
+ }, {
+ "valueType" : "{urn:hl7-org:elm-types:r1}Integer",
+ "value" : "1",
+ "type" : "Literal"
+ } ]
+ } ]
+ },
+ "else" : {
+ "type" : "As",
+ "operand" : {
+ "type" : "Null"
+ },
+ "asTypeSpecifier" : {
+ "type" : "ListTypeSpecifier",
+ "elementType" : {
+ "name" : "{urn:hl7-org:elm-types:r1}String",
+ "type" : "NamedTypeSpecifier"
+ }
+ }
+ }
+ }
}, {
"name" : "CPT_CODE",
"value" : {
@@ -418,6 +687,59 @@
}
}
}
+ }, {
+ "identifier" : "encounterReference",
+ "expression" : {
+ "type" : "If",
+ "condition" : {
+ "type" : "And",
+ "operand" : [ {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "path" : "encounter",
+ "scope" : "P",
+ "type" : "Property"
+ }
+ }
+ }, {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "path" : "reference",
+ "type" : "Property",
+ "source" : {
+ "path" : "encounter",
+ "scope" : "P",
+ "type" : "Property"
+ }
+ }
+ }
+ } ]
+ },
+ "then" : {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "path" : "reference",
+ "type" : "Property",
+ "source" : {
+ "path" : "encounter",
+ "scope" : "P",
+ "type" : "Property"
+ }
+ }
+ },
+ "else" : {
+ "asType" : "{urn:hl7-org:elm-types:r1}String",
+ "type" : "As",
+ "operand" : {
+ "type" : "Null"
+ }
+ }
+ }
} ],
"relationship" : [ ],
"return" : {
@@ -459,6 +781,57 @@
}
} ]
}
+ }, {
+ "name" : "Location",
+ "value" : {
+ "type" : "If",
+ "condition" : {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "name" : "encounterReference",
+ "type" : "QueryLetRef"
+ }
+ }
+ },
+ "then" : {
+ "name" : "GetEncounterLocation",
+ "type" : "FunctionRef",
+ "operand" : [ {
+ "type" : "Indexer",
+ "operand" : [ {
+ "type" : "Split",
+ "stringToSplit" : {
+ "name" : "encounterReference",
+ "type" : "QueryLetRef"
+ },
+ "separator" : {
+ "valueType" : "{urn:hl7-org:elm-types:r1}String",
+ "value" : "/",
+ "type" : "Literal"
+ }
+ }, {
+ "valueType" : "{urn:hl7-org:elm-types:r1}Integer",
+ "value" : "1",
+ "type" : "Literal"
+ } ]
+ } ]
+ },
+ "else" : {
+ "type" : "As",
+ "operand" : {
+ "type" : "Null"
+ },
+ "asTypeSpecifier" : {
+ "type" : "ListTypeSpecifier",
+ "elementType" : {
+ "name" : "{urn:hl7-org:elm-types:r1}String",
+ "type" : "NamedTypeSpecifier"
+ }
+ }
+ }
+ }
}, {
"name" : "CPT_CODE",
"value" : {
@@ -481,6 +854,288 @@
} ]
}
}
+ }, {
+ "name" : "MedicationList",
+ "context" : "Patient",
+ "accessLevel" : "Public",
+ "expression" : {
+ "type" : "Query",
+ "source" : [ {
+ "alias" : "M",
+ "expression" : {
+ "dataType" : "{http://hl7.org/fhir}MedicationRequest",
+ "type" : "Retrieve"
+ }
+ } ],
+ "relationship" : [ ],
+ "where" : {
+ "type" : "And",
+ "operand" : [ {
+ "type" : "And",
+ "operand" : [ {
+ "type" : "Equal",
+ "operand" : [ {
+ "name" : "ToString",
+ "libraryName" : "FHIRHelpers",
+ "type" : "FunctionRef",
+ "operand" : [ {
+ "path" : "system",
+ "type" : "Property",
+ "source" : {
+ "type" : "Indexer",
+ "operand" : [ {
+ "path" : "identifier",
+ "scope" : "M",
+ "type" : "Property"
+ }, {
+ "valueType" : "{urn:hl7-org:elm-types:r1}Integer",
+ "value" : "0",
+ "type" : "Literal"
+ } ]
+ }
+ } ]
+ }, {
+ "name" : "UWMC_SYSTEM_VALUE",
+ "type" : "ExpressionRef"
+ } ]
+ }, {
+ "type" : "LessOrEqual",
+ "operand" : [ {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "path" : "authoredOn",
+ "scope" : "M",
+ "type" : "Property"
+ }
+ }, {
+ "type" : "ToDateTime",
+ "operand" : {
+ "type" : "Today"
+ }
+ } ]
+ } ]
+ }, {
+ "type" : "GreaterOrEqual",
+ "operand" : [ {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "path" : "authoredOn",
+ "scope" : "M",
+ "type" : "Property"
+ }
+ }, {
+ "type" : "ToDateTime",
+ "operand" : {
+ "type" : "Subtract",
+ "operand" : [ {
+ "type" : "Today"
+ }, {
+ "value" : 2,
+ "unit" : "year",
+ "type" : "Quantity"
+ } ]
+ }
+ } ]
+ } ]
+ },
+ "return" : {
+ "expression" : {
+ "type" : "Tuple",
+ "element" : [ {
+ "name" : "Name",
+ "value" : {
+ "name" : "ConceptText",
+ "type" : "FunctionRef",
+ "operand" : [ {
+ "strict" : false,
+ "type" : "As",
+ "operand" : {
+ "path" : "medication",
+ "scope" : "M",
+ "type" : "Property"
+ },
+ "asTypeSpecifier" : {
+ "name" : "{http://hl7.org/fhir}CodeableConcept",
+ "type" : "NamedTypeSpecifier"
+ }
+ } ]
+ }
+ }, {
+ "name" : "Start",
+ "value" : {
+ "name" : "DateTimeText",
+ "type" : "FunctionRef",
+ "operand" : [ {
+ "path" : "authoredOn",
+ "scope" : "M",
+ "type" : "Property"
+ } ]
+ }
+ }, {
+ "name" : "Dosage",
+ "value" : {
+ "type" : "Query",
+ "source" : [ {
+ "alias" : "$this",
+ "expression" : {
+ "type" : "Query",
+ "source" : [ {
+ "alias" : "$this",
+ "expression" : {
+ "path" : "dosageInstruction",
+ "scope" : "M",
+ "type" : "Property"
+ }
+ } ],
+ "where" : {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "path" : "text",
+ "type" : "Property",
+ "source" : {
+ "name" : "$this",
+ "type" : "AliasRef"
+ }
+ }
+ }
+ },
+ "return" : {
+ "distinct" : false,
+ "expression" : {
+ "path" : "text",
+ "type" : "Property",
+ "source" : {
+ "name" : "$this",
+ "type" : "AliasRef"
+ }
+ }
+ }
+ }
+ } ],
+ "where" : {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "name" : "$this",
+ "type" : "AliasRef"
+ }
+ }
+ }
+ },
+ "return" : {
+ "distinct" : false,
+ "expression" : {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "name" : "$this",
+ "type" : "AliasRef"
+ }
+ }
+ }
+ }
+ }, {
+ "name" : "Quantity",
+ "value" : {
+ "type" : "If",
+ "condition" : {
+ "type" : "And",
+ "operand" : [ {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "path" : "dispenseRequest",
+ "scope" : "M",
+ "type" : "Property"
+ }
+ }
+ }, {
+ "type" : "Not",
+ "operand" : {
+ "type" : "IsNull",
+ "operand" : {
+ "path" : "quantity",
+ "type" : "Property",
+ "source" : {
+ "path" : "dispenseRequest",
+ "scope" : "M",
+ "type" : "Property"
+ }
+ }
+ }
+ } ]
+ },
+ "then" : {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "path" : "quantity",
+ "type" : "Property",
+ "source" : {
+ "path" : "dispenseRequest",
+ "scope" : "M",
+ "type" : "Property"
+ }
+ }
+ }
+ },
+ "else" : {
+ "asType" : "{urn:hl7-org:elm-types:r1}Decimal",
+ "type" : "As",
+ "operand" : {
+ "type" : "Null"
+ }
+ }
+ }
+ }, {
+ "name" : "Prescriber",
+ "value" : {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "path" : "display",
+ "type" : "Property",
+ "source" : {
+ "path" : "requester",
+ "scope" : "M",
+ "type" : "Property"
+ }
+ }
+ }
+ }, {
+ "name" : "Authored",
+ "value" : {
+ "path" : "value",
+ "type" : "Property",
+ "source" : {
+ "path" : "authoredOn",
+ "scope" : "M",
+ "type" : "Property"
+ }
+ }
+ } ]
+ }
+ },
+ "sort" : {
+ "by" : [ {
+ "direction" : "desc",
+ "path" : "Authored",
+ "type" : "ByColumn"
+ } ]
+ }
+ }
}, {
"name" : "Summary",
"context" : "Patient",
@@ -505,6 +1160,12 @@
}
} ]
}
+ }, {
+ "name" : "MedicationList",
+ "value" : {
+ "name" : "MedicationList",
+ "type" : "ExpressionRef"
+ }
} ]
}
} ]
diff --git a/src/helpers/utility.js b/src/helpers/utility.js
index 975930896..4cfd5a8ad 100644
--- a/src/helpers/utility.js
+++ b/src/helpers/utility.js
@@ -696,3 +696,14 @@ export function getPatientSearchURL(shouldClearSession) {
export function getEnvVersionString() {
return getEnv(`${ENV_VAR_PREFIX}_VERSION_STRING`);
}
+
+export function dedupArrObjects(arr, key) {
+ if (isEmptyArray(arr)) return null;
+ if (!key) return arr;
+ return arr.reduce((acc, obj) => {
+ if (!acc.find(item => item[key] === obj[key])) {
+ acc.push(obj);
+ }
+ return acc;
+ }, []);
+}
diff --git a/src/styles/components/_Report.scss b/src/styles/components/_Report.scss
index 1d60a9f2f..cc7361644 100644
--- a/src/styles/components/_Report.scss
+++ b/src/styles/components/_Report.scss
@@ -7,6 +7,28 @@ $selector-box-shadow: 0 2px 2px #383e40;
background-color: $color-gray-lightest;
border-top: 4px solid $color-blue;
}
+ .flags-container {
+ .flag-item {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+ .flag {
+ color: $color-red-darker;
+ font-size: 1.2rem;
+ &.info {
+ color: $color-info;
+ }
+ &:hover {
+ color: $color-red;
+ cursor: pointer;
+ }
+ &.info:hover {
+ color: $color-info-light;
+ cursor: auto;
+ }
+ }
+ }
.summary__nav {
padding: 64px 0 24px 0px;
.title-text-container {
@@ -51,15 +73,29 @@ $selector-box-shadow: 0 2px 2px #383e40;
min-height: 72px;
background: $color-white;
padding: 8px;
+ .flags-container {
+ margin-left: 24px;
+ margin-right: 24px;
+ margin-bottom: 16px;
+ }
}
.sub-section {
border: 1px solid $color-gray-lighter;
margin-bottom: 8px;
margin-top: 8px;
&__header {
- padding: 0 20px 4px;
+ padding: 0 20px 12px;
margin-block-start: 0.5em;
margin-block-end: 0.5em;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ .flags-container {
+ margin: 0;
+ .flag {
+ font-size: 1rem;
+ }
+ }
}
&__anchor {
width: 2px;
@@ -69,7 +105,6 @@ $selector-box-shadow: 0 2px 2px #383e40;
display: flex;
align-items: center;
margin-block-start: 0;
- margin-block-end: 8px;
}
&:not(.sub-section-notitle):first-of-type {
margin-top: 0;
@@ -188,7 +223,7 @@ $selector-box-shadow: 0 2px 2px #383e40;
}
.rt-th:has(.col-Name_column),
.rt-td:has(.col-Name_column) {
- min-width: 70%;
+ min-width: 40%;
}
}
}
diff --git a/src/utils/executeELM.js b/src/utils/executeELM.js
index 0c4c6171f..6bfc052c8 100644
--- a/src/utils/executeELM.js
+++ b/src/utils/executeELM.js
@@ -152,7 +152,10 @@ async function executeELM(collector, oResourceTypes) {
if (!evalResults[PATIENT_SUMMARY_KEY]) {
evalResults[PATIENT_SUMMARY_KEY] = {};
}
- Promise.allSettled([executeELMForReport(patientBundle), ...elmLibs]).then(
+ Promise.allSettled([
+ executeELMForReport(patientBundle),
+ ...elmLibs,
+ ]).then(
(results) => {
evalResults[PATIENT_SUMMARY_KEY]["ReportSummary"] =
results[0].status !== "rejected" ? results[0].value : null;
@@ -190,9 +193,12 @@ async function executeELMForReport(bundle) {
console.log("Issue occurred loading ELM lib for reoirt", e);
r4ReportCommonELM = null;
});
+
if (!r4ReportCommonELM) return null;
- let reportLib = new cql.Library(r4ReportCommonELM);
+ let reportLib = new cql.Library(r4ReportCommonELM, new cql.Repository({
+ FHIRHelpers: r4HelpersELM,
+ }));
const reportExecutor = new cql.Executor(
reportLib,
new cql.CodeService(valueSetDB)