Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into liquid-layout
Browse files Browse the repository at this point in the history
  • Loading branch information
jtquach1 committed May 20, 2024
2 parents 44db8e3 + 4f5e358 commit 0b1b6f1
Show file tree
Hide file tree
Showing 14 changed files with 228 additions and 91 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/views/Patient/MedReqDropDown/MedReqDropDown.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.etasuButtonText {
margin-bottom: 0px;
font-weight: bold;
font-size: 14px;
font-size: 1.2em;
}

.etasuButtonTimestamp {
Expand Down
2 changes: 1 addition & 1 deletion src/views/Patient/MedReqDropDown/MedReqDropDown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ function MedReqDropDown({
};
return (
<>
<Card sx={{ bgcolor: 'white' }}>
<Card sx={{ bgcolor: 'white', width: '100%', margin: '0 auto 0' }}>
<CardContent>
<Grid item container spacing={2}>
<Grid item container alignItems="left" direction="column" spacing={2}>
Expand Down
190 changes: 130 additions & 60 deletions src/views/Patient/MedReqDropDown/cdsHooksCards/cdsHooksCard.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import { useState, useEffect, ReactElement } from 'react';
import { Button, Card, CardActions, CardContent, Grid, Typography } from '@mui/material';
import { Box, Button, Card, CardContent, Grid, Typography } from '@mui/material';
import { ReactElement, useEffect, useState } from 'react';

import axios from 'axios';
import Client from 'fhirclient/lib/Client';

import AddCircleOutlineRoundedIcon from '@mui/icons-material/AddCircleOutlineRounded';
import ArrowForwardIosRoundedIcon from '@mui/icons-material/ArrowForwardIosRounded';
import KeyboardArrowDownRoundedIcon from '@mui/icons-material/KeyboardArrowDownRounded';
import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf';
import Accordion from '@mui/material/Accordion';
import AccordionDetails from '@mui/material/AccordionDetails';
import AccordionSummary from '@mui/material/AccordionSummary';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import {
Action,
Card as HooksCard,
Link,
Suggestion,
Action
Suggestion
} from '../../../../cds-hooks/resources/HookTypes';
import { SmartApp } from '../../../Questionnaire/SmartApp';
import { AppContext, getAppContext } from '../../../Questionnaire/questionnaireUtil';
import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf';

// TODO:
// - create a css file for better style
Expand Down Expand Up @@ -234,78 +242,140 @@ const CdsHooksCard = (props: CdsHooksCardProps) => {
});
});
}

const decisionCard = {
backgroundColor: '#fff',
border: '1px solid rgba(0, 0, 0, 0.12)',
borderRadius: '4px'
};

const cardSource = { fontSize: '.85rem', fontStyle: 'italic', margin: '0 0 5px' };
const sourceLink = { marginRight: '8px', color: '#4183c4', textDecoration: 'none' };

return (
<Grid item xs={12}>
<Card variant="outlined" style={decisionCard}>
<Card
variant="outlined"
style={decisionCard}
sx={{ margin: '0 auto 0', marginTop: '20px', maxWidth: '560px' }}
>
<Box sx={{ margin: '0 auto 0', width: '90%' }}>
<CardContent>
<Typography variant="h5" component="div">
{props.card?.summary}
</Typography>
<Typography>{props.card?.detail}</Typography>
<Typography style={cardSource} gutterBottom>
</CardContent>

{/* Forms */}
{links.filter(link => link.type === 'smart').length > 0 ? (
<div>
<Typography color="text.secondary">Required Forms</Typography>
<List>
{links.map((link: Link) => {
if (link.type === 'smart') {
return (
<ListItem key={link?.label}>
<Button
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
textAlign: 'left',
width: '100%',
marginBottom: '5px'
}}
variant="outlined"
onClick={() => buttonClickAction(link)}
endIcon={<ArrowForwardIosRoundedIcon />}
>
{link?.label}
</Button>
</ListItem>
);
}
})}
</List>
</div>
) : (
<></>
)}

