From d71d5ec09cde45371f53c7600d93b3a7a5265c69 Mon Sep 17 00:00:00 2001 From: Ariel Virgulto Date: Thu, 21 Dec 2023 08:32:10 -0600 Subject: [PATCH 1/5] Migrate to accordian, update styling/functionality --- .../PatientSearchBar/PatientSearchBar.js | 8 +- src/components/RequestBox/RequestBox.js | 87 +++++++++++-------- src/components/RequestBox/request.css | 6 +- src/components/SMARTBox/PatientBox.js | 2 + 4 files changed, 64 insertions(+), 39 deletions(-) diff --git a/src/components/RequestBox/PatientSearchBar/PatientSearchBar.js b/src/components/RequestBox/PatientSearchBar/PatientSearchBar.js index 123ed142..3e1a38bf 100644 --- a/src/components/RequestBox/PatientSearchBar/PatientSearchBar.js +++ b/src/components/RequestBox/PatientSearchBar/PatientSearchBar.js @@ -57,7 +57,7 @@ export default function PatientSearchBar(props) { {filteredListOfPatients.map(patient => { return ( -
+ item.id === patient.id)} @@ -72,7 +72,7 @@ export default function PatientSearchBar(props) { responseExpirationDays={props.responseExpirationDays} defaultUser={props.defaultUser} /> -
+ ); })}
@@ -80,8 +80,8 @@ export default function PatientSearchBar(props) { } return ( -
+ {listOfPatients[0] ? patientSearchBar() : 'loading...'} -
+ ); } \ No newline at end of file diff --git a/src/components/RequestBox/RequestBox.js b/src/components/RequestBox/RequestBox.js index 35deb168..da62d35b 100644 --- a/src/components/RequestBox/RequestBox.js +++ b/src/components/RequestBox/RequestBox.js @@ -8,31 +8,36 @@ import { getAge } from '../../util/fhir'; import { retrieveLaunchContext } from '../../util/util'; import './request.css'; import InProgressFormBox from './InProgressFormBox/InProgressFormBox.js'; +import Accordion from '@mui/material/Accordion'; +import AccordionSummary from '@mui/material/AccordionSummary'; +import AccordionDetails from '@mui/material/AccordionDetails'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import PatientSearchBar from './PatientSearchBar/PatientSearchBar.js'; -const style = { - position: 'absolute', - top: '50%', - left: '50%', - flexDirection: 'column', - width: '80%', - height: '70%', - overflowY: 'scroll', - transform: 'translate(-50%, -50%)', - display: 'flex', - bgcolor: 'background.paper', - border: '2px solid #000', - borderBottom: '2px solid black', - boxShadow: 24, - p: 4, - padding: '50px' -}; +// const style = { +// position: 'absolute', +// top: '50%', +// left: '50%', +// flexDirection: 'column', +// width: '80%', +// height: '70%', +// overflowY: 'scroll', +// transform: 'translate(-50%, -50%)', +// display: 'flex', +// bgcolor: 'background.paper', +// border: '2px solid #000', +// borderBottom: '2px solid black', +// boxShadow: 24, +// p: 4, +// padding: '50px' +// }; export default class RequestBox extends Component { constructor(props) { super(props); this.state = { openPatient: false, + expanded: false, patientList: [], patient: {}, prefetchedResources: new Map(), @@ -157,13 +162,16 @@ export default class RequestBox extends Component { getPatients = () => { + console.log('getting patients -- > ', this.props.patientFhirQuery); this.props.client .request(this.props.patientFhirQuery, { flat: true }) .then(result => { + console.log('result is -- > ', result); this.setState({ patientList: result, - openPatient: true + // openPatient: true, + expanded: true }); }) .catch(e => { @@ -432,6 +440,13 @@ export default class RequestBox extends Component { return Object.keys(this.state.patient).length === 0; } + handleChange = (panel) => (event, isExpanded) => { + if (isExpanded) { + this.getPatients(); + } + this.setState({ expanded: isExpanded ? true: false}); + }; + render() { const disableSendToCRD = this.isOrderNotSelected() || this.props.loading; const disableSendRx = this.isOrderNotSelected() || this.props.loading; @@ -439,15 +454,19 @@ export default class RequestBox extends Component { return (
- - + } + aria-controls="panel1a-content" + id="panel1a-header" > - {/* Patient selection pop up and search */} - + + + +
+ {this.state.patientList instanceof Error ? this.renderError() : } - -
- +
+ + +
{this.state.patient.id ? ( Patient ID: {this.state.patient.id} @@ -477,13 +495,12 @@ export default class RequestBox extends Component { No patient selected )}
-
+
{this.renderPatientInfo()} {this.renderPrefetchedResources()}
-
- {this.state.patient.id ? ( + {this.state.patient.id ? (
)} +
+
); } diff --git a/src/components/RequestBox/request.css b/src/components/RequestBox/request.css index 2da628c9..c0a3d539 100644 --- a/src/components/RequestBox/request.css +++ b/src/components/RequestBox/request.css @@ -12,7 +12,7 @@ .request { border: 1px solid black; - height:375px; + height: auto; padding: 10px; border-radius: 5px; background-color: rgb(248, 248, 248) @@ -123,4 +123,8 @@ .empty-field { color: dimgrey; font-style: italic; +} + +.patient-info { + margin: 5px; } \ No newline at end of file diff --git a/src/components/SMARTBox/PatientBox.js b/src/components/SMARTBox/PatientBox.js index af8001ff..509aa7a0 100644 --- a/src/components/SMARTBox/PatientBox.js +++ b/src/components/SMARTBox/PatientBox.js @@ -140,6 +140,7 @@ export default class PatientBox extends Component { const response = JSON.parse(this.state.response); this.updateQRResponse(patient, response); } + this.props.callback('expanded', false); } updateQRResponse(patient, response) { @@ -389,6 +390,7 @@ export default class PatientBox extends Component { render() { const patient = this.props.patient; + console.log('patient --- > ', patient); let name = ''; if (patient.name) { name = {`${patient.name[0].given[0]} ${patient.name[0].family}`} ; From b68d25ec4b240d1e9080a075c070e3ad915ab759 Mon Sep 17 00:00:00 2001 From: Ariel Virgulto Date: Thu, 21 Dec 2023 09:17:50 -0600 Subject: [PATCH 2/5] Clear out state before new query --- .../InProgressFormBoxStyle.css | 3 --- src/components/RequestBox/RequestBox.js | 21 +++++++------------ src/components/SMARTBox/PatientBox.js | 4 +--- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/components/RequestBox/InProgressFormBox/InProgressFormBoxStyle.css b/src/components/RequestBox/InProgressFormBox/InProgressFormBoxStyle.css index 4e8b3eea..ceea9016 100644 --- a/src/components/RequestBox/InProgressFormBox/InProgressFormBoxStyle.css +++ b/src/components/RequestBox/InProgressFormBox/InProgressFormBoxStyle.css @@ -4,7 +4,4 @@ border-radius: 5px; padding:20px; margin:20px 0 20px 0; - - /* This should be inherited, need to change */ - width:48.5vw; } \ No newline at end of file diff --git a/src/components/RequestBox/RequestBox.js b/src/components/RequestBox/RequestBox.js index da62d35b..63bb9b29 100644 --- a/src/components/RequestBox/RequestBox.js +++ b/src/components/RequestBox/RequestBox.js @@ -36,7 +36,6 @@ export default class RequestBox extends Component { constructor(props) { super(props); this.state = { - openPatient: false, expanded: false, patientList: [], patient: {}, @@ -68,10 +67,6 @@ export default class RequestBox extends Component { componentDidMount() { } - exitSmart = () => { - this.setState({ openPatient: false }); - }; - prepPrefetch() { const preppedResources = new Map(); Object.keys(this.state.prefetchedResources).forEach(resourceKey => { @@ -161,16 +156,11 @@ export default class RequestBox extends Component { }; getPatients = () => { - - console.log('getting patients -- > ', this.props.patientFhirQuery); - this.props.client .request(this.props.patientFhirQuery, { flat: true }) .then(result => { - console.log('result is -- > ', result); this.setState({ patientList: result, - // openPatient: true, expanded: true }); }) @@ -440,9 +430,14 @@ export default class RequestBox extends Component { return Object.keys(this.state.patient).length === 0; } - handleChange = (panel) => (event, isExpanded) => { + handleChange = () => (event, isExpanded) => { if (isExpanded) { this.getPatients(); + } else { + this.setState({ + patientList: [], + expanded: false + }); } this.setState({ expanded: isExpanded ? true: false}); }; @@ -454,7 +449,7 @@ export default class RequestBox extends Component { return (
- + } aria-controls="panel1a-content" @@ -483,7 +478,7 @@ export default class RequestBox extends Component { responseExpirationDays={this.props.responseExpirationDays} defaultUser={this.props.defaultUser} />} - +
diff --git a/src/components/SMARTBox/PatientBox.js b/src/components/SMARTBox/PatientBox.js index 509aa7a0..b95d49c1 100644 --- a/src/components/SMARTBox/PatientBox.js +++ b/src/components/SMARTBox/PatientBox.js @@ -118,7 +118,7 @@ export default class PatientBox extends Component { updateValues(patient) { this.props.callback('patient', patient); - this.props.callback('openPatient', false); + this.props.callback('expanded', false); this.props.clearCallback(); if (this.state.request) { const request = JSON.parse(this.state.request); @@ -140,7 +140,6 @@ export default class PatientBox extends Component { const response = JSON.parse(this.state.response); this.updateQRResponse(patient, response); } - this.props.callback('expanded', false); } updateQRResponse(patient, response) { @@ -324,7 +323,6 @@ export default class PatientBox extends Component { } getRequests() { - console.log(this.props.client); const patientId = this.props.patient.id; this.getDeviceRequest(patientId); this.getServiceRequest(patientId); From b1920b9042bcbc6d1a8a9632a22eba70630d5867 Mon Sep 17 00:00:00 2001 From: Ariel Virgulto Date: Tue, 26 Dec 2023 09:50:25 -0600 Subject: [PATCH 3/5] Update workflow of select a patient and update call of patients --- .../PatientSearchBar/PatientSearchBar.js | 38 ++- .../PatientSearchBarStyle.css | 11 +- src/components/RequestBox/RequestBox.js | 257 +++++------------- src/components/RequestBox/request.css | 2 +- src/components/SMARTBox/PatientBox.js | 5 +- src/containers/RequestBuilder.js | 134 ++++++++- src/index.css | 13 +- 7 files changed, 235 insertions(+), 225 deletions(-) diff --git a/src/components/RequestBox/PatientSearchBar/PatientSearchBar.js b/src/components/RequestBox/PatientSearchBar/PatientSearchBar.js index 3e1a38bf..250428f4 100644 --- a/src/components/RequestBox/PatientSearchBar/PatientSearchBar.js +++ b/src/components/RequestBox/PatientSearchBar/PatientSearchBar.js @@ -24,20 +24,37 @@ export default function PatientSearchBar(props) { } return ''; } + + function getFilteredLength(searchstring, listOfPatients) { + const filteredListOfPatients = listOfPatients[0].filter((element) => { + if (searchstring === '') { + return element; + } + else { + return element.name.toLowerCase().includes(searchstring); + } + }); + + return filteredListOfPatients.length; + } function patientSearchBar() { return ( - { - setInput(newInputValue.toLowerCase()); - }} - options={listOfPatients[0].map(item => item.name)} - renderInput={(params) => } /> + +

Filter patient list

+ { + setInput(newInputValue.toLowerCase()); + }} + options={listOfPatients[0].map(item => item.name)} + renderInput={(params) => } /> +

Showing {getFilteredLength(input, listOfPatients)} of {props.searchablePatients.length} records

+
{displayFilteredPatientList(input, listOfPatients[0])}
); @@ -52,7 +69,6 @@ export default function PatientSearchBar(props) { return element.name.toLowerCase().includes(searchstring); } }); - return ( {filteredListOfPatients.map(patient => { diff --git a/src/components/RequestBox/PatientSearchBar/PatientSearchBarStyle.css b/src/components/RequestBox/PatientSearchBar/PatientSearchBarStyle.css index bcd1cac6..4908c658 100644 --- a/src/components/RequestBox/PatientSearchBar/PatientSearchBarStyle.css +++ b/src/components/RequestBox/PatientSearchBar/PatientSearchBarStyle.css @@ -3,10 +3,8 @@ } .search-box { - top: -10; - width: 100%; - margin: 10px auto; - margin-bottom: 50px; + width: 75%; + margin: 0px 10px 25px 20px; } .search-box-container { @@ -15,4 +13,9 @@ display: flex; flex-direction: column; justify-content: space-evenly +} + +.search-header { + display: flex; + align-items: center; } \ No newline at end of file diff --git a/src/components/RequestBox/RequestBox.js b/src/components/RequestBox/RequestBox.js index 63bb9b29..295cb316 100644 --- a/src/components/RequestBox/RequestBox.js +++ b/src/components/RequestBox/RequestBox.js @@ -1,52 +1,18 @@ -import PersonIcon from '@mui/icons-material/Person'; -import { Box, Button, ButtonGroup, Modal } from '@mui/material'; +import { Button, ButtonGroup } from '@mui/material'; import _ from 'lodash'; import React, { Component } from 'react'; import buildNewRxRequest from '../../util/buildScript.2017071.js'; -import { defaultValues, shortNameMap, types } from '../../util/data'; +import { shortNameMap, types } from '../../util/data'; import { getAge } from '../../util/fhir'; import { retrieveLaunchContext } from '../../util/util'; import './request.css'; import InProgressFormBox from './InProgressFormBox/InProgressFormBox.js'; -import Accordion from '@mui/material/Accordion'; -import AccordionSummary from '@mui/material/AccordionSummary'; -import AccordionDetails from '@mui/material/AccordionDetails'; -import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; - -import PatientSearchBar from './PatientSearchBar/PatientSearchBar.js'; - -// const style = { -// position: 'absolute', -// top: '50%', -// left: '50%', -// flexDirection: 'column', -// width: '80%', -// height: '70%', -// overflowY: 'scroll', -// transform: 'translate(-50%, -50%)', -// display: 'flex', -// bgcolor: 'background.paper', -// border: '2px solid #000', -// borderBottom: '2px solid black', -// boxShadow: 24, -// p: 4, -// padding: '50px' -// }; + export default class RequestBox extends Component { constructor(props) { super(props); this.state = { - expanded: false, - patientList: [], - patient: {}, - prefetchedResources: new Map(), - codeValues: defaultValues, - code: null, - codeSystem: null, - display: null, - request: {}, gatherCount: 0, - response: {} }; this.renderRequestResources = this.renderRequestResources.bind(this); @@ -60,8 +26,7 @@ export default class RequestBox extends Component { // TODO - see how to submit response for alternative therapy replaceRequestAndSubmit(request) { - this.setState({ request: request }); - // Submit the cds hook request. + this.props.callback(request,request); // Submit the cds hook request. this.submitOrderSign(request); } @@ -69,14 +34,14 @@ export default class RequestBox extends Component { prepPrefetch() { const preppedResources = new Map(); - Object.keys(this.state.prefetchedResources).forEach(resourceKey => { + Object.keys(this.props.prefetchedResources).forEach(resourceKey => { let resourceList = []; - if (Array.isArray(this.state.prefetchedResources[resourceKey])) { - resourceList = this.state.prefetchedResources[resourceKey].map(resource => { + if (Array.isArray(this.props.prefetchedResources[resourceKey])) { + resourceList = this.props.prefetchedResources[resourceKey].map(resource => { return resource; }); } else { - resourceList = this.state.prefetchedResources[resourceKey]; + resourceList = this.props.prefetchedResources[resourceKey]; } preppedResources.set(resourceKey, resourceList); @@ -85,27 +50,27 @@ export default class RequestBox extends Component { } submitPatientView = () => { - this.props.submitInfo(this.prepPrefetch(), null, this.state.patient, 'patient-view'); + this.props.submitInfo(this.prepPrefetch(), null, this.props.patient, 'patient-view'); }; submitOrderSelect = () => { - if (!_.isEmpty(this.state.request)) { + if (!_.isEmpty(this.props.request)) { this.props.submitInfo( this.prepPrefetch(), - this.state.request, - this.state.patient, + this.props.request, + this.props.patient, 'order-select' ); } }; submitOrderSign = request => { - this.props.submitInfo(this.prepPrefetch(), request, this.state.patient, 'order-sign'); + this.props.submitInfo(this.prepPrefetch(), request, this.props.patient, 'order-sign'); }; submit = () => { - if (!_.isEmpty(this.state.request)) { - this.submitOrderSign(this.state.request); + if (!_.isEmpty(this.props.request)) { + this.submitOrderSign(this.props.request); } }; @@ -116,12 +81,12 @@ export default class RequestBox extends Component { this.state.prefetchCompleted ) { // if the prefetch contains a medicationRequests bundle - if (this.state.prefetchedResources.medicationRequests) { + if (this.props.prefetchedResources.medicationRequests) { this.submitPatientView(); } // we could use this in the future to send order-select //// if the prefetch contains a request - //if (this.state.prefetchedResources.request) { + //if (this.props.prefetchedResources.request) { // this.submitOrderSelect(); //} } @@ -131,50 +96,10 @@ export default class RequestBox extends Component { this.setState({ [elementName]: text }); }; - updateStateList = (elementName, text) => { - this.setState(prevState => { - return { [elementName]: [...prevState[elementName], text] }; - }); - }; - - updateStateMap = (elementName, key, text) => { - this.setState(prevState => { - if (!prevState[elementName][key]) { - prevState[elementName][key] = []; - } - return { [elementName]: { ...prevState[elementName], [key]: text } }; - }); - }; - - clearState = () => { - this.setState({ - prefetchedResources: new Map(), - practitioner: {}, - coverage: {}, - response: {} - }); - }; - - getPatients = () => { - this.props.client - .request(this.props.patientFhirQuery, { flat: true }) - .then(result => { - this.setState({ - patientList: result, - expanded: true - }); - }) - .catch(e => { - this.setState({ - patientList: e - }); - }); - }; - emptyField = (empty); renderPatientInfo() { - const patient = this.state.patient; + const patient = this.props.patient; if (Object.keys(patient).length === 0) { return
; } @@ -211,20 +136,20 @@ export default class RequestBox extends Component { Coding
- Code: {this.state.code ? this.state.code : this.emptyField} + Code: {this.props.code ? this.props.code : this.emptyField}
- System: {this.state.codeSystem ? shortNameMap[this.state.codeSystem] : this.emptyField} + System: {this.props.codeSystem ? shortNameMap[this.props.codeSystem] : this.emptyField}
- Display: {this.state.display ? this.state.display : this.emptyField} + Display: {this.props.display ? this.props.display : this.emptyField}
); } renderPrefetchedResources() { - const prefetchMap = new Map(Object.entries(this.state.prefetchedResources)); + const prefetchMap = new Map(Object.entries(this.props.prefetchedResources)); if (prefetchMap.size > 0) { return this.renderRequestResources(prefetchMap); } @@ -300,7 +225,7 @@ export default class RequestBox extends Component { launchSmartOnFhirApp = () => { console.log('Launch SMART on FHIR App'); - let userId = this.state.prefetchedResources?.practitioner?.id; + let userId = this.props.prefetchedResources?.practitioner?.id; if (!userId) { console.log( 'Practitioner not populated from prefetch, using default from config: ' + @@ -310,12 +235,12 @@ export default class RequestBox extends Component { } let link = { - appContext: 'user=' + userId + '&patient=' + this.state.patient.id, + appContext: 'user=' + userId + '&patient=' + this.props.patient.id, type: 'smart', url: this.props.smartAppUrl }; - retrieveLaunchContext(link, this.state.patient.id, this.props.client.state).then(result => { + retrieveLaunchContext(link, this.props.patient.id, this.props.client.state).then(result => { link = result; console.log(link); // launch the application in a new window @@ -341,10 +266,10 @@ export default class RequestBox extends Component { response = undefined; if (!this.isOrderNotSelected()) { - if (Object.keys(this.state.request).length > 0) { - order = `${this.state.request.resourceType}/${this.state.request.id}`; - if (this.state.request.insurance && this.state.request.insurance.length > 0) { - coverage = `${this.state.request.insurance[0].reference}`; + if (Object.keys(this.props.request).length > 0) { + order = `${this.props.request.resourceType}/${this.props.request.id}`; + if (this.props.request.insurance && this.props.request.insurance.length > 0) { + coverage = `${this.props.request.insurance[0].reference}`; } } } @@ -357,8 +282,8 @@ export default class RequestBox extends Component { } } - if (Object.keys(this.state.response).length > 0) { - response = `QuestionnaireResponse/${this.state.response.id}`; + if (Object.keys(this.props.response).length > 0) { + response = `QuestionnaireResponse/${this.props.response.id}`; } if (order && response) { @@ -375,7 +300,7 @@ export default class RequestBox extends Component { let linkCopy = Object.assign({}, link); - return retrieveLaunchContext(linkCopy, this.state.patient.id, this.props.client.state).then( + return retrieveLaunchContext(linkCopy, this.props.patient.id, this.props.client.state).then( result => { linkCopy = result; return linkCopy; @@ -391,9 +316,9 @@ export default class RequestBox extends Component { // build the NewRx Message var newRx = buildNewRxRequest( - this.state.prefetchedResources.patient, - this.state.prefetchedResources.practitioner, - this.state.request + this.props.prefetchedResources.patient, + this.props.prefetchedResources.practitioner, + this.props.request ); console.log(newRx); const serializer = new XMLSerializer(); @@ -423,101 +348,51 @@ export default class RequestBox extends Component { }; isOrderNotSelected() { - return Object.keys(this.state.request).length === 0; + return Object.keys(this.props.request).length === 0; } isPatientNotSelected() { - return Object.keys(this.state.patient).length === 0; + return Object.keys(this.props.patient).length === 0; } - handleChange = () => (event, isExpanded) => { - if (isExpanded) { - this.getPatients(); - } else { - this.setState({ - patientList: [], - expanded: false - }); - } - this.setState({ expanded: isExpanded ? true: false}); - }; - render() { const disableSendToCRD = this.isOrderNotSelected() || this.props.loading; const disableSendRx = this.isOrderNotSelected() || this.props.loading; const disableLaunchSmartOnFhir = this.isPatientNotSelected(); return (
-
- - } - aria-controls="panel1a-content" - id="panel1a-header" - > - - - -
- - {this.state.patientList instanceof Error - ? this.renderError() - : } - -
-
-
-
-
- {this.state.patient.id ? ( - Patient ID: {this.state.patient.id} - ) : ( - No patient selected - )} -
-
- {this.renderPatientInfo()} - {this.renderPrefetchedResources()} -
-
- {this.state.patient.id ? ( -
- - - - - - + { this.props.patient.id ? ( +
+
+
+ Patient ID: {this.props.patient.id} +
+
+ {this.renderPatientInfo()} + {this.renderPrefetchedResources()} +
+
+
+ + + + + + +
) : ( - + )} -
-
); } diff --git a/src/components/RequestBox/request.css b/src/components/RequestBox/request.css index c0a3d539..14b6aedd 100644 --- a/src/components/RequestBox/request.css +++ b/src/components/RequestBox/request.css @@ -15,7 +15,7 @@ height: auto; padding: 10px; border-radius: 5px; - background-color: rgb(248, 248, 248) + background-color: rgb(248, 248, 248); } .select-button{ diff --git a/src/components/SMARTBox/PatientBox.js b/src/components/SMARTBox/PatientBox.js index b95d49c1..ea337028 100644 --- a/src/components/SMARTBox/PatientBox.js +++ b/src/components/SMARTBox/PatientBox.js @@ -134,6 +134,10 @@ export default class PatientBox extends Component { } } else { this.updatePrefetchRequest(null, patient, this.props.defaultUser); + this.props.callback('request', {}); + this.props.callback('code', null); + this.props.callback('codeSystem', null); + this.props.callback('display', null); } if (this.state.response) { @@ -388,7 +392,6 @@ export default class PatientBox extends Component { render() { const patient = this.props.patient; - console.log('patient --- > ', patient); let name = ''; if (patient.name) { name = {`${patient.name[0].given[0]} ${patient.name[0].family}`} ; diff --git a/src/containers/RequestBuilder.js b/src/containers/RequestBuilder.js index adecf489..99fd6d66 100644 --- a/src/containers/RequestBuilder.js +++ b/src/containers/RequestBuilder.js @@ -1,16 +1,23 @@ import React, { Component } from 'react'; - +import { Button, Box, IconButton } from '@mui/material'; +import PersonIcon from '@mui/icons-material/Person'; +import RefreshIcon from '@mui/icons-material/Refresh'; import DisplayBox from '../components/DisplayBox/DisplayBox'; -import ConsoleBox from '../components/ConsoleBox/ConsoleBox'; import '../index.css'; import '../components/ConsoleBox/consoleBox.css'; import SettingsBox from '../components/SettingsBox/SettingsBox'; import RequestBox from '../components/RequestBox/RequestBox'; import buildRequest from '../util/buildRequest.js'; -import { types } from '../util/data.js'; +import { types, defaultValues } from '../util/data.js'; import { createJwt, setupKeys } from '../util/auth'; import env from 'env-var'; import FHIR from 'fhirclient'; +import Accordion from '@mui/material/Accordion'; +import AccordionSummary from '@mui/material/AccordionSummary'; +import AccordionDetails from '@mui/material/AccordionDetails'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; + +import PatientSearchBar from '../components/RequestBox/PatientSearchBar/PatientSearchBar'; export default class RequestBuilder extends Component { constructor(props) { @@ -19,11 +26,19 @@ export default class RequestBuilder extends Component { keypair: null, loading: false, logs: [], - patient: {}, + patient: {}, + expanded: false, + patientList: [], response: null, + code: null, + codeSystem: null, + display: null, + prefetchedResources: new Map(), + request: {}, showSettings: false, token: null, client: this.props.client, + codeValues: defaultValues, // Configurable values alternativeTherapy: env.get('REACT_APP_ALT_DRUG').asBool(), baseUrl: env.get('REACT_APP_EHR_BASE').asString(), @@ -63,6 +78,8 @@ export default class RequestBuilder extends Component { if (!this.state.client) { this.reconnectEhr(); } else { + // Call patients on load of page + this.getPatients(); this.setState({ baseUrl: this.state.client.state.serverUrl }); this.setState({ ehrUrl: this.state.client.state.serverUrl }); } @@ -90,8 +107,15 @@ export default class RequestBuilder extends Component { updateStateElement = (elementName, text) => { this.setState({ [elementName]: text }); + // if the patientFhirQuery is updated, make a call to get the patients + if (elementName === 'patientFhirQuery') { + setTimeout(() => { + this.getPatients(); + }, 1000); + } }; + timeout = time => { let controller = new AbortController(); setTimeout(() => controller.abort(), time * 1000); @@ -182,6 +206,48 @@ export default class RequestBuilder extends Component { this.requestBox.current.replaceRequestAndSubmit(resource); } + getPatients = () => { + this.props.client + .request(this.state.patientFhirQuery, { flat: true }) + .then(result => { + this.setState({ + patientList: result, + }); + }) + .catch(e => { + this.setState({ + patientList: e + }); + }); + }; + + updateStateList = (elementName, text) => { + this.setState(prevState => { + return { [elementName]: [...prevState[elementName], text] }; + }); + }; + + updateStateMap = (elementName, key, text) => { + this.setState(prevState => { + if (!prevState[elementName][key]) { + prevState[elementName][key] = []; + } + return { [elementName]: { ...prevState[elementName], [key]: text } }; + }); + }; + + clearState = () => { + this.setState({ + prefetchedResources: new Map(), + practitioner: {}, + coverage: {}, + response: {} + }); + }; + handleChange = () => (event, isExpanded) => { + this.setState({ expanded: isExpanded ? true: false}); + }; + render() { return (
@@ -203,6 +269,53 @@ export default class RequestBuilder extends Component { Reconnect EHR
+
+ + } + aria-controls="panel1a-content" + id="panel1a-header" + style={{marginLeft: '45%'}} + > + + + + {this.state.patientList.length > 0 && this.state.expanded ? +
+ + {this.state.patientList instanceof Error + ? this.renderError() + : } + +
+ : + } + +
+
+ this.getPatients()} + size="large" + > + + +
{this.state.showSettings && ( @@ -222,6 +335,13 @@ export default class RequestBuilder extends Component { fhirServerUrl={this.state.baseUrl} fhirVersion={'r4'} patientId={this.state.patient.id} + patient={this.state.patient} + request={this.state.request} + response={this.state.response} + code={this.state.code} + codeSystem={this.state.codeSystem} + display={this.state.display} + prefetchedResources={this.state.prefetchedResources} launchUrl={this.state.launchUrl} responseExpirationDays={this.state.responseExpirationDays} pimsUrl={this.state.pimsUrl} @@ -233,12 +353,6 @@ export default class RequestBuilder extends Component { patientFhirQuery ={this.state.patientFhirQuery} />
-
- -
-
-
-
diff --git a/src/index.css b/src/index.css index 5ab4fed4..b720cfa8 100644 --- a/src/index.css +++ b/src/index.css @@ -15,8 +15,6 @@ body { box-shadow: none; } - - .floating-label { position: absolute; pointer-events: none; @@ -307,11 +305,12 @@ 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; + margin-bottom: 10px; + display: flow; + height: 55px; + padding:10px; + border-bottom: 1px solid black; + background-color: #005B94; } .loading{ From f5084681d0819f8a4e3bf267a93dd91a93918e0b Mon Sep 17 00:00:00 2001 From: Ariel Virgulto Date: Tue, 26 Dec 2023 20:52:59 -0600 Subject: [PATCH 4/5] Delete console box, update spacing of select btn --- src/components/ConsoleBox/ConsoleBox.js | 69 ---------------- src/components/ConsoleBox/consoleBox.css | 78 ------------------- .../InProgressFormBox/InProgressFormBox.js | 2 +- src/components/SMARTBox/smart.css | 1 + src/containers/RequestBuilder.js | 1 - 5 files changed, 2 insertions(+), 149 deletions(-) delete mode 100644 src/components/ConsoleBox/ConsoleBox.js delete mode 100644 src/components/ConsoleBox/consoleBox.css diff --git a/src/components/ConsoleBox/ConsoleBox.js b/src/components/ConsoleBox/ConsoleBox.js deleted file mode 100644 index 056f7226..00000000 --- a/src/components/ConsoleBox/ConsoleBox.js +++ /dev/null @@ -1,69 +0,0 @@ -import { Button } from '@mui/material'; -import React, { Component } from 'react'; - -export default class ConsoleBox extends Component { - constructor(props) { - super(props); - this.state = { - showStatus: 'hideConsole', - headerStatus: 'collapseHeader' - }; - - this.toggleConsole = this.toggleConsole.bind(this); - } - - handleAddition = (e, { value }) => { - this.setState({ - options: [{ text: value, value }, ...this.state.options] - }); - }; - - handleChange = (e, { value }) => { - this.props.updateCB(this.props.elementName, value); - this.setState({ currentValue: value }); - }; - - toggleConsole() { - if (this.state.showStatus === 'showConsole') { - this.setState({ showStatus: 'hideConsole' }); - this.setState({ headerStatus: 'collapseHeader' }); - } else { - this.setState({ showStatus: 'showConsole' }); - this.setState({ headerStatus: 'showHeader' }); - } - } - - render() { - try { - var objDiv = document.getElementById('your_div'); - if (objDiv) { - objDiv.scrollTop = objDiv.scrollHeight; - } - } catch (error) { - console.log('Encountered error', error); - } - let i = 0; - return ( -
- -
- {this.props.logs.map(element => { - i++; - return ( -
- {' '} - {element.content} -
- ); - })} -
-
- ); - } -} diff --git a/src/components/ConsoleBox/consoleBox.css b/src/components/ConsoleBox/consoleBox.css deleted file mode 100644 index 69359024..00000000 --- a/src/components/ConsoleBox/consoleBox.css +++ /dev/null @@ -1,78 +0,0 @@ -.consoleMain{ - border-width:1px 5px 3px 5px; - border-style: solid solid solid solid; - border-color: black; - background-color: #333333; - color:white; - overflow-y:scroll; - overflow-x: wrap; - word-break:break-all; - font-family: 'Courier New', Courier, monospace; - transition: all .2s ease; - /* transition-duration: .2s; */ - transition-delay: .25s; -} -.resize{ - resize: vertical; - transition-duration:0s; - transition-delay:0s; -} -.showConsole{ - height:200px; - - -} -.hideConsole{ - resize:none; - height:0px !important; - border-width: 0px; - transition-property: all; - transition-duration: .2s; - transition-delay: 0s; -} - -.consoleHeader{ - border: 3px solid black; - background-color: black; - color: white; - margin-top: 30px; - font-family: 'Courier New', Courier, monospace; - display:block; - font-size: 18px; - text-align: center; - transition-property: all; - transition-duration: .2s; - transition-delay: 0s; -} - -.showHeader{ - width:100%; -} - -.collapseHeader{ - width: 250px; - color: black; - text-align:center; - border-width: 1px 1px 1px 1px; - background-color: white; - transition-property: all; - transition-duration: .2s; - transition-delay: .25s; -} - -.showHeader:hover ~ .resize{ - transition-delay:.25s; - transition-duration:.4s; -} - -.errorClass{ - color:#dc3545; -} - -.warningClass{ - color: #ffc107; -} - -.infoClass{ - color: #17a2b8; -} \ No newline at end of file diff --git a/src/components/RequestBox/InProgressFormBox/InProgressFormBox.js b/src/components/RequestBox/InProgressFormBox/InProgressFormBox.js index 7cfe2573..293003e8 100644 --- a/src/components/RequestBox/InProgressFormBox/InProgressFormBox.js +++ b/src/components/RequestBox/InProgressFormBox/InProgressFormBox.js @@ -1,4 +1,4 @@ -import { Box, Button, Paper, Typography, ButtonGroup } from '@mui/material'; +import { Box, Button, Typography, ButtonGroup } from '@mui/material'; import React from 'react'; import './InProgressFormBoxStyle.css'; diff --git a/src/components/SMARTBox/smart.css b/src/components/SMARTBox/smart.css index 69043330..243de77e 100644 --- a/src/components/SMARTBox/smart.css +++ b/src/components/SMARTBox/smart.css @@ -86,6 +86,7 @@ html{ .select-btn { height: 40px; align-self: center; + margin-top: 25px !important; } .emptyForm { diff --git a/src/containers/RequestBuilder.js b/src/containers/RequestBuilder.js index 99fd6d66..f6bf000d 100644 --- a/src/containers/RequestBuilder.js +++ b/src/containers/RequestBuilder.js @@ -4,7 +4,6 @@ import PersonIcon from '@mui/icons-material/Person'; import RefreshIcon from '@mui/icons-material/Refresh'; import DisplayBox from '../components/DisplayBox/DisplayBox'; import '../index.css'; -import '../components/ConsoleBox/consoleBox.css'; import SettingsBox from '../components/SettingsBox/SettingsBox'; import RequestBox from '../components/RequestBox/RequestBox'; import buildRequest from '../util/buildRequest.js'; From e4e2235132b8afc66a539cfbe15e7335242864ab Mon Sep 17 00:00:00 2001 From: Ariel Virgulto Date: Thu, 4 Jan 2024 10:52:25 -0500 Subject: [PATCH 5/5] Move settings box above accordian --- src/containers/RequestBuilder.js | 20 ++++++++++++-------- src/index.css | 5 +++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/containers/RequestBuilder.js b/src/containers/RequestBuilder.js index f6bf000d..0cbaa73d 100644 --- a/src/containers/RequestBuilder.js +++ b/src/containers/RequestBuilder.js @@ -267,6 +267,18 @@ export default class RequestBuilder extends Component { > Reconnect EHR +
+
+ {/*
*/} + {this.state.showSettings && ( +
+ +
+ )}
@@ -316,14 +328,6 @@ export default class RequestBuilder extends Component {
-
- {this.state.showSettings && ( - - )}
{/*for the ehr launch */}