Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clinician portal for SPARC #1874

Draft
wants to merge 32 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
069c09f
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Apr 18, 2024
5ef84fb
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Apr 18, 2024
3aff319
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Apr 18, 2024
63de6c1
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Apr 18, 2024
6f7f312
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Apr 22, 2024
88dc1d8
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Apr 23, 2024
81dd381
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Apr 23, 2024
ba5e391
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Apr 24, 2024
3dfad20
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Apr 24, 2024
dd71754
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Apr 24, 2024
863ec69
CARDS-2514: New "locking" module, with basic locking feature
acrowthe May 30, 2024
5002ec0
CARDS-2514: New "locking" module, with basic locking feature
acrowthe May 30, 2024
544395d
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Jun 18, 2024
7514368
CARDS-2514: New "locking" module, with basic locking feature
acrowthe Jan 16, 2025
40e9f24
CARDS-2558: New "clinician-portal" module
sdumitriu Jul 19, 2024
e10494a
CARDS-2558: New "clinician-portal" module
marta- Jul 20, 2024
49b3cf1
CARDS-2569: Allow configuring the menu items to be displayed for a Form
marta- Jul 22, 2024
2a1ad37
CARDS-2558 / CARDS-2559: Visit page view for clinicians
marta- Jul 22, 2024
367d5cf
CARDS-2558 / CARDS-2570: Custom form view for clinicians
sdumitriu Jul 22, 2024
1f74d4b
CARDS-2558 / CARDS-2570: Custom form view for clinicians
sdumitriu Jul 22, 2024
f47a115
CARDS-2558 / CARDS-2560: Patient page view for clinicians
sdumitriu Jul 22, 2024
1b02191
CARDS-2558: New "clinician-portal" module
sdumitriu Jul 22, 2024
2db53a6
CARDS-2558 / CARDS-2559: Visit page view for clinicians
marta- Jul 23, 2024
bd46047
CARDS-2558 / CARDS-2570: Custom form view for clinicians
marta- Jul 23, 2024
04972ff
CARDS-2558 / CARDS-2560: Patient page view for clinicians
marta- Jul 23, 2024
923099f
CARDS-2558 / CARDS-2560: Patient page view for clinicians
marta- Jul 23, 2024
b5d17b1
CARDS-2558 / CARDS-2559: Visit page view for clinicians
marta- Jul 23, 2024
2f0c1bf
CARDS-2558 / CARDS-2559: Visit page view for clinicians
marta- Jul 23, 2024
8af2406
CARDS-2558 / CARDS-2559: Visit page view for clinicians
marta- Jul 23, 2024
03e105d
CARDS-2558 / CARDS-2559: Visit page view for clinicians
marta- Jul 24, 2024
75230bb
CARDS-2558 / CARDS-2559: Visit page view for clinicians
marta- Jan 7, 2025
9e09bcf
[misc] Updateyarn.lock
marta- Jan 17, 2025
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
344 changes: 339 additions & 5 deletions aggregated-frontend/src/main/frontend/yarn.lock

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions compose-cluster/generate_compose_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
argparser.add_argument('--saml_cloud_iam_demo', help='Enable SAML authentication with CARDS via the Cloud-IAM.com demo', action='store_true')
argparser.add_argument('--server_address', help='Domain name (or Domain name:port) that the public will use for accessing this CARDS deployment')
argparser.add_argument('--slack_notifications', help='Enable the periodic sending of performance metrics to a Slack channel', action='store_true')
argparser.add_argument('--locking', help='Enable the ability to lock and unlock resources', action='store_true')
argparser.add_argument('--smtps', help='Enable SMTPS emailing functionality', action='store_true')
argparser.add_argument('--smtps_localhost_proxy', help='Run an SSL termination proxy so that the CARDS container may connect to the host\'s SMTP server at localhost:25', action='store_true')
argparser.add_argument('--smtps_test_container', help='Enable the mock SMTPS (cards/postfix-docker) container for viewing CARDS-sent emails.', action='store_true')
Expand Down Expand Up @@ -778,6 +779,9 @@ def newListIfEmpty(yaml_object, *keys):
if 'NIGHTLY_SLACK_NOTIFICATIONS_SCHEDULE' in os.environ:
yaml_obj['services']['cardsinitial']['environment'].append("NIGHTLY_SLACK_NOTIFICATIONS_SCHEDULE={}".format(os.environ['NIGHTLY_SLACK_NOTIFICATIONS_SCHEDULE']))