{/* Suggestions */}
{suggestions.length > 0 ? (
<div>
<Typography sx={{ marginTop: '10px' }} color="text.secondary">
Suggestions
</Typography>
<List>
{suggestions.map((suggestion: Suggestion, ind) => {
const buttonId = 'suggestion_button-' + props.cardInd + '-' + ind;
return (
<ListItem key={suggestion?.label}>
<Button
variant="contained"
endIcon={<AddCircleOutlineRoundedIcon />}
onClick={() =>
buttonClickSuggestion(
suggestion,
buttonId,
suggestions.length,
props.cardInd,
props.selectionBehavior
)
}
id={buttonId}
>
{suggestion?.label}
</Button>
</ListItem>
);
})}
</List>
</div>
) : (
<></>
)}

{/* Documentation and Guides */}
{links.filter(link => link.type === 'absolute').length > 0 ? (
<Accordion
sx={{ display: 'block', marginTop: '10px', width: '100%', backgroundColor: '#F3F6F9' }}
>
<AccordionSummary expandIcon={<KeyboardArrowDownRoundedIcon />}>
<Typography sx={{ fontSize: 14 }} color="text.secondary">
View documentation and guides
</Typography>
</AccordionSummary>
<AccordionDetails>
{links.map((link: Link) => {
if (link.type === 'absolute') {
return (
<Grid item key={link?.label}>
<Button
endIcon={<PictureAsPdfIcon />}
onClick={() => buttonClickAction(link)}
>
{link?.label}
</Button>
</Grid>
);
}
})}
</AccordionDetails>
</Accordion>
) : (
<></>
)}

