Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.
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
105 changes: 62 additions & 43 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import ReactDOM from 'react-dom'
import "./App.css";
import cqlfhir from "cql-exec-fhir";
import executeElm from "./elmExecutor/executeElm";
import fetchArtifacts from "./util/fetchArtifacts";
import {fetchArtifacts, fetchArtifactsOperation, fetchFromQuestionnaireResponse, searchByOrder} from "./util/fetchArtifacts";
import fetchFhirVersion from "./util/fetchFhirVersion";
import { buildFhirUrl } from "./util/util";
import PriorAuth from "./components/PriorAuth/PriorAuth";
Expand Down Expand Up @@ -39,7 +39,7 @@ export default class App extends Component {
priorAuthClaim: null,
specialtyRxBundle: null,
cqlPrepopulationResults: null,
deviceRequest: null,
orderResource: null,
bundle: null,
filter: true,
filterChecked: true,
Expand Down Expand Up @@ -73,20 +73,21 @@ export default class App extends Component {
this.standaloneLaunch = this.standaloneLaunch.bind(this);
this.filter = this.filter.bind(this);
this.onFilterCheckboxRefChange = this.onFilterCheckboxRefChange.bind(this);
this.fetchResourcesAndExecuteCql = this.fetchResourcesAndExecuteCql.bind(this);
}

componentDidMount() {
if(!this.props.standalone) {
this.ehrLaunch(false);
// fetchArtifactsOperation(this.appContext, this.smart, this.consoleLog);
}
}

standaloneLaunch(patient, response) {
const template = `Questionnaire/${response.questionnaire}`;
fetchFhirVersion(this.props.smart.state.serverUrl)
.then(fhirVersion => {
this.fhirVersion = fhirVersion;
const questionnaireUrl = buildFhirUrl(template, this.props.FHIR_PREFIX, this.fhirVersion);
const questionnaireUrl = response.questionnaire;
fetch(questionnaireUrl).then(r => r.json())
.then(questionnaire => {
this.setState({ questionnaire: questionnaire });
Expand All @@ -102,63 +103,84 @@ export default class App extends Component {
})
}


ehrLaunch(isContainedQuestionnaire, questionnaire) {
// Temporary indication before full supports for relaunch is implemented
if(!this.appContext.request) {
alert("Supports for relaunch will be added in the near future!");
this.consoleLog("Supports for relaunch will be added in the near future!", "errorClass");
return;
let acOrder = this.appContext.order;
let acCoverage = this.appContext.coverage;
let acQuestionnaire = this.appContext.questionnaire;
let acResponse = this.appContext.response;
if(acOrder && acCoverage && !acQuestionnaire && !acResponse) {
// TODO: There's an additional case where you could launch
// with just the order/coverage by invoking the operation
// but I think the endpoint extension on coverage which
// would facilitate that is going away in ballot.
searchByOrder(acOrder, this.smart).then((res) => {
// TODO: Don't know how to deal with multiple QRs
// Let user pick with a UI? Force orders to
// uniquely identify QRs?
// for now just pick the first one
acResponse = res[0].resource;
acQuestionnaire = acResponse.questionnaire;
this.setState({response: acResponse});
this.fetchResourcesAndExecuteCql(acOrder, acCoverage, acQuestionnaire);
});
} else if(acResponse) {
// start relaunch
// TODO: could potentially pass order to this function and avoid
// needing to search the QR context extension for it
// which would also support QRs without the extension.
fetchFromQuestionnaireResponse(acResponse, this.smart).then((relaunchContext) => {
this.setState({response: relaunchContext.response})
this.fetchResourcesAndExecuteCql(relaunchContext.order, relaunchContext.coverage, relaunchContext.questionnaire);
});
} else if(acQuestionnaire && acOrder && acCoverage){
this.consoleLog("fetching artifacts", "infoClass");
this.setState({
isFetchingArtifacts: true
})
const reloadQuestionnaire = questionnaire !== undefined;
this.setState({reloadQuestionnaire});
this.fetchResourcesAndExecuteCql(acOrder, acCoverage, acQuestionnaire);
} else {
alert("invalid app context")
}
const deviceRequest = JSON.parse(this.appContext.request.replace(/\\/g,""));
this.consoleLog("fetching artifacts", "infoClass");
this.setState({
isFetchingArtifacts: true
})
const reloadQuestionnaire = questionnaire !== undefined;

}

fetchResourcesAndExecuteCql(order, coverage, questionnaire) {
fetchFhirVersion(this.props.smart.state.serverUrl)
.then(fhirVersion => {
this.fhirVersion = fhirVersion;

fetchArtifacts(
this.props.FHIR_PREFIX,
this.props.FILE_PREFIX,
!isContainedQuestionnaire ? this.appContext.template : questionnaire,
this.fhirVersion,
this.smart,
this.consoleLog,
isContainedQuestionnaire
)
fetchArtifactsOperation(order, coverage, questionnaire, this.smart, this.consoleLog)
.then(artifacts => {
console.log("fetched needed artifacts:", artifacts);

const orderResource = artifacts.order;
let fhirWrapper = this.getFhirWrapper(this.fhirVersion);

this.setState({ questionnaire: artifacts.questionnaire });
this.setState({ deviceRequest: deviceRequest });
this.setState({ orderResource: orderResource });
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")) });
this.setState({ });
// execute for each main library
return Promise.all(
artifacts.mainLibraryElms.map(mainLibraryElm => {
let parameterObj;
if (deviceRequest.resourceType === "DeviceRequest") {
if (orderResource.resourceType === "DeviceRequest") {
parameterObj = {
device_request: fhirWrapper.wrap(deviceRequest)
device_request: fhirWrapper.wrap(orderResource)
};
} else if (
deviceRequest.resourceType === "ServiceRequest"
orderResource.resourceType === "ServiceRequest"
) {
parameterObj = {
service_request: fhirWrapper.wrap(deviceRequest)
service_request: fhirWrapper.wrap(orderResource)
};
} else if (deviceRequest.resourceType === "MedicationRequest") {
} else if (orderResource.resourceType === "MedicationRequest") {
parameterObj = {
medication_request: fhirWrapper.wrap(deviceRequest)
medication_request: fhirWrapper.wrap(orderResource)
};
} else if (deviceRequest.resourceType === "MedicationDispense") {
} else if (orderResource.resourceType === "MedicationDispense") {
parameterObj = {
medication_dispense: fhirWrapper.wrap(deviceRequest)
medication_dispense: fhirWrapper.wrap(orderResource)
};
}

Expand Down Expand Up @@ -194,7 +216,7 @@ export default class App extends Component {
return executeElm(
this.smart,
this.fhirVersion,
deviceRequest,
orderResource,
executionInputs,
this.consoleLog
);
Expand Down Expand Up @@ -247,13 +269,11 @@ export default class App extends Component {
this.setState({
bundle: fullBundle,
cqlPrepopulationResults: allLibrariesResults,
isFetchingArtifacts: false,
reloadQuestionnaire
isFetchingArtifacts: false
});
});
});
}

getFhirWrapper(fhirVersion) {
if (fhirVersion == "r4") {
return cqlfhir.FHIRWrapper.FHIRv400();
Expand Down Expand Up @@ -615,8 +635,9 @@ export default class App extends Component {
) : (
<QuestionnaireForm
qform={this.state.questionnaire}
appContext = {this.appContext}
cqlPrepopulationResults={this.state.cqlPrepopulationResults}
deviceRequest={this.state.deviceRequest}
deviceRequest={this.state.orderResource}
bundle={this.state.bundle}
patientId={this.patientId}
standalone={this.props.standalone}
Expand All @@ -627,8 +648,6 @@ export default class App extends Component {
setSpecialtyRxBundle={this.setSpecialtyRxBundle.bind(this)}
fhirVersion={this.fhirVersion.toUpperCase()}
smart={this.smart}
FHIR_PREFIX={this.props.FHIR_PREFIX}
FILE_PATH={this.props.FILE_PREFIX}
renderButtons={this.renderButtons}
filterFieldsFn={this.filter}
filterChecked={this.state.filter}
Expand Down
15 changes: 11 additions & 4 deletions src/components/QuestionnaireForm/QuestionnaireForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default class QuestionnaireForm extends Component {
this.patientId = props.patientId;
this.fhirVersion = props.fhirVersion;
this.FHIR_PREFIX = props.FHIR_PREFIX;
this.appContext = props.appContext;
this.partialForms = {};
this.handleGtable = this.handleGtable.bind(this);
this.getLibraryPrepopulationResult = this.getLibraryPrepopulationResult.bind(this);
Expand All @@ -61,7 +62,7 @@ export default class QuestionnaireForm extends Component {

componentWillMount() {
// search for any partially completed QuestionnaireResponses
if (this.props.standalone) {
if (this.props.response) {
const response = this.props.response;
const items = this.props.qform.item;
const parentItems = [];
Expand Down Expand Up @@ -226,8 +227,14 @@ export default class QuestionnaireForm extends Component {

let count = 0;

partialResponses.entry.forEach(r => {
if (r.resource.questionnaire.includes(this.props.qform.id)) {
partialResponses.entry.forEach(bundleEntry => {
let questionnaireId = null;
if(bundleEntry.resource.contained) {
questionnaireId = bundleEntry.resource?.contained[0]?.id;
}
const questionaireIdUrl = bundleEntry.resource.questionnaire;

if (this.props.qform.id === questionnaireId || questionaireIdUrl.includes(this.props.qform.id)) {
count = count + 1;
// add the option to the popupOptions
let date = new Date(bundleEntry.resource.authored);
Expand Down Expand Up @@ -905,7 +912,7 @@ export default class QuestionnaireForm extends Component {
};
this.addAuthorToResponse(qr, this.getPractitioner());

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

const request = this.props.deviceRequest;
Expand Down
2 changes: 0 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ tokenPost.onload = function() {
// too badly.
ReactDOM.render(
<App
FHIR_PREFIX={appContext.fhirpath}
FILE_PREFIX={appContext.filepath}
appContext={appContext}
standalone={standalone}
smart={smart}
Expand Down
Loading