if args.locking:
yaml_obj['services']['cardsinitial']['environment'].append("LOCKING_ENABLED=true")

if ENABLE_BACKUP_SERVER:
print("Configuring service: backup_recorder")

Expand Down
6 changes: 6 additions & 0 deletions distribution/docker_entry.sh
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ then
featureFlagString="$featureFlagString -f mvn:io.uhndata.cards/cards-slack-notifications/${CARDS_VERSION}/slingosgifeature"
fi

#Should the cards-locking module be loaded?
if [[ "$LOCKING_ENABLED" == "true" ]]
then
featureFlagString="$featureFlagString -f mvn:io.uhndata.cards/cards-locking/${CARDS_VERSION}/slingosgifeature"
fi

if [[ "$SMTPS_LOCALHOST_PROXY" == "true" ]]
then
keytool -import -trustcacerts -file /etc/cert/smtps_certificate.crt -keystore /etc/ssl/certs/java/cacerts -keypass changeit -storepass changeit -noprompt
Expand Down
177 changes: 99 additions & 78 deletions modules/data-entry/src/main/frontend/src/questionnaire/Form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import SessionExpiryWarningModal from "./SessionExpiryWarningModal.jsx";
*/
function Form (props) {
let { classes, id, contentOffset } = props;
let { mode, className, disableHeader, disableButton, doneButtonStyle, doneIcon, doneLabel, onDone, questionnaireAddons, paginationProps } = props;
let { mode, className, actionSwitches, disableHeader, disableButton, doneButtonStyle, doneIcon, doneLabel, onDone, questionnaireAddons, paginationProps } = props;
// Record if the form was already checked out before opening it, which may indicate that another user is editing, or it is being edited in a different tab
let [ wasCheckedOut, setWasCheckedOut ] = useState(false);
// This holds the full form JSON, once it is received from the server
Expand Down Expand Up @@ -443,87 +443,108 @@ function Form (props) {
);
}

let isActionEnabled = (action) => (!!!actionSwitches || !!(actionSwitches[action]?.(data)));

let isDropdnEnabled = () => (
(isEdit && isActionEnabled("subject"))
|| (!isEdit && isActionEnabled("text"))
|| isActionEnabled("delete")
);

let dropdownList = (
<List>
{ isEdit ?
<ListItem className={classes.actionsMenuItem}>
<Button onClick={() => {setSelectorDialogOpen(true); setActionsMenu(null)}}>
Change subject
</Button>
</ListItem>
: <>
<ListItem className={classes.actionsMenuItem}>
<PrintButton
variant="text"
size="medium"
resourcePath={formURL}
resourceData={data}
breadcrumb={getTextHierarchy(data?.subject, true)}
date={DateTime.fromISO(data['jcr:created']).toLocaleString(DateTime.DATE_MED)}
onClose={() => { setActionsMenu(null); }}
/>
</ListItem>
<ListItem className={classes.actionsMenuItem}>
<Button
size="medium"
onClick={() => {
window.open(formURL + ".txt");
setActionsMenu(null);
}}>
Export as text
</Button>
</ListItem>
</> }
<ListItem className={classes.actionsMenuItem}>
<DeleteButton
entryPath={data ? data["@path"] : formURL}
entryName={getEntityIdentifier(data)}
entryType="Form"
onComplete={onDelete}
variant="text"
size="medium"
/>
</ListItem>
</List>
<List>
{ isEdit ?
( isActionEnabled("subject") &&
<ListItem className={classes.actionsMenuItem}>
<Button onClick={() => {setSelectorDialogOpen(true); setActionsMenu(null)}}>
Change subject
</Button>
</ListItem>
)
:
( isActionEnabled("text") &&
<ListItem className={classes.actionsMenuItem}>
<Button
size="medium"
onClick={() => {
window.open(formURL + ".txt");
setActionsMenu(null);
}}>
Export as text
</Button>
</ListItem>
)
}
{ isActionEnabled("delete") &&
<ListItem className={classes.actionsMenuItem}>
<DeleteButton
entryPath={data ? data["@path"] : formURL}
entryName={getEntityIdentifier(data)}
entryType="Form"
onComplete={onDelete}
variant="text"
size="medium"
/>
</ListItem>
}
</List>
)