<Box sx={{ textAlign: 'right', paddingTop: '10px' }}>
<Typography style={cardSource}>
{'Source '}
<a href={props.card?.source?.url} style={sourceLink}>
{props.card?.source?.label}
</a>
</Typography>
</CardContent>
<CardActions>
<Grid container spacing={1}>
{links.map((link: Link) => {
if (link.type === 'smart') {
return (
<Grid item key={link?.label}>
<Button variant="outlined" onClick={() => buttonClickAction(link)}>
{link?.label}
</Button>
</Grid>
);
}
return (
<Grid item key={link?.label}>
<Button endIcon={<PictureAsPdfIcon />} onClick={() => buttonClickAction(link)}>
{link?.label}
</Button>
</Grid>
);
})}
</Grid>
</CardActions>
<CardActions>
<Grid container spacing={1}>
{suggestions.map((suggestion: Suggestion, ind) => {
const buttonId = 'suggestion_button-' + props.cardInd + '-' + ind;
return (
<Grid item key={suggestion?.label}>
<Button
variant="contained"
onClick={() =>
buttonClickSuggestion(
suggestion,
buttonId,
suggestions.length,
props.cardInd,
props.selectionBehavior
)
}
id={buttonId}
>
{suggestion?.label}
</Button>
</Grid>
);
})}
</Grid>
</CardActions>
</Card>
</Grid>
</Box>
</Box>
</Card>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface CdsHooksCardsProps {

const CdsHooksCards = (props: CdsHooksCardsProps) => {
return (
<Grid item container spacing={2}>
<Grid item container spacing={2} maxWidth={'600px'} margin={'0 auto 0'}>
{props.cards.map((card: HooksCard, cardInd) => (
<CdsHooksCard
key={card?.summary}
Expand Down
39 changes: 23 additions & 16 deletions src/views/Patient/MedReqDropDown/etasuStatus/EtasuStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,22 +98,29 @@ const EtasuStatus = (props: EtasuStatusProps) => {
<Box sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}>
{props.remsAdminResponse ? (
<List>
{getRequirements().map((param: EtasuParamParam) => (
<ListItem disablePadding key={param.name} data-testid="etasu-item">
<ListItemIcon>
{param.resource.status === 'success' ? (
<CheckCircle color="success" />
) : (
<Close color="warning" />
)}
</ListItemIcon>
{param.resource.status === 'success' ? (
<ListItemText primary={param.name} />
) : (
<ListItemText primary={param.name} secondary={param.resource.note?.[0]?.text} />
)}
</ListItem>
))}
{getRequirements().map((param: EtasuParamParam) => {
if (param.resource) {
return (
<ListItem disablePadding key={param.name} data-testid="etasu-item">
<ListItemIcon>
{param.resource?.status === 'success' ? (
<CheckCircle color="success" />
) : (
<Close color="warning" />
)}
</ListItemIcon>
{param.resource?.status === 'success' ? (
<ListItemText primary={param.name} />
) : (
<ListItemText
primary={param.name}
secondary={param.resource?.note?.[0]?.text}
/>
)}
</ListItem>
);
}
})}
</List>
) : (
'Not Available'
Expand Down
46 changes: 43 additions & 3 deletions src/views/Questionnaire/QuestionnaireForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Meta,
Organization,
Parameters,
Patient,
Questionnaire,
QuestionnaireItem,
QuestionnaireResponse,
Expand Down Expand Up @@ -44,7 +45,7 @@ import Client from 'fhirclient/lib/Client';
import ConfigData from '../../config.json';
import { SelectPopup } from './components/SelectPopup';
import AlertDialog from './components/AlertDialog';

import { RemsAdminResponse } from './components/RemsInterface/RemsInterface';
import { PrepopulationResults } from './SmartApp';
import { v4 as uuid } from 'uuid';
import axios, { AxiosResponse } from 'axios';
Expand Down Expand Up @@ -223,10 +224,15 @@ export function QuestionnaireForm(props: QuestionnaireProps) {
const [popupState, popupDispatch] = useReducer(reducer, initialPopupState);
const [showRxAlert, setShowRxAlert] = useState<RxAlert>({ open: false });
const [formValidationErrors, setFormValidationErrors] = useState<any[]>([]);
const [patient, setPatient] = useState<Patient | undefined>(undefined);
const LForms = window.LForms;
const questionnaireFormId = `formContainer-${props.questionnaireForm.id}-${props.tabIndex}`;

useEffect(() => {
const patientId = getPatient();
props.smartClient.request(patientId).then(res => {
setPatient(res);
});
// search for any partially completed QuestionnaireResponses
if (props.response) {
const response = props.response;
Expand Down Expand Up @@ -1139,7 +1145,7 @@ export function QuestionnaireForm(props: QuestionnaireProps) {
// Get tooltip for Submit button
const getMissingFieldsTooltip = () => {
const tooltip = isFilledOut() ? 'Submit to REMS admin' : 'Fill out missing fields';
return <Typography fontSize={16}>{tooltip}</Typography>;
return <Typography fontSize={'small'}>{tooltip}</Typography>;
};

// Get missing fields to display
Expand Down Expand Up @@ -1734,8 +1740,42 @@ export function QuestionnaireForm(props: QuestionnaireProps) {
specialtyRxBundle,
options
)
.then(response => {
.then((response: RemsAdminResponse) => {
const remsCaseUrl = 'http://hl7.org/fhir/sid/rems-case'; // placeholder
const proceedToRems = () => {
const caseNumber = response.data?.case_number;
if (caseNumber && patient) {
patient.identifier = patient.identifier?.filter(iden => {
if (iden.system === remsCaseUrl && iden.period) {
if (iden.period?.end) {
const endDate = new Date(iden.period.end);
if (endDate.getMilliseconds() < Date.now()) {
return false; // filter out old identifiers
}
}
}
return true;
});
const endDate = new Date(Date.now() + 86400000); // 86400000 is 1 day in milliseconds
patient.identifier?.push({
value: caseNumber,
system: remsCaseUrl,
period: {
start: new Date(Date.now()).toISOString(),
end: endDate.toISOString()
}
});
// update patient
props.smartClient.request({
url: patient.resourceType + '/' + patient.id,
method: 'PUT',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(patient)
});
}

props.setSpecialtyRxBundle(specialtyRxBundle);
};
if (response.status == 201) {
Expand Down
Loading

0 comments on commit 0b1b6f1

Please sign in to comment.