Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.

Commit 7b936e1

Browse files
authored
Merge pull request #34 from mcode/app-context-changes
App context changes
2 parents 12ee10d + 3dd4443 commit 7b936e1

5 files changed

Lines changed: 280 additions & 52 deletions

File tree

src/App.jsx

Lines changed: 62 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import ReactDOM from 'react-dom'
33
import "./App.css";
44
import cqlfhir from "cql-exec-fhir";
55
import executeElm from "./elmExecutor/executeElm";
6-
import fetchArtifacts from "./util/fetchArtifacts";
6+
import {fetchArtifacts, fetchArtifactsOperation, fetchFromQuestionnaireResponse, searchByOrder} from "./util/fetchArtifacts";
77
import fetchFhirVersion from "./util/fetchFhirVersion";
88
import { buildFhirUrl } from "./util/util";
99
import PriorAuth from "./components/PriorAuth/PriorAuth";
@@ -39,7 +39,7 @@ export default class App extends Component {
3939
priorAuthClaim: null,
4040
specialtyRxBundle: null,
4141
cqlPrepopulationResults: null,
42-
deviceRequest: null,
42+
orderResource: null,
4343
bundle: null,
4444
filter: true,
4545
filterChecked: true,
@@ -73,20 +73,21 @@ export default class App extends Component {
7373
this.standaloneLaunch = this.standaloneLaunch.bind(this);
7474
this.filter = this.filter.bind(this);
7575
this.onFilterCheckboxRefChange = this.onFilterCheckboxRefChange.bind(this);
76+
this.fetchResourcesAndExecuteCql = this.fetchResourcesAndExecuteCql.bind(this);
7677
}
7778

7879
componentDidMount() {
7980
if(!this.props.standalone) {
8081
this.ehrLaunch(false);
82+
// fetchArtifactsOperation(this.appContext, this.smart, this.consoleLog);
8183
}
8284
}
8385

8486
standaloneLaunch(patient, response) {
85-
const template = `Questionnaire/${response.questionnaire}`;
8687
fetchFhirVersion(this.props.smart.state.serverUrl)
8788
.then(fhirVersion => {
8889
this.fhirVersion = fhirVersion;
89-
const questionnaireUrl = buildFhirUrl(template, this.props.FHIR_PREFIX, this.fhirVersion);
90+
const questionnaireUrl = response.questionnaire;
9091
fetch(questionnaireUrl).then(r => r.json())
9192
.then(questionnaire => {
9293
this.setState({ questionnaire: questionnaire });
@@ -102,63 +103,84 @@ export default class App extends Component {
102103
})
103104
}
104105

106+
105107
ehrLaunch(isContainedQuestionnaire, questionnaire) {
106-
// Temporary indication before full supports for relaunch is implemented
107-
if(!this.appContext.request) {
108-
alert("Supports for relaunch will be added in the near future!");
109-
this.consoleLog("Supports for relaunch will be added in the near future!", "errorClass");
110-
return;
108+
let acOrder = this.appContext.order;
109+
let acCoverage = this.appContext.coverage;
110+
let acQuestionnaire = this.appContext.questionnaire;
111+
let acResponse = this.appContext.response;
112+
if(acOrder && acCoverage && !acQuestionnaire && !acResponse) {
113+
// TODO: There's an additional case where you could launch
114+
// with just the order/coverage by invoking the operation
115+
// but I think the endpoint extension on coverage which
116+
// would facilitate that is going away in ballot.
117+
searchByOrder(acOrder, this.smart).then((res) => {
118+
// TODO: Don't know how to deal with multiple QRs
119+
// Let user pick with a UI? Force orders to
120+
// uniquely identify QRs?
121+
// for now just pick the first one
122+
acResponse = res[0].resource;
123+
acQuestionnaire = acResponse.questionnaire;
124+
this.setState({response: acResponse});
125+
this.fetchResourcesAndExecuteCql(acOrder, acCoverage, acQuestionnaire);
126+
});
127+
} else if(acResponse) {
128+
// start relaunch
129+
// TODO: could potentially pass order to this function and avoid
130+
// needing to search the QR context extension for it
131+
// which would also support QRs without the extension.
132+
fetchFromQuestionnaireResponse(acResponse, this.smart).then((relaunchContext) => {
133+
this.setState({response: relaunchContext.response})
134+
this.fetchResourcesAndExecuteCql(relaunchContext.order, relaunchContext.coverage, relaunchContext.questionnaire);
135+
});
136+
} else if(acQuestionnaire && acOrder && acCoverage){
137+
this.consoleLog("fetching artifacts", "infoClass");
138+
this.setState({
139+
isFetchingArtifacts: true
140+
})
141+
const reloadQuestionnaire = questionnaire !== undefined;
142+
this.setState({reloadQuestionnaire});
143+
this.fetchResourcesAndExecuteCql(acOrder, acCoverage, acQuestionnaire);
144+
} else {
145+
alert("invalid app context")
111146
}
112-
const deviceRequest = JSON.parse(this.appContext.request.replace(/\\/g,""));
113-
this.consoleLog("fetching artifacts", "infoClass");
114-
this.setState({
115-
isFetchingArtifacts: true
116-
})
117-
const reloadQuestionnaire = questionnaire !== undefined;
118-
147+
}
148+
149+
fetchResourcesAndExecuteCql(order, coverage, questionnaire) {
119150
fetchFhirVersion(this.props.smart.state.serverUrl)
120151
.then(fhirVersion => {
121152
this.fhirVersion = fhirVersion;
122153

123-
fetchArtifacts(
124-
this.props.FHIR_PREFIX,
125-
this.props.FILE_PREFIX,
126-
!isContainedQuestionnaire ? this.appContext.template : questionnaire,
127-
this.fhirVersion,
128-
this.smart,
129-
this.consoleLog,
130-
isContainedQuestionnaire
131-
)
154+
fetchArtifactsOperation(order, coverage, questionnaire, this.smart, this.consoleLog)
132155
.then(artifacts => {
133156
console.log("fetched needed artifacts:", artifacts);
134-
157+
const orderResource = artifacts.order;
135158
let fhirWrapper = this.getFhirWrapper(this.fhirVersion);
136-
137159
this.setState({ questionnaire: artifacts.questionnaire });
138-
this.setState({ deviceRequest: deviceRequest });
160+
this.setState({ orderResource: orderResource });
139161
this.setState({ isAdaptiveFormWithoutExtension: artifacts.questionnaire.meta && artifacts.questionnaire.meta.profile && artifacts.questionnaire.meta.profile.includes("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-adapt") && (artifacts.questionnaire.extension === undefined || !artifacts.questionnaire.extension.includes(e => e.url === "http://hl7.org/fhir/StructureDefinition/cqf-library")) });
140162
this.setState({ });
141163
// execute for each main library
142164
return Promise.all(
143165
artifacts.mainLibraryElms.map(mainLibraryElm => {
144166
let parameterObj;
145-
if (deviceRequest.resourceType === "DeviceRequest") {
167+
if (orderResource.resourceType === "DeviceRequest") {
146168
parameterObj = {
147-
device_request: fhirWrapper.wrap(deviceRequest)
169+
device_request: fhirWrapper.wrap(orderResource)
148170
};
149171
} else if (
150-
deviceRequest.resourceType === "ServiceRequest"
172+
orderResource.resourceType === "ServiceRequest"
151173
) {
152174
parameterObj = {
153-
service_request: fhirWrapper.wrap(deviceRequest)
175+
service_request: fhirWrapper.wrap(orderResource)
154176
};
155-
} else if (deviceRequest.resourceType === "MedicationRequest") {
177+
} else if (orderResource.resourceType === "MedicationRequest") {
156178
parameterObj = {
157-
medication_request: fhirWrapper.wrap(deviceRequest)
179+
medication_request: fhirWrapper.wrap(orderResource)
158180
};
159-
} else if (deviceRequest.resourceType === "MedicationDispense") {
181+
} else if (orderResource.resourceType === "MedicationDispense") {
160182
parameterObj = {
161-
medication_dispense: fhirWrapper.wrap(deviceRequest)
183+
medication_dispense: fhirWrapper.wrap(orderResource)
162184
};
163185
}
164186

@@ -194,7 +216,7 @@ export default class App extends Component {
194216
return executeElm(
195217
this.smart,
196218
this.fhirVersion,
197-
deviceRequest,
219+
orderResource,
198220
executionInputs,
199221
this.consoleLog
200222
);
@@ -247,13 +269,11 @@ export default class App extends Component {
247269
this.setState({
248270
bundle: fullBundle,
249271
cqlPrepopulationResults: allLibrariesResults,
250-
isFetchingArtifacts: false,
251-
reloadQuestionnaire
272+
isFetchingArtifacts: false
252273
});
253274
});
254275
});
255276
}
256-
257277
getFhirWrapper(fhirVersion) {
258278
if (fhirVersion == "r4") {
259279
return cqlfhir.FHIRWrapper.FHIRv400();
@@ -615,8 +635,9 @@ export default class App extends Component {
615635
) : (
616636
<QuestionnaireForm
617637
qform={this.state.questionnaire}
638+
appContext = {this.appContext}
618639
cqlPrepopulationResults={this.state.cqlPrepopulationResults}
619-
deviceRequest={this.state.deviceRequest}
640+
deviceRequest={this.state.orderResource}
620641
bundle={this.state.bundle}
621642
patientId={this.patientId}
622643
standalone={this.props.standalone}
@@ -627,8 +648,6 @@ export default class App extends Component {
627648
setSpecialtyRxBundle={this.setSpecialtyRxBundle.bind(this)}
628649
fhirVersion={this.fhirVersion.toUpperCase()}
629650
smart={this.smart}
630-
FHIR_PREFIX={this.props.FHIR_PREFIX}
631-
FILE_PATH={this.props.FILE_PREFIX}
632651
renderButtons={this.renderButtons}
633652
filterFieldsFn={this.filter}
634653
filterChecked={this.state.filter}

src/components/QuestionnaireForm/QuestionnaireForm.jsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export default class QuestionnaireForm extends Component {
4040
this.patientId = props.patientId;
4141
this.fhirVersion = props.fhirVersion;
4242
this.FHIR_PREFIX = props.FHIR_PREFIX;
43+
this.appContext = props.appContext;
4344
this.partialForms = {};
4445
this.handleGtable = this.handleGtable.bind(this);
4546
this.getLibraryPrepopulationResult = this.getLibraryPrepopulationResult.bind(this);
@@ -61,7 +62,7 @@ export default class QuestionnaireForm extends Component {
6162

6263
componentWillMount() {
6364
// search for any partially completed QuestionnaireResponses
64-
if (this.props.standalone) {
65+
if (this.props.response) {
6566
const response = this.props.response;
6667
const items = this.props.qform.item;
6768
const parentItems = [];
@@ -226,8 +227,14 @@ export default class QuestionnaireForm extends Component {
226227

227228
let count = 0;
228229

229-
partialResponses.entry.forEach(r => {
230-
if (r.resource.questionnaire.includes(this.props.qform.id)) {
230+
partialResponses.entry.forEach(bundleEntry => {
231+
let questionnaireId = null;
232+
if(bundleEntry.resource.contained) {
233+
questionnaireId = bundleEntry.resource?.contained[0]?.id;
234+
}
235+
const questionaireIdUrl = bundleEntry.resource.questionnaire;
236+
237+
if (this.props.qform.id === questionnaireId || questionaireIdUrl.includes(this.props.qform.id)) {
231238
count = count + 1;
232239
// add the option to the popupOptions
233240
let date = new Date(bundleEntry.resource.authored);
@@ -905,7 +912,7 @@ export default class QuestionnaireForm extends Component {
905912
};
906913
this.addAuthorToResponse(qr, this.getPractitioner());
907914

908-
qr.questionnaire = `${this.FHIR_PREFIX}${this.fhirVersion}/Questionnaire/${this.props.qform.id}`;
915+
qr.questionnaire = this.appContext.questionnaire?this.appContext.questionnaire:this.props.response.questionnaire;
909916
console.log("GetQuestionnaireResponse final QuestionnaireResponse: ", qr);
910917

911918
const request = this.props.deviceRequest;

src/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,6 @@ tokenPost.onload = function() {
9999
// too badly.
100100
ReactDOM.render(
101101
<App
102-
FHIR_PREFIX={appContext.fhirpath}
103-
FILE_PREFIX={appContext.filepath}
104102
appContext={appContext}
105103
standalone={standalone}
106104
smart={smart}

0 commit comments

Comments
 (0)