let formMenu = (
<div className={classes.actionsMenu}>
{isEdit ?
<Tooltip title="Save and view" onClick={onClose}>
<IconButton color="primary" size="large">
<DoneIcon />
</IconButton>
</Tooltip>
:
<Tooltip title="Edit">
<IconButton color="primary" onClick={onEdit} size="large">
<EditIcon />
</IconButton>
</Tooltip>
}
<Tooltip title="More actions" onClick={(event) => {setActionsMenu(event.currentTarget)}}>
<IconButton size="large">
<MoreIcon fontSize="small" />
</IconButton>
</Tooltip>
{ !actionsMenu && <div style={{display: "none"}}>{ dropdownList }</div> }
<Popover
open={Boolean(actionsMenu)}
anchorEl={actionsMenu}
onClose={() => {setActionsMenu(null)}}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
>
{ dropdownList }
</Popover>
</div>
<div className={classes.actionsMenu}>
{ isEdit ?
( isActionEnabled("save") &&
<Tooltip title="Save and view" onClick={onClose}>
<IconButton color="primary" size="large">
<DoneIcon />
</IconButton>
</Tooltip>
)
:
( isActionEnabled("edit") &&
<Tooltip title="Edit">
<IconButton color="primary" onClick={onEdit} size="large">
<EditIcon />
</IconButton>
</Tooltip>
)
}
{ !isEdit && isActionEnabled("print") &&
<PrintButton
variant="icon"
size="large"
resourcePath={formURL}
resourceData={data}
breadcrumb={getTextHierarchy(data?.subject, true)}
date={DateTime.fromISO(data['jcr:created']).toLocaleString(DateTime.DATE_MED)}
/>
}
{ isDropdnEnabled() &&
<>
<Tooltip title="More actions" onClick={(event) => {setActionsMenu(event.currentTarget)}}>
<IconButton size="large">
<MoreIcon fontSize="small" />
</IconButton>
</Tooltip>
{ !actionsMenu && <div style={{display: "none"}}>{ dropdownList }</div> }
<Popover
open={Boolean(actionsMenu)}
anchorEl={actionsMenu}
onClose={() => {setActionsMenu(null)}}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
>
{ dropdownList }
</Popover>
</>
}
</div>
)

let getTimestampString = (timestamp) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,10 @@ const questionnaireStyle = theme => ({
borderColor: theme.palette.error.main,
color: theme.palette.error.main,
},
LOCKEDFlag:{
backgroundColor: theme.palette.primary.main,
color: theme.palette.background.paper
},
DefaultFlag: {
},
formPreview: {
Expand Down Expand Up @@ -733,6 +737,11 @@ const questionnaireStyle = theme => ({
paddingTop: theme.spacing(4),
},
},
lockDialogInput: {
marginTop: theme.spacing(3),
marginRight: theme.spacing(3),
marginBottom: theme.spacing(3),
}
});

export default questionnaireStyle;
Loading