From adbf0d4d6f8b2ec4763d6d3e5a1239e6fbecc8cb Mon Sep 17 00:00:00 2001 From: kghoreshi Date: Thu, 1 Dec 2022 21:01:08 -0500 Subject: [PATCH 1/3] match prefetch to current admin prefetch --- src/PrefetchTemplate.js | 91 ++++++--------------------- src/components/SMARTBox/PatientBox.js | 8 +-- src/properties.json | 6 +- src/util/buildRequest.js | 35 +---------- 4 files changed, 27 insertions(+), 113 deletions(-) diff --git a/src/PrefetchTemplate.js b/src/PrefetchTemplate.js index fb485a93..865b5cdd 100644 --- a/src/PrefetchTemplate.js +++ b/src/PrefetchTemplate.js @@ -6,83 +6,32 @@ export class PrefetchTemplate { const prefetchMap = new Map(); - const COVERAGE_PREFETCH_QUERY = new PrefetchTemplate( - "Coverage?patient={{context.patientId}}"); - - const DEVICE_REQUEST_BUNDLE = new PrefetchTemplate( - "DeviceRequest?_id={{context.draftOrders.DeviceRequest.id}}" - + "&_include=DeviceRequest:patient" - + "&_include=DeviceRequest:performer" - + "&_include=DeviceRequest:requester" - + "&_include=DeviceRequest:device" - + "&_include:iterate=PractitionerRole:organization" - + "&_include:iterate=PractitionerRole:practitioner"); - - const MEDICATION_REQUEST_BUNDLE = new PrefetchTemplate( - "MedicationRequest?_id={{context.medications.MedicationRequest.id}}" - + "&_include=MedicationRequest:patient" - + "&_include=MedicationRequest:intended-dispenser" - + "&_include=MedicationRequest:requester:PractitionerRole" - + "&_include=MedicationRequest:medication" - + "&_include:iterate=PractitionerRole:organization" - + "&_include:iterate=PractitionerRole:practitioner"); - - const MEDICATION_DISPENSE_BUNDLE = new PrefetchTemplate( - "MedicationDispense?_id={{context.medications.MedicationDispense.id}}" - + "&_include=MedicationDispense:patient" - + "&_include=MedicationDispense:intended-dispenser" - + "&_include=MedicationDispense:requester:PractitionerRole" - + "&_include=MedicationDispense:medication" - + "&_include:iterate=PractitionerRole:organization" - + "&_include:iterate=PractitionerRole:practitioner"); - - const NUTRITION_ORDER_BUNDLE = new PrefetchTemplate( - "NutritionOrder?_id={{context.draftOrders.NutritionOrder.id}}" - + "&_include=NutritionOrder:patient" - + "&_include=NutritionOrder:provider" - + "&_include=NutritionOrder:requester" - + "&_include=PractitionerRole:organization" - + "&_include=PractitionerRole:practitioner" - + "&_include=NutritionOrder:encounter" - + "&_include=Encounter:location"); - - const SERVICE_REQUEST_BUNDLE = new PrefetchTemplate( - "ServiceRequest?_id={{context.draftOrders.ServiceRequest.id}}" - + "&_include=ServiceRequest:patient" - + "&_include=ServiceRequest:performer" - + "&_include=ServiceRequest:requester" - + "&_include:iterate=PractitionerRole:organization" - + "&_include:iterate=PractitionerRole:practitioner"); - - const APPOINTMENT_BUNDLE = new PrefetchTemplate( - "appointmentBundle", - "Appointment?_id={{context.appointments.Appointment.id}}" - + "&_include=Appointment:patient" - + "&_include=Appointment:practitioner:PractitionerRole" - + "&_include:iterate=PractitionerRole:organization" - + "&_include:iterate=PractitionerRole:practitioner" - + "&_include=Appointment:location"); - - const ENCOUNTER_BUNDLE = new PrefetchTemplate( - "encounterBundle", - "Encounter?_id={{context.encounterId}}" - + "&_include=Encounter:patient" - + "&_include=Encounter:service-provider" - + "&_include=Encounter:practitioner" - + "&_include=Encounter:location"); - - prefetchMap.set("Coverage", COVERAGE_PREFETCH_QUERY); - prefetchMap.set("DeviceRequest", DEVICE_REQUEST_BUNDLE); - prefetchMap.set("MedicationRequest", MEDICATION_REQUEST_BUNDLE); - prefetchMap.set("MedicationDispense", MEDICATION_DISPENSE_BUNDLE); - prefetchMap.set("ServiceRequest", SERVICE_REQUEST_BUNDLE); - prefetchMap.set("Encounter", ENCOUNTER_BUNDLE); + const PRACTITIONER_PREFETCH = new PrefetchTemplate( + "{{context.userId}}"); + const REQUEST_PREFETCH = new PrefetchTemplate( + "MedicationRequest/{{context.medications.MedicationRequest.id}}"); + const PATIENT_PREFETCH = new PrefetchTemplate("{{context.patientId}}"); + + // prefetchMap.set("Coverage", COVERAGE_PREFETCH_QUERY); + prefetchMap.set("request", REQUEST_PREFETCH); + prefetchMap.set("practitioner", PRACTITIONER_PREFETCH); + prefetchMap.set("patient", PATIENT_PREFETCH); + // prefetchMap.set("ServiceRequest", SERVICE_REQUEST_BUNDLE); + // prefetchMap.set("Encounter", ENCOUNTER_BUNDLE); return prefetchMap; } static generateParamElementMap() { const paramElementMap = new Map(); + // TODO - this should just be inferred based on context. Or rather + // the instructions from the hook about what context to fill in + // Quite literally, the "context" here refers to the "context" of the + // cds-hook, which as of now is just hard-coded in buildRequest.js + // Rather than do this, which searches the request resource for information, + // the cds-hook should be constructed and then the context used to actually make + // the appropriate requests. + paramElementMap.set('context.userId', ['requester', 'reference']) paramElementMap.set('context.draftOrders.DeviceRequest.id', ['id']); paramElementMap.set('context.medications.MedicationRequest.id', ['id']); paramElementMap.set('context.medications.MedicationDispense.id', ['id']); diff --git a/src/components/SMARTBox/PatientBox.js b/src/components/SMARTBox/PatientBox.js index e638ac5d..7480a084 100644 --- a/src/components/SMARTBox/PatientBox.js +++ b/src/components/SMARTBox/PatientBox.js @@ -98,7 +98,7 @@ export default class SMARTBox extends Component { updatePrefetchRequest(request) { this.props.callback(request.resourceType, request); - const queries = this.props.updatePrefetchCallback(request, request.resourceType, "Coverage"); + const queries = this.props.updatePrefetchCallback(request, "request", "patient", "practitioner"); queries.forEach((query, queryKey) => { const urlQuery = this.props.ehrUrl + '/' + query; fetch(urlQuery, { @@ -106,10 +106,8 @@ export default class SMARTBox extends Component { }).then((response) => { const responseJson = response.json() return responseJson; - }).then((bundle) => { - bundle['entry'].forEach((fullResource) => { - this.props.callbackMap("prefetchedResources", queryKey, fullResource); - }); + }).then((resource) => { + this.props.callbackMap("prefetchedResources", queryKey, resource); }); }); this.props.callback("request", request); diff --git a/src/properties.json b/src/properties.json index 725130a4..49a817ee 100644 --- a/src/properties.json +++ b/src/properties.json @@ -5,9 +5,9 @@ "server": "http://localhost:8090", "ehr_server": "http://localhost:8080/test-ehr/r4", "ehr_base": "http://localhost:8080/test-ehr/r4", - "cds_service":"http://localhost:8090/r4/cds-services", - "order_sign": "order-sign-crd", - "order_select": "order-select-crd", + "cds_service":"http://localhost:8090/cds-services", + "order_sign": "rems-order-sign", + "order_select": "rems-order-select", "user": "alice", "password": "alice", "public_keys": "http://localhost:3001/public_keys", diff --git a/src/util/buildRequest.js b/src/util/buildRequest.js index 7fb9fff3..857370eb 100644 --- a/src/util/buildRequest.js +++ b/src/util/buildRequest.js @@ -85,41 +85,8 @@ export default function buildRequest(request, patient, ehrUrl, token, prefetch, if(includePrefetch){ r4json.prefetch = {}; - prefetch.forEach((resource, key) => { - if (key === 'DeviceRequest') { - r4json.prefetch.deviceRequestBundle = { - "resourceType": "Bundle", - "type": "collection", - "entry": resource - }; - } else if (key === 'ServiceRequest') { - r4json.prefetch.serviceRequestBundle = { - "resourceType": "Bundle", - "type": "collection", - "entry": resource - }; - } else if(key === 'MedicationRequest') { - r4json.prefetch.medicationRequestBundle = { - "resourceType": "Bundle", - "type": "collection", - "entry": resource - }; - } else if (key === 'MedicationDispense') { - r4json.prefetch.medicationDispenseBundle = { - "resourceType": "Bundle", - "type": "collection", - "entry": resource - }; - } else if (key === 'Coverage') { - r4json.prefetch.coverageBundle = { - "resourceType": "Bundle", - "type": "collection", - "entry": resource - }; - } else { - console.error("Invalid prefetch key used: " + key + "."); - } + r4json.prefetch[key] = resource }); } From b95e541c4490cd2ed874fa508e2cbc14f7b28a2a Mon Sep 17 00:00:00 2001 From: kghoreshi Date: Fri, 2 Dec 2022 14:38:42 -0500 Subject: [PATCH 2/3] minor changes fixing prefetch formatting --- src/components/RequestBox/RequestBox.js | 29 ++++++++++----- src/components/SMARTBox/PatientBox.js | 47 +++++++++++++------------ src/util/buildRequest.js | 2 +- 3 files changed, 45 insertions(+), 33 deletions(-) diff --git a/src/components/RequestBox/RequestBox.js b/src/components/RequestBox/RequestBox.js index 31f21b17..ad864301 100644 --- a/src/components/RequestBox/RequestBox.js +++ b/src/components/RequestBox/RequestBox.js @@ -57,9 +57,15 @@ export default class RequestBox extends Component { prepPrefetch() { const preppedResources = new Map(); Object.keys(this.state.prefetchedResources).forEach((resourceKey) => { - const resourceList = this.state.prefetchedResources[resourceKey].map((resource) => { - return resource; - }) + let resourceList = [] + if(Array.isArray(this.state.prefetchedResources[resourceKey])){ + resourceList = this.state.prefetchedResources[resourceKey].map((resource) => { + return resource; + }) + } else { + resourceList = this.state.prefetchedResources[resourceKey] + } + preppedResources.set(resourceKey, resourceList); }); return preppedResources; @@ -92,7 +98,7 @@ export default class RequestBox extends Component { if(!prevState[elementName][key]){ prevState[elementName][key] = []; } - return {[elementName]: {...prevState[elementName], [key]: [...prevState[elementName][key], text]}}; + return {[elementName]: {...prevState[elementName], [key]: text}}; }); }; @@ -212,11 +218,16 @@ export default class RequestBox extends Component { var renderedPrefetches = new Map(); requestResources.forEach((resourceList, resourceKey) => { const renderedList = []; - resourceList.forEach((resource) => { - console.log("Request resources:" + JSON.stringify(requestResources)); - console.log("Request key:" + resourceKey); - renderedList.push(this.renderResource(resource)) - }); + if(Array.isArray(resourceList)){ + resourceList.forEach((resource) => { + console.log("Request resources:" + JSON.stringify(requestResources)); + console.log("Request key:" + resourceKey); + renderedList.push(this.renderResource(resource)) + }); + } else { + renderedList.push(this.renderResource(resourceList)) + } + renderedPrefetches.set(resourceKey, renderedList); }); console.log(renderedPrefetches); diff --git a/src/components/SMARTBox/PatientBox.js b/src/components/SMARTBox/PatientBox.js index 7480a084..468e4c26 100644 --- a/src/components/SMARTBox/PatientBox.js +++ b/src/components/SMARTBox/PatientBox.js @@ -38,7 +38,7 @@ export default class SMARTBox extends Component { } else if (request.resourceType === "ServiceRequest") { code = request.code.coding[0]; } else if (request.resourceType === "MedicationRequest" - || request.resourceType === "MedicationDispense") { + || request.resourceType === "MedicationDispense") { code = request.medicationCodeableConcept.coding[0]; } if (code) { @@ -77,7 +77,7 @@ export default class SMARTBox extends Component { this.props.callback("patient", patient); this.props.callback("openPatient", false); this.props.clearCallback(); - if(this.state.request !== "none" ) { + if (this.state.request !== "none") { const request = JSON.parse(this.state.request); if (request.resourceType === "DeviceRequest" || request.resourceType === "ServiceRequest" || request.resourceType === "MedicationRequest" || request.resourceType === "MedicationDispense") { this.updatePrefetchRequest(request); @@ -85,8 +85,8 @@ export default class SMARTBox extends Component { this.props.clearCallback(); } } - - if(this.state.response !== "none") { + + if (this.state.response !== "none") { const response = JSON.parse(this.state.response); this.updateQRResponse(patient, response); } @@ -161,7 +161,7 @@ export default class SMARTBox extends Component { flat: true, }) .then((result) => { - this.setState({ medicationDispenses: result}); + this.setState({ medicationDispenses: result }); }); } @@ -189,17 +189,17 @@ export default class SMARTBox extends Component { this.setState({ response: "none" }); - } else { + } else { this.setState({ response: data.value }); } } - + getRequests() { const client = FHIR.client( - this.props.params - ); + this.props.params + ); const patientId = this.props.patient.id; this.getDeviceRequest(patientId, client); this.getServiceRequest(patientId, client); @@ -233,7 +233,7 @@ export default class SMARTBox extends Component { const display = `${qr.questionnaire}: created at ${qr.authored}`; let option = { key: qr.id, - text: display, + text: display, value: JSON.stringify(qr), content: (
@@ -268,24 +268,25 @@ export default class SMARTBox extends Component { }); } if (this.state.medicationRequests.data) { - this.state.medicationRequests.data.forEach((e) => { + this.state.medicationRequests.data.forEach((e) => { this.makeOption(e, options); }); } if (this.state.medicationDispenses.data) { this.state.medicationDispenses.data.forEach((e) => { - this.makeOption(e, options); - })}; + this.makeOption(e, options); + }) + }; - if(this.state.questionnaireResponses.data) { + if (this.state.questionnaireResponses.data) { returned = true; this.state.questionnaireResponses.data.forEach(qr => this.makeQROption(qr, responseOptions)); } - + let noResults = 'No results found.' - if(!returned) { - noResults = 'Loading...'; + if (!returned) { + noResults = 'Loading...'; } return ( @@ -319,10 +320,10 @@ export default class SMARTBox extends Component { Request: - In Progress Form: - Date: Fri, 9 Dec 2022 19:14:30 -0500 Subject: [PATCH 3/3] support hydration --- src/PrefetchTemplate.js | 3 --- src/components/SMARTBox/PatientBox.js | 2 +- src/util/buildRequest.js | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/PrefetchTemplate.js b/src/PrefetchTemplate.js index 865b5cdd..52d8fa42 100644 --- a/src/PrefetchTemplate.js +++ b/src/PrefetchTemplate.js @@ -8,12 +8,9 @@ export class PrefetchTemplate { const PRACTITIONER_PREFETCH = new PrefetchTemplate( "{{context.userId}}"); - const REQUEST_PREFETCH = new PrefetchTemplate( - "MedicationRequest/{{context.medications.MedicationRequest.id}}"); const PATIENT_PREFETCH = new PrefetchTemplate("{{context.patientId}}"); // prefetchMap.set("Coverage", COVERAGE_PREFETCH_QUERY); - prefetchMap.set("request", REQUEST_PREFETCH); prefetchMap.set("practitioner", PRACTITIONER_PREFETCH); prefetchMap.set("patient", PATIENT_PREFETCH); // prefetchMap.set("ServiceRequest", SERVICE_REQUEST_BUNDLE); diff --git a/src/components/SMARTBox/PatientBox.js b/src/components/SMARTBox/PatientBox.js index 468e4c26..11e9bd7f 100644 --- a/src/components/SMARTBox/PatientBox.js +++ b/src/components/SMARTBox/PatientBox.js @@ -98,7 +98,7 @@ export default class SMARTBox extends Component { updatePrefetchRequest(request) { this.props.callback(request.resourceType, request); - const queries = this.props.updatePrefetchCallback(request, "request", "patient", "practitioner"); + const queries = this.props.updatePrefetchCallback(request, "patient", "practitioner"); queries.forEach((query, queryKey) => { const urlQuery = this.props.ehrUrl + '/' + query; fetch(urlQuery, { diff --git a/src/util/buildRequest.js b/src/util/buildRequest.js index 1095d5d6..7558f9d5 100644 --- a/src/util/buildRequest.js +++ b/src/util/buildRequest.js @@ -44,7 +44,7 @@ export default function buildRequest(request, patient, ehrUrl, token, prefetch, "subject": "cds-service4" }, "context": { - "userId": request.requester.reference, + "userId": request.requester.reference.split("/")[1], "patientId": patient.id, "encounterId": "enc89284" }