diff --git a/.github/workflows/docker-cd-dev.yml b/.github/workflows/docker-cd-dev.yml
index cb807a3f..3bb6c929 100644
--- a/.github/workflows/docker-cd-dev.yml
+++ b/.github/workflows/docker-cd-dev.yml
@@ -27,4 +27,4 @@ jobs:
context: .
platforms: linux/amd64,linux/arm64
push: true
- tags: codexrems/crd-request-generator:REMSvCurrent
+ tags: codexrems/request-generator:REMSvCurrent
diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml
index 5a327945..ee467398 100644
--- a/.github/workflows/docker-cd.yml
+++ b/.github/workflows/docker-cd.yml
@@ -27,4 +27,4 @@ jobs:
context: .
platforms: linux/amd64,linux/arm64
push: true
- tags: codexrems/crd-request-generator:REMSvCurrent
+ tags: codexrems/request-generator:REMSvCurrent
diff --git a/.github/workflows/docker-tag-cd.yml b/.github/workflows/docker-tag-cd.yml
index a9a19b76..b695536d 100644
--- a/.github/workflows/docker-tag-cd.yml
+++ b/.github/workflows/docker-tag-cd.yml
@@ -23,7 +23,7 @@ jobs:
id: meta
uses: docker/metadata-action@v4
with:
- images: codexrems/crd-request-generator
+ images: codexrems/request-generator
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 624ae545..2b18427d 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -7,11 +7,11 @@
{
"type": "chrome",
"request": "launch",
- "name": "Debug CRD-Request-Generator (Launch Docker)",
+ "name": "Debug Request-Generator (Launch Docker)",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}",
"sourceMapPathOverrides": {
- "/home/node/app/crd-request-generator/*": "${webRoot}/*",
+ "/home/node/app/request-generator/*": "${webRoot}/*",
},
"runtimeArgs": [
"--remote-debugging-port=9222"
@@ -20,18 +20,18 @@
{
"type": "chrome",
"request": "attach",
- "name": "Debug CRD-Request-Generator (Attach Docker)",
+ "name": "Debug Request-Generator (Attach Docker)",
"port": 9222,
"urlFilter": "http://localhost:3000/*",
"webRoot": "${workspaceFolder}",
"sourceMapPathOverrides": {
- "/home/node/app/crd-request-generator/*": "${webRoot}/*",
+ "/home/node/app/request-generator/*": "${webRoot}/*",
}
},
{
"type": "chrome",
"request": "launch",
- "name": "Debug CRD-Request-Generator (Launch Local)",
+ "name": "Debug Request-Generator (Launch Local)",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}",
"runtimeArgs": [
@@ -42,7 +42,7 @@
"type": "chrome",
"request": "attach",
"port": 9222,
- "name": "Debug CRD-Request-Generator (Attach Local)",
+ "name": "Debug Request-Generator (Attach Local)",
"urlFilter": "http://localhost:3000/*",
"webRoot": "${workspaceFolder}",
}
diff --git a/Dockerfile b/Dockerfile
index 1e73e6af..efc4563f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
FROM node:14-alpine
-WORKDIR /home/node/app/crd-request-generator
+WORKDIR /home/node/app/request-generator
COPY --chown=node:node . .
RUN npm install
COPY --chown=node:node . .
diff --git a/Dockerfile.dev b/Dockerfile.dev
index fa117b4f..2d637e9b 100644
--- a/Dockerfile.dev
+++ b/Dockerfile.dev
@@ -1,5 +1,5 @@
FROM node:14-alpine
-WORKDIR /home/node/app/crd-request-generator
+WORKDIR /home/node/app/request-generator
COPY --chown=node:node . .
RUN npm install
EXPOSE 3000
diff --git a/README.md b/README.md
index c7acb0f4..ba9f4c6f 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-# CRD Request Generator
-This subproject provides a small web application that is capable of generating CRD requests and displaying the CDS Hooks cards that are provided as a response. This project is written in JavaScript and runs in [node.js](https://nodejs.org/en/).
+# Request Generator
+This subproject provides a small web application that is capable of generating requests and displaying the CDS Hooks cards that are provided as a response. This project is written in JavaScript and runs in [node.js](https://nodejs.org/en/).
## Running the request generator standalone
1. Install node.js
2. Clone the repository
- * `git clone https://github.com/mcode/crd-request-generator.git`
+ * `git clone https://github.com/mcode/request-generator.git`
3. Install the dependencies
* `cd request-generator`
* `npm install`
diff --git a/src/components/ConsoleBox/ConsoleBox.js b/src/components/ConsoleBox/ConsoleBox.js
index e637834b..fed877d4 100644
--- a/src/components/ConsoleBox/ConsoleBox.js
+++ b/src/components/ConsoleBox/ConsoleBox.js
@@ -1,3 +1,4 @@
+import { Button } from '@mui/material';
import React, {Component} from 'react';
export default class ConsoleBox extends Component {
@@ -46,17 +47,15 @@ export default class ConsoleBox extends Component {
let i = 0;
return (
-
-
-
-
-
-
- {this.props.logs.map(element => {
- i++;
- return
{element.content}
- }) }
-
+
+
+ {this.props.logs.map(element => {
+ i++;
+ return
{element.content}
+ }) }
+
)
diff --git a/src/components/ConsoleBox/consoleBox.css b/src/components/ConsoleBox/consoleBox.css
index d6a68ce2..69359024 100644
--- a/src/components/ConsoleBox/consoleBox.css
+++ b/src/components/ConsoleBox/consoleBox.css
@@ -45,22 +45,12 @@
transition-delay: 0s;
}
-.showHeader:hover{
- color:#CCCCCC;
-}
-
.showHeader{
width:100%;
}
-.showHeader::after{
- content:"-";
-}
-.collapseHeader::after{
- content:"+";
-}
.collapseHeader{
- width:25px;
+ width: 250px;
color: black;
text-align:center;
border-width: 1px 1px 1px 1px;
diff --git a/src/components/DisplayBox/DisplayBox.js b/src/components/DisplayBox/DisplayBox.js
index 735a9ea8..761a1196 100644
--- a/src/components/DisplayBox/DisplayBox.js
+++ b/src/components/DisplayBox/DisplayBox.js
@@ -1,12 +1,11 @@
-import React, {Component} from 'react';
+import React, { Component } from 'react';
import FHIR from "fhirclient";
-import styles from './card-list.css';
-import Button from 'terra-button';
-import TerraCard from 'terra-card';
-import Text from 'terra-text';
+import './card-list.css';
+import { Button, Card, CardActions, CardContent, Typography } from '@mui/material';
import PropTypes from 'prop-types';
import axios from 'axios';
import ReactMarkdown from 'react-markdown';
+import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf';
import { retrieveLaunchContext } from '../../util/util';
import './displayBox.css';
@@ -164,8 +163,9 @@ export default class DisplayBox extends Component{
* Prevent the source link from opening in the same tab
* @param {*} e - Event emitted when source link is clicked
*/
- launchSource(e) {
+ launchSource(e, link) {
e.preventDefault();
+ window.open(link.url, '_blank');
}
exitSmart(e) {
@@ -231,23 +231,23 @@ export default class DisplayBox extends Component{
if (!source.label) { return null; }
let icon;
if (source.icon) {
- icon =
;
+ icon =
;
}
if (!this.props.isDemoCard) {
return (
-
- Source:
this.launchSource(e)}>{source.label}
+
);
}
return (
-
+
Source:
this.launchSource(e)}
+ onClick={e => this.launchSource(e, source)}
>
{source.label}
@@ -280,13 +280,13 @@ export default class DisplayBox extends Component{
const card = JSON.parse(JSON.stringify(c));
// -- Summary --
- const summarySection =
{card.summary};
+ const summarySection =
{card.summary}
;
// -- Source --
const sourceSection = card.source && Object.keys(card.source).length ? this.renderSource(card.source) : '';
// -- Detail (ReactMarkdown supports Github-flavored markdown) --
- const detailSection = card.detail ?
:
None;
+ const detailSection = card.detail ?
:
None
;
// -- Suggestions --
let suggestionsSection = [];
@@ -299,10 +299,9 @@ export default class DisplayBox extends Component{
);
});
}
@@ -311,54 +310,75 @@ export default class DisplayBox extends Component{
let linksSection;
if (card.links) {
card.links = this.modifySmartLaunchUrls(card) || card.links;
- linksSection = card.links.map((link, ind) => (
-
- Code: {this.state.code ? this.state.code : "N/A"}
+ Code: {this.state.code ? this.state.code : this.emptyField}
System:{" "}
- {this.state.codeSystem ? shortNameMap[this.state.codeSystem] : "N/A"}
+ {this.state.codeSystem ? shortNameMap[this.state.codeSystem] : this.emptyField}
- Display: {this.state.display ? this.state.display : "N/A"}
+ Display: {this.state.display ? this.state.display : this.emptyField}
);
@@ -191,16 +201,22 @@ export default class RequestBox extends Component {
const qrResponse = this.state.response;
return (
-
- In Progress Form
-
-
Form: { qrResponse.questionnaire ? qrResponse.questionnaire : "N/A"}
-
- Author: {qrResponse.author ? qrResponse.author.reference : "N/A"}
-
-
- Date: {qrResponse.authored ? qrResponse.authored : "N/A"}
-
+ {qrResponse.questionnaire ?
+ <>
+
+ In Progress Form
+
+
Form: { qrResponse.questionnaire ? qrResponse.questionnaire : this.emptyField}
+
+ Author: {qrResponse.author ? qrResponse.author.reference : this.emptyField}
+
+
+ Date: {qrResponse.authored ? qrResponse.authored : this.emptyField}
+
+ >
+ :
+
+ }
);
}
@@ -417,7 +433,7 @@ export default class RequestBox extends Component {
params['tokenResponse'] = {access_token: this.props.access_token.access_token};
}
const disableSendToCRD = this.isOrderNotSelected() || this.props.loading ;
- const disableLaunchDTR = this.isOrderNotSelected() && Object.keys(this.state.response).length === 0;
+ const disableLaunchDTR = !this.state.response.questionnaire;
const disableSendRx = this.isOrderNotSelected() || this.props.loading;
const disableLaunchSmartOnFhir = this.isPatientNotSelected();
return (
@@ -456,41 +472,39 @@ export default class RequestBox extends Component {
)}
-
- Patient Select:
-
+
}>
+ Select a patient
+
- {this.state.patient.id ? this.state.patient.id : "N/A"}
+ {this.state.patient.id ? Patient ID: {this.state.patient.id} : No patient selected}
{this.renderPatientInfo()}
{this.renderPrefetchedResources()}
-
- Deidentify Records
-
-
+
+ {this.state.patient.id ?
+
+ Deidentify Records
+
+
:
+ }
-
-
- Launch SMART on FHIR App
-
-
- Send Rx to PIMS
-
-
- Relaunch DTR
-
-
- Submit to REMS-Admin
-
+ {this.state.patient.id ?
+
+
+ Open In-Progress Form
+ Launch SMART on FHIR App
+ Send Rx to Pharmacy
+ Sign Order
+
+
+ : }
);
}
diff --git a/src/components/RequestBox/request.css b/src/components/RequestBox/request.css
index b31ead0b..0e1e0845 100644
--- a/src/components/RequestBox/request.css
+++ b/src/components/RequestBox/request.css
@@ -1,4 +1,6 @@
.request-header{
+ margin-top: 10px;
+ margin-left: 8px;
border-width: 1px 1px 2px 2px;
border-style: solid;
border-color: transparent transparent black black;
@@ -117,4 +119,13 @@
.questionnaire-response {
width: 100%;
padding:10px 10px 10px 0px;
+}
+
+.action-btns {
+ margin-top: 5px;
+}
+
+.empty-field {
+ color: dimgrey;
+ font-style: italic;
}
\ No newline at end of file
diff --git a/src/components/SMARTBox/PatientBox.js b/src/components/SMARTBox/PatientBox.js
index 13018ff6..4d07a1c2 100644
--- a/src/components/SMARTBox/PatientBox.js
+++ b/src/components/SMARTBox/PatientBox.js
@@ -3,7 +3,8 @@ import { Dropdown, Header } from 'semantic-ui-react'
import { getAge } from "../../util/fhir";
import FHIR from "fhirclient";
import "./smart.css";
-
+import { Button, IconButton } from '@mui/material';
+import RefreshIcon from '@mui/icons-material/Refresh';
export default class SMARTBox extends Component {
constructor(props) {
@@ -31,6 +32,12 @@ export default class SMARTBox extends Component {
this.handleResponseChange = this.handleResponseChange.bind(this);
}
+ componentDidMount() {
+ // get requests and responses on open of patients
+ this.getRequests()
+ this.getResponses();
+ }
+
getCoding(request) {
let code = null;
if (request.resourceType === "DeviceRequest") {
@@ -64,7 +71,7 @@ export default class SMARTBox extends Component {
let option = {
key: request.id,
- text: "(" + code.code + ") " + code.display,
+ text: code.display + " (Medication request: " + code.code + ")",
value: JSON.stringify(request),
content: (
@@ -256,31 +263,33 @@ export default class SMARTBox extends Component {
let returned = false;
if (this.state.deviceRequests.data) {
returned = true;
- console.log(this.state.deviceRequests);
this.state.deviceRequests.data.forEach((e) => {
this.makeOption(e, options);
});
}
if (this.state.serviceRequests.data) {
+ returned = true;
this.state.serviceRequests.data.forEach((e) => {
this.makeOption(e, options);
});
}
if (this.state.medicationRequests.data) {
+ returned = true;
this.state.medicationRequests.data.forEach((e) => {
this.makeOption(e, options);
});
}
if (this.state.medicationDispenses.data) {
+ returned = true;
this.state.medicationDispenses.data.forEach((e) => {
this.makeOption(e, options);
})
};
if (this.state.questionnaireResponses.data) {
- returned = true;
this.state.questionnaireResponses.data.forEach(qr => this.makeQROption(qr, responseOptions));
+ returned = true;
}
let noResults = 'No results found.'
@@ -293,15 +302,9 @@ export default class SMARTBox extends Component {
{
- this.updateValues(patient);
- }}
>
ID: {patient.id}
- {/*
- {text}
- */}
Name:{" "}
{name ? name : "N/A"}
@@ -319,28 +322,37 @@ export default class SMARTBox extends Component {
Request:
-
+ { !options.length && returned ?
+ No reqeusts
+ :
+
+ }
-
+
In Progress Form:
+
+
+
-
+ { !responseOptions.length && returned ?
+ No in progress forms :
+
+ }
+
this.updateValues(patient)}>Select
);
diff --git a/src/components/SMARTBox/smart.css b/src/components/SMARTBox/smart.css
index cdef0b26..0bb23c26 100644
--- a/src/components/SMARTBox/smart.css
+++ b/src/components/SMARTBox/smart.css
@@ -19,16 +19,12 @@ iframe{
.patient-selection-box{
width:100%;
- height:100px;
padding:10px;
flex:.5;
border-bottom:3px solid black;
- background-color:#e2e2e2;
-}
-
-.patient-selection-box:hover{
- background-color:white;
- cursor: pointer;
+ display: grid;
+ grid-template-columns: 15% 35% 35% 10%;
+ column-gap: 5px;
}
.smartExit{
@@ -74,13 +70,10 @@ iframe{
.patient-info {
display:inline-block;
- width: 300px;
}
.request-info {
- display: inline-block;
- width:350px;
- vertical-align: top; /* here */
+ display: inherit;
}
@@ -93,4 +86,23 @@ iframe{
}
.ui.header.text {
font-size: 1em;
+}
+
+.select-btn {
+ height: 40px;
+ align-self: center;
+}
+
+.emptyForm {
+ margin-left: 8px;
+ color: dimgray;
+ font-style: italic;
+}
+
+.ui.fluid.dropdown {
+ height: fit-content;
+}
+
+.ui.dropdown>.text {
+ display: block;
}
\ No newline at end of file
diff --git a/src/containers/RequestBuilder.js b/src/containers/RequestBuilder.js
index 4f794a72..5473188f 100644
--- a/src/containers/RequestBuilder.js
+++ b/src/containers/RequestBuilder.js
@@ -148,6 +148,7 @@ export default class RequestBuilder extends Component {
}).then(response => {
clearTimeout(this.timeout)
response.json().then((fhirResponse) => {
+ console.log(fhirResponse);
if (fhirResponse && fhirResponse.status) {
this.consoleLog("Server returned status "
+ fhirResponse.status + ": "
@@ -160,6 +161,7 @@ export default class RequestBuilder extends Component {
})
}).catch(() => {
this.consoleLog("No response received from the server", types.error);
+ this.setState({ response: null });
this.setState({loading: false});
});
} catch (error) {
@@ -391,16 +393,9 @@ export default class RequestBuilder extends Component {
return (
- this.updateStateElement("ehrLaunch", true)}>EHR Launch
- this.updateStateElement("ehrLaunch", false)}>Standalone
this.updateStateElement("showSettings", !this.state.showSettings)}>
-
- {/* {this.state.ehrLaunch?
-
-
- :null} */}
- {/*
- Submit
- */}
- {/*
-
-
-
-
-
-
*/}
+
+
+
diff --git a/src/index.css b/src/index.css
index ba377cd9..ce75eedf 100644
--- a/src/index.css
+++ b/src/index.css
@@ -308,6 +308,7 @@ input:not(:focus):not([value=""]):valid ~ .floating-label{
.nav-header{
margin-bottom: 10px;
+ height: 55px;
padding:10px;
border-bottom: 1px solid black;
background-color: #005B94;