Skip to content

Commit

Permalink
[DUOS-2608][DUOS-2676] Read Only View Of DAR Form (#2335)
Browse files Browse the repository at this point in the history
* implemented read only view of dar form

* exclude instructions + format component

* fixed failing tests

* fixed typo

* show researcher details instead of current user

* cypress testing error fix

* removed signing official field

* revert changes to ajax.js

* Revert "fixed typo"

This reverts commit 8ec2637.

* fixed code

* fixed typo

* added collaborator list changes

* fix application tabs

* fixed instructions

* fix eraCommons

* Rename eRACommons.js to ERACommons.js

* WIP

* fixed

* Rename ERACommons.js to eRACommons.js

* fixed

* remove comments

* addressed comments

* fix

* remove alerts
  • Loading branch information
hams7504 authored Oct 19, 2023
1 parent bc70648 commit 481a9fc
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 52 deletions.
2 changes: 1 addition & 1 deletion src/Routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const Routes = (props) => (
<AuthenticatedRoute path="/member_console" component={MemberConsole} props={props} rolesAllowed={[USER_ROLES.member]}/>
<AuthenticatedRoute path="/dar_vote_review/:collectionId" component={DarCollectionReview} props={Object.assign({readOnly: true}, props)}
rolesAllowed={[USER_ROLES.chairperson, USER_ROLES.member]}/>
<AuthenticatedRoute path="/dar_application_review/:collectionId" component={DataAccessRequestApplication} props={props}
<AuthenticatedRoute path="/dar_application_review/:collectionId" component={DataAccessRequestApplication} props={Object.assign({}, props, {readOnlyMode: true})}
rolesAllowed={[USER_ROLES.researcher]} />
{/* Order is important for processing links with embedded dataRequestIds */}
<AuthenticatedRoute path="/dar_application/:dataRequestId" component={DataAccessRequestApplication} props={props} rolesAllowed={[USER_ROLES.researcher]} />
Expand Down
23 changes: 15 additions & 8 deletions src/components/eRACommons.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export const eRACommons = hh(class eRACommons extends React.Component {
expirationCount: 0,
eraCommonsId: '',
nihError: false,
isHovered: false
isHovered: false,
researcherProfile: {}
};

componentDidMount = async () => {
Expand All @@ -26,6 +27,14 @@ export const eRACommons = hh(class eRACommons extends React.Component {
}
};

componentDidUpdate(prevProps) {
if (this.props.researcherProfile !== prevProps.researcherProfile) {
this.setState({ researcherProfile: this.props.researcherProfile }, () => {
this.getUserInfo();
});
}
}

onMouseEnter = () => {
this.setState({ isHovered: true });
};
Expand All @@ -48,7 +57,7 @@ export const eRACommons = hh(class eRACommons extends React.Component {
};

getUserInfo = async () => {
const response = await User.getMe();
const response = this.props.readOnly ? this.state.researcherProfile : await User.getMe();
const props = response.researcherProperties;
const authProp = find({'propertyKey':'eraAuthorized'})(props);
const expProp = find({'propertyKey':'eraExpiration'})(props);
Expand Down Expand Up @@ -140,12 +149,11 @@ export const eRACommons = hh(class eRACommons extends React.Component {
div({
isRendered: (!this.state.isAuthorized || this.state.expirationCount < 0)
}, [
a({
!this.props.readOnly && a({
style: buttonStyle,
onMouseEnter: this.onMouseEnter,
onMouseLeave: this.onMouseLeave,
onClick: this.redirectToNihLogin,
disabled: this.props.readOnly,
target: '_blank'
}, [
div({ style: logoStyle }),
Expand All @@ -169,13 +177,12 @@ export const eRACommons = hh(class eRACommons extends React.Component {
paddingTop: 5
}
}, [this.state.eraCommonsId]),
button({
!this.props.readOnly && button({
style: {
float: 'left',
margin: '2px 0 0 10px'
},
type: 'button',
disabled: this.props.readOnly,
onClick: this.deleteNihAccount,
className: 'close'
}, [
Expand All @@ -190,8 +197,8 @@ export const eRACommons = hh(class eRACommons extends React.Component {
},
className: 'col-lg-12 col-md-12 col-sm-6 col-xs-12 no-padding'
}, [
div({ isRendered: this.state.expirationCount >= 0, className: 'fadein' }, ['Your NIH authentication will expire in ' + this.state.expirationCount + ' days']),
div({ isRendered: this.state.expirationCount < 0, className: 'fadein' }, ['Your NIH authentication has expired'])
div({ isRendered: this.state.expirationCount >= 0, className: 'fadein' }, [`${this.props.readOnly ? 'This user\'s' : 'Your'} NIH authentication will expire in ${this.state.expirationCount} days`]),
div({ isRendered: this.state.expirationCount < 0, className: 'fadein' }, [`${this.props.readOnly ? 'This user\'s' : 'Your'} NIH authentication has expired`])
])
])
])
Expand Down
9 changes: 5 additions & 4 deletions src/pages/dar_application/DataAccessRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export default function DataAccessRequest(props) {
setDatasets,
validation,
readOnlyMode,
includeInstructions,
formValidationChange,
ariaLevel = 2
} = props;
Expand Down Expand Up @@ -132,7 +133,7 @@ export default function DataAccessRequest(props) {
validators: [FormValidators.REQUIRED],
validation: validation.datasetIds,
onValidationChange,
description: 'Please start typing the Dataset Name, Sample Collection ID, or PI of the dataset(s) for which you would like to request access:',
description: includeInstructions ? 'Please start typing the Dataset Name, Sample Collection ID, or PI of the dataset(s) for which you would like to request access:' : '',
defaultValue: datasets?.map((ds) => formatSearchDataset(ds)),
selectConfig: {
// return custom html for displaying
Expand All @@ -156,7 +157,7 @@ export default function DataAccessRequest(props) {
disabled: readOnlyMode,
validators: [FormValidators.REQUIRED],
validation: validation.projectTitle,
description: 'Please note that coordinated requests by External Collaborators should each use the same title.',
description: includeInstructions ? 'Please note that coordinated requests by External Collaborators should each use the same title.' : '',
id: 'projectTitle',
placeholder: 'Project Title',
defaultValue: formData.projectTitle,
Expand Down Expand Up @@ -304,7 +305,7 @@ export default function DataAccessRequest(props) {
type: FormFieldTypes.TEXTAREA,
title: '2.4 Non-Technical Summary',
validators: [FormValidators.REQUIRED],
description: 'Please enter below a non-technical summary of your RUS suitable for understanding by the general public (written at a high school reading level or below).',
description: includeInstructions ? 'Please enter below a non-technical summary of your RUS suitable for understanding by the general public (written at a high school reading level or below).' : '',
placeholder: 'Please limit your your non-technical summary to 1100 characters',
rows: 6,
maxLength: 1100,
Expand All @@ -317,7 +318,7 @@ export default function DataAccessRequest(props) {

h(FormFieldTitle, {
title: '2.5 Data Use Acknowledgements',
description: 'Please confirm listed acknowledgements and/or document requirements below:',
description: includeInstructions ? 'Please confirm listed acknowledgements and/or document requirements below:' : '',
isRendered: needsGsoAcknowledgement(datasets) || needsDsAcknowledgement(dataUseTranslations) || needsPubAcknowledgement(datasets),
}),

Expand Down
75 changes: 49 additions & 26 deletions src/pages/dar_application/DataAccessRequestApplication.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@ import {
import { isArray, set } from 'lodash';
import DucAddendum from './DucAddendum';
import UsgOmbText from '../../components/UsgOmbText';

const ApplicationTabs = [
{ name: 'Researcher Information' },
{ name: 'Data Access Request' },
{ name: 'Research Purpose Statement' },
{ name: 'Data Use Agreement' }
{ name: 'Research Purpose Statement' }
];

const fetchAllDatasets = async (dsIds) => {
Expand Down Expand Up @@ -189,7 +187,11 @@ const DataAccessRequestApplication = (props) => {
fetchAllDatasets(formData.datasetIds).then((datasets) => {
setDatasets(datasets);
});
}, [formData.datasetIds]);
if (!props.readOnlyMode) {
ApplicationTabs.push({ name: 'Data Use Agreement' });
setApplicationTabs(ApplicationTabs);
}
}, [formData.datasetIds, props.readOnlyMode]);

useEffect(() => {
translateDataUseRestrictionsFromDataUseArray(datasets.map((ds) => ds.dataUse)).then((translations) => {
Expand Down Expand Up @@ -225,14 +227,31 @@ const DataAccessRequestApplication = (props) => {
setStep(newStep);
}, []);

useEffect(() => {
const fetchData = async () => {
try {
const { collectionId } = props.match.params;
if (props.readOnlyMode) {
const collection = await Collections.getCollectionById(collectionId);
const response = await User.getById(collection.createUserId);
setResearcher(response);
} else {
const response = await User.getMe();
const signingOfficials = await User.getSOsForCurrentUser();
setResearcher(response);
setAllSigningOfficials(signingOfficials);
}
} catch (error) {
setShowDialogSave(false);
NotyUtil.showError('Error displaying user information. Please try again in a few moments.');
}
};
fetchData();
}, [props.match.params, props.readOnlyMode]);

const init = useCallback(async () => {
const { dataRequestId, collectionId } = props.match.params;
let formData = {};
const researcher = await User.getMe();
const signingOfficials = await User.getSOsForCurrentUser();

setResearcher(researcher);
setAllSigningOfficials(signingOfficials);
setIsLoading(false);

if (!isNil(collectionId)) {
Expand Down Expand Up @@ -260,7 +279,7 @@ const DataAccessRequestApplication = (props) => {

batchFormFieldChange(formData);
window.addEventListener('scroll', onScroll); // eslint-disable-line -- codacy says event listeners are dangerous
}, [onScroll, props.match.params]);
}, [onScroll, props.match.params, researcher]);

useEffect(() => {
init();
Expand All @@ -286,7 +305,7 @@ const DataAccessRequestApplication = (props) => {

const updateDraftResponse = async (formattedFormData, referenceId) => {
let darPartialResponse;
if(!isNil(referenceId) && !isEmpty(referenceId)) {
if (!isNil(referenceId) && !isEmpty(referenceId)) {
darPartialResponse = await DAR.updateDarDraft(formattedFormData, referenceId);
} else {
darPartialResponse = await DAR.postDarDraft(formattedFormData);
Expand Down Expand Up @@ -453,7 +472,7 @@ const DataAccessRequestApplication = (props) => {

return (
<div>
<div className='container' style={{ paddingBottom: '2%' }}>
<div className={props.readOnlyMode ? 'application-information-page' : 'container'} style={{ padding: props.readOnlyMode ? '2% 3%' : '0 0 2%', backgroundColor: props.readOnlyMode ? 'white' : '' }}>
<div className='col-lg-12 col-md-12 col-sm-12 col-xs-12'>
<div className='row no-margin'>
<Notification notificationData={notificationData} />
Expand All @@ -462,10 +481,11 @@ const DataAccessRequestApplication = (props) => {
'col-lg-12 col-md-12 col-sm-9 ' : 'col-lg-12 col-md-12 col-sm-12 ')}>
<PageHeading
title='Data Access Request Application'
description='Please complete the fields below to request access to data.'
description={props.readOnlyMode ? '' : 'Please complete the fields below to request access to data.'}
/>
</div>
{formData.darCode !== null &&
!props.readOnlyMode &&
<div className='col-lg-2 col-md-3 col-sm-3 col-xs-12 no-padding'>
<a id='btn_back' onClick={back} className='btn-primary btn-back'>
<i className='glyphicon glyphicon-chevron-left' />
Expand Down Expand Up @@ -529,7 +549,8 @@ const DataAccessRequestApplication = (props) => {
<div className='step-container'>
<ResearcherInfo
completed={!isNil(get('institutionId', researcher))}
readOnlyMode={isAttested}
readOnlyMode={props.readOnlyMode || isAttested}
includeInstructions={!props.readOnlyMode}
darCode={formData.darCode}
formData={formData}
validation={formValidation.researcherInfoErrors}
Expand All @@ -551,7 +572,8 @@ const DataAccessRequestApplication = (props) => {
<div className='step-container'>
<DataAccessRequest
formData={formData}
readOnlyMode={isAttested}
readOnlyMode={props.readOnlyMode || isAttested}
includeInstructions={!props.readOnlyMode}
datasets={datasets}
validation={formValidation.darErrors}
formValidationChange={(val) => formValidationChange('darErrors', val)}
Expand All @@ -569,23 +591,24 @@ const DataAccessRequestApplication = (props) => {
<div className='step-container'>
<ResearchPurposeStatement
darCode={formData.darCode}
readOnlyMode={isAttested}
readOnlyMode={props.readOnlyMode || isAttested}
validation={formValidation.rusErrors}
formValidationChange={(val) => formValidationChange('rusErrors', val)}
formFieldChange={formFieldChange}
formData={formData}
/>
</div>

<div className='step-container'>
<DataUseAgreements
darCode={formData.darCode}
cancelAttest={() => setIsAttested(false)}
isAttested={isAttested}
attest={attemptSubmit}
save={() => setShowDialogSave(true)}
/>
</div>
{!props.readOnlyMode ?
<div className='step-container'>
<DataUseAgreements
darCode={formData.darCode}
cancelAttest={() => setIsAttested(false)}
isAttested={isAttested}
attest={attemptSubmit}
save={() => setShowDialogSave(true)}
/>
</div> : <div />}

{isAttested &&
<div className='step-container'>
Expand All @@ -596,7 +619,7 @@ const DataAccessRequestApplication = (props) => {
</div>
</form>
</div>
<UsgOmbText />
{!props.readOnlyMode ? <UsgOmbText /> : null}
</div>
);
};
Expand Down
18 changes: 10 additions & 8 deletions src/pages/dar_application/ResearcherInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default function ResearcherInfo(props) {
const {
allSigningOfficials,
readOnlyMode,
includeInstructions,
completed,
darCode,
eRACommonsDestination,
Expand Down Expand Up @@ -58,7 +59,7 @@ export default function ResearcherInfo(props) {
div({
datacy: 'researcher-info-profile-submitted',
isRendered: (completed === false && libraryCardReqSatisfied === false), className: 'rp-alert' }, [
Alert({
!readOnlyMode && Alert({
id: 'profileSubmitted',
type: 'important',
title: span([
Expand All @@ -84,14 +85,15 @@ export default function ResearcherInfo(props) {

div({className: 'dar-application-row'}, [
h3('1.2 Researcher Identification' + (formData.checkCollaborator ? ' (optional)' : '')),
span({ className: `${showNihValidationError ? 'errored' : 'default-color'}`, isRendered: formData.checkCollaborator !== true }, [
!readOnlyMode && span({ className: `${showNihValidationError ? 'errored' : 'default-color'}`, isRendered: formData.checkCollaborator !== true }, [
'Please authenticate with ',
a({ target: '_blank', href: 'https://era.nih.gov/reg-accounts/register-commons.htm' }, ['eRA Commons']), ' in order to proceed.'
]),
div({ className: 'flex-row', style: { justifyContent: 'flex-start', alignItems: 'flex-start' } }, [
h4({ style: { marginRight: 30, marginTop: 30 } }, '1.2.1'),
eRACommons({
destination: eRACommonsDestination,
researcherProfile: researcher,
onNihStatusUpdate: onNihStatusUpdate,
location: location,
validationError: showNihValidationError,
Expand All @@ -104,17 +106,17 @@ export default function ResearcherInfo(props) {
div({
datacy: 'researcher-info-missing-library-cards',
isRendered: libraryCardReqSatisfied === false, className: 'rp-alert' }, [
Alert({ id: 'missingLibraryCard', type: 'danger', title: missingLibraryCard })
!readOnlyMode && Alert({ id: 'missingLibraryCard', type: 'danger', title: missingLibraryCard })
]),
div({
datacy: 'researcher-info-profile-unsubmitted',
isRendered: (completed === false && libraryCardReqSatisfied === true), className: 'rp-alert' }, [
Alert({ id: 'profileUnsubmitted', type: 'danger', title: profileUnsubmitted })
!readOnlyMode && Alert({ id: 'profileUnsubmitted', type: 'danger', title: profileUnsubmitted })
]),
div({
datacy: 'researcher-info-profile-submitted',
isRendered: (completed === true && libraryCardReqSatisfied === true), className: 'rp-alert' }, [
Alert({ id: 'profileSubmitted', type: 'info', title: profileSubmitted })
!readOnlyMode && Alert({ id: 'profileSubmitted', type: 'info', title: profileSubmitted })
]),
]),
div({ className: 'flex-row', style: { justifyContent: 'flex-start' } }, [
Expand Down Expand Up @@ -151,7 +153,7 @@ export default function ResearcherInfo(props) {

div({className: 'dar-application-row', datacy: 'internal-lab-staff'}, [
h3('1.4 Internal Lab Staff'),
div(
includeInstructions && div(
`Please add internal Lab Staff here. Internal Lab Staff are defined as users of data from
this data access request, including any that are downloaded or utilized in the cloud.
please do not list External Collaborators or Internal Collaborators at a PI or equivalent
Expand All @@ -173,7 +175,7 @@ export default function ResearcherInfo(props) {

div({className: 'dar-application-row', datacy: 'internal-collaborators'}, [
h3('1.5 Internal Collaborators'),
div(
includeInstructions && div(
`Please list Internal Collaborators here. Internal Collaborators are defined as individuals
who are not under the direct supervision of the PI (e.g., not a member of the PI's
laboratory) who assists with the PI's research project involving controlled-access data
Expand Down Expand Up @@ -364,7 +366,7 @@ export default function ResearcherInfo(props) {

div({className: 'dar-application-row', datacy: 'external-collaborators'}, [
h3('1.9 External Collaborators'),
div(
includeInstructions && div(
`Please list External collaborators here. External Collaborators are not employees of the
Requesting PI's institution and/or do not work at the same location as the PI, and
consequently must be independently approved to access controlled-access data subject to
Expand Down
9 changes: 7 additions & 2 deletions src/pages/dar_application/collaborator/CollaboratorList.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,16 @@ export default function CollaboratorList(props) {
id: `add-${collaboratorKey}-btn`,
type: 'button', // default button element type inside a form is "submit".
className: 'button button-white',
style: { marginTop: 25, marginBottom: 5 },
style: {
marginTop: 25,
marginBottom: 5,
...(props.disabled ? { cursor: 'not-allowed' } : {}),
},
onClick: () => {
!props.disabled && setShowNewForm(true);
},
isRendered: !showNewForm
isRendered: !showNewForm,
disabled: props.disabled,
}, [`Add ${collaboratorLabel}`]),
h(CollaboratorForm, {
index: collaborators.length,
Expand Down
Loading

0 comments on commit 481a9fc

Please sign in to comment.