Skip to content

Commit

Permalink
[DUOS-1759][risk=no] Updated step selector for data access request pa…
Browse files Browse the repository at this point in the history
…ge (#1787)

* [DUOS-1752] Added initial attempt at step1 of the new dar application request page
- Added radio group option to forms
- Added global styles (initial start)
- Modified forms to extract some of the specific styling to the data submission form (that this page doesnt share)

* [DUOS-1752] fixed key issue

* Update src/components/forms/forms.js

Co-authored-by: Gregory Rushton <rushtong@users.noreply.github.com>

* [DUOS-1752] moved the new researcher components into the old researcher component >.<

* [DUOS-1669] reorganized the css, added creatable select option. Want to change the normal select so it does not allow you to add a value, but later. Moved new researcher code to the existing researcher component.

* [common-forms] reorganized the css, added creatable select option. Want to change the normal select so it does not allow you to add a value, but later

* [common-forms] added some of Shae's changes

* [common-forms] reorganized files again

* [common-forms] fixed eslint

* [common-forms] removed unnecessary css liine

* [common-forms] split formComponents css into a separate file as well. Removed explicit creatable formfieldType - it will now create if a creatableConfig is provided, otherwise, it will not allow the user to add new fields

* codacy

* fixed unit tests and codacy

* removed searchPlaceholder in favor of keeping "placeholder"

* [DUOS-1752] Hooked up form components with actions and variables.

* [DUOS-1752] moved code to a new component, reverted researcherInfo to orig

* [DUOS-1752] Added warning

* [DUOS-1752] Added textarea to formComponents, fixed signing official not saving value, converted input checkboxes to FormField components - will update the radio later :(

* [DUOS-1752] added z index so the error message will overlay on top of the form components

* [DUOS-1759] added side bar selector

* [DUOS-1759] im sorry it's a mess

* [DUOS-1752] reverted data access request application changes, just duped it out into a new file instead.

* [DUOS-1752] replaced radio group components with the formField radio component

* [DUOS-1752] replaced radio group components with the formField radio component

* [DUOS-1752] removed dead code, added aria leveling

* fixed merge errors

* fixed error:
> Warning: You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.

Not sure if this is the right fix

* [DUOS-1759] updated so position:sticky will work!

* [DUOS-1759] converted tabs to an array, life is just easier this way lol

* [DUOS-1759] few changes:
1. position-stickyed the step bar
2. added window eventListener to watch for changes in scroll position and select the appropriate step.
3. One hiccup was that when you clicked on a section, it would slowly scroll there in the tab selector since the onScroll would update for the current position, overtaking the default where the tab selector would immediately change, and that ~.5s delay felt realy bad... so I added a debounce manually. Tried to do it through lodash, but it wasn't working, and I wasnt sure why.

* [DUOS-1759] testing.... to see if eslint-disable-line allows you to skirt codacy rules

* [DUOS-1759] testing.... to see if eslint-disable-line allows you to skirt codacy rules

* [DUOS-1752] disabled name, fixed default value not being set for checkboxes and radio components on the cloud use section

* [DUOS-1752] updated form field id, updated routes to lock new dev routes behind env

* [DUOS-1752] removed progress section, which meant updating the class ids, which ... isnt ideal. So updated the methods to use class instead of id, since the ids should not have to be futzed with and tied to the step they show up in!

* [DUOS-1752] updated default value to undefined by default

* [DUOS-1752] moved related code into same div

* codacy

* flipped direction of children

* [DUOS-1752] codacy

Co-authored-by: Gregory Rushton <rushtong@users.noreply.github.com>
  • Loading branch information
lu-c and rushtong authored Sep 14, 2022
1 parent bf3efa8 commit 875e43a
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 73 deletions.
1 change: 1 addition & 0 deletions src/components/Alert.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
background-color: white;
border: 1px solid #6B0080;
border-radius: 5px;
font-weight: bold;
}

.alert-title {
Expand Down
2 changes: 1 addition & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ html, body, .body, #root {

.main {
position: relative;
overflow-x: hidden;
overflow-x: clip;
min-width: 100%;
min-height: 100vh;
/* must be same height as the footer */
Expand Down
72 changes: 72 additions & 0 deletions src/pages/DataAccessRequestApplication.css
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,75 @@ fieldset[disabled] .regular-checkbox:before {
cursor: not-allowed !important;
opacity: 0.65;
}

/* ------------------------------------- */
/* New Forms Styles */
/* ------------------------------------- */
.forms-v2 {
border-top: 1px solid #929292;
display: flex;
flex-direction: row;
margin-top: 30px;
padding: 0;
}

.step-container {
clear: both;
}

/* ------------------------------------- */
/* MUI Overrides */
/* ------------------------------------- */
.multi-step-buttons-container {
width: 200px;
flex-shrink: 0;
margin-top: 25px;
margin-right: 25px;
position: sticky;
top: 0;
align-self: flex-start;
}

.multi-step-buttons-container .MuiButtonBase-root {
align-items: flex-start;
}

.multi-step-buttons-container .MuiTabs-indicator {
width: 5px;
right: unset;
left: 0;
}

.multi-step-buttons-container .MuiButtonBase-root {
margin-top: 25px;
padding-left: 20px;
}

.multi-step-buttons-container .step,
.multi-step-buttons-container .Mui-selected .step {
font-size: 14px;
font-weight: bold;
font-family: 'Montserrat';
color: #646464;
text-transform: none;
text-align: left;
margin-bottom: 5px;
}

.multi-step-buttons-container .title {
font-size: 17px;
font-weight: bold;
font-family: 'Montserrat';
text-transform: none;
text-align: left;
color: #333F52;
}

.multi-step-buttons-container .Mui-selected .title {
color: #2BBD9B;
}

.multi-step-buttons-container .MuiTouchRipple-root span {
background-color: rgba(43, 189, 155, .3);
}

3 changes: 2 additions & 1 deletion src/pages/DataAccessRequestApplication.js
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ class DataAccessRequestApplication extends Component {
]),
hr({ className: 'section-separator' }),

div({ className: 'row fsi-row-lg-level fsi-row-md-level multi-step-buttons no-margin' }, [
div({ className: `row fsi-row-lg-level fsi-row-md-level multi-step-buttons no-margin` }, [

a({
id: 'btn_step_1',
Expand Down Expand Up @@ -951,6 +951,7 @@ class DataAccessRequestApplication extends Component {
])
])
]),

form({ name: 'form', 'noValidate': true }, [
div({ id: 'form-views' }, [

Expand Down
163 changes: 97 additions & 66 deletions src/pages/DataAccessRequestApplication_new.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component } from 'react';
import { a, div, form, h, hr, i, small, span } from 'react-hyperscript-helpers';
import { a, div, form, h, i } from 'react-hyperscript-helpers';
import ResearcherInfo from './dar_application/ResearcherInfo_new';
import DataAccessRequest from './dar_application/DataAccessRequest';
import ResearchPurposeStatement from './dar_application/ResearchPurposeStatement';
Expand All @@ -19,7 +19,15 @@ import { Storage } from '../libs/storage';
import { any, assign, cloneDeep, find, get, getOr, head, isEmpty, isNil, keys, map, merge, pickBy } from 'lodash/fp';
import './DataAccessRequestApplication.css';
import headingIcon from '../images/icon_add_access.png';

import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';

const ApplicationTabs = [
{ name: 'Researcher Information' },
{ name: 'Data Access Request' },
{ name: 'Research Purpose Statement' },
{ name: 'Data Use Agreement', showStep: false }
];
class DataAccessRequestApplicationNew extends Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -103,13 +111,15 @@ class DataAccessRequestApplicationNew extends Component {
invalid: false
}
},
problemSavingRequest: false
problemSavingRequest: false,
forcedScroll: null
};

this.goToStep = this.goToStep.bind(this);
this.formFieldChange = this.formFieldChange.bind(this);
this.partialSave = this.partialSave.bind(this);
this.changeDARDocument = this.changeDARDocument.bind(this);
this.onScroll = this.onScroll.bind(this);
}

//helper function to coordinate local state changes as well as updates to form data on the parent
Expand Down Expand Up @@ -162,6 +172,10 @@ class DataAccessRequestApplicationNew extends Component {
});
}

async componentWillUnmount () {
window.removeEventListener('scroll', this.onScroll);
}

async getDatasets(formData) {
const dsIds = get('datasetIds')(formData);
let datasets;
Expand Down Expand Up @@ -215,6 +229,8 @@ class DataAccessRequestApplicationNew extends Component {
prev.formData = merge(prev.formData, formData);
return prev;
});

window.addEventListener('scroll', this.onScroll); // eslint-disable-line -- codacy says event listeners are dangerous
}

formatDatasetForAutocomplete = (dataset) => {
Expand Down Expand Up @@ -273,27 +289,62 @@ class DataAccessRequestApplicationNew extends Component {

//NOTE: use nextPage and previous page instead of having individual go to pages for each step
nextPage = () => {
this.setState(prev => {
prev.step = prev.step + 1;
return prev;
});
window.scrollTo(0,0);
this.goToStep(this.state.step + 1);
};

prevPage = () => {
this.goToStep(this.state.step - 1);
};

goToStep = (step = 1) => {
this.resetForcedScrollDebounce();
this.setState(prev => {
prev.step = prev.step - 1;
prev.step = step;
return prev;
});
window.scrollTo(0,0);
window.scroll({
top: document.getElementsByClassName('step-container')[step - 1].offsetTop,
behavior: 'smooth'
});
};

goToStep = (step = 1) => {
onScroll = () => {
if (this.state.forcedScroll) {
this.resetForcedScrollDebounce();
} else {
const scrollPos = window.scrollY;
const scrollBuffer = window.innerHeight * .25;
const sectionIndex = ApplicationTabs
.map((tab, index) => document.getElementsByClassName('step-container')[index].offsetTop)
.findIndex(scrollTop => scrollTop > scrollPos + scrollBuffer);

this.setState(prev => {
if (sectionIndex === 0) {
prev.step = 1;
} else if (sectionIndex === -1) {
prev.step = ApplicationTabs.length;
} else {
prev.step = sectionIndex;
}
return prev;
});
}
};

resetForcedScrollDebounce = () => {
if (this.state.forcedScroll) {
clearTimeout(this.state.forcedScroll);
}

this.setState(prev => {
prev.step = step;
prev.forcedScroll = setTimeout(() => { // eslint-disable-line -- codacy says settimeout is dangerous
this.setState(prev => {
prev.forcedScroll = null;
return prev;
});
}, 200);
return prev;
});
window.scrollTo(0, 0);
};

attestAndSave = () => {
Expand Down Expand Up @@ -902,67 +953,47 @@ class DataAccessRequestApplicationNew extends Component {
i({ className: 'glyphicon glyphicon-chevron-left' }), 'Back'
])
])
]),
hr({ className: 'section-separator' }),

div({ className: 'row fsi-row-lg-level fsi-row-md-level multi-step-buttons no-margin' }, [

a({
id: 'btn_step_1',
onClick: (() => this.goToStep(1, false)),
className: 'col-lg-3 col-md-3 col-sm-12 col-xs-12 access-color jumbotron box-vote multi-step-title '
+ (this.state.step === 1 ? 'active' : '')
}, [
small({}, ['Step 1']),
'Researcher Information',
span({ className: 'glyphicon glyphicon-chevron-right', 'aria-hidden': 'true' }, [])
]),

a({
id: 'btn_step_2',
onClick: (() => this.goToStep(2, false)),
className: 'col-lg-3 col-md-3 col-sm-12 col-xs-12 access-color jumbotron box-vote multi-step-title '
+ (this.state.step === 2 ? 'active' : '')
}, [
small({}, ['Step 2']),
'Data Access Request',
span({ className: 'glyphicon glyphicon-chevron-right', 'aria-hidden': 'true' }, [])
]),

a({
id: 'btn_step_3',
onClick: (() => this.goToStep(3, false)),
className: 'col-lg-3 col-md-3 col-sm-12 col-xs-12 access-color jumbotron box-vote multi-step-title '
+ (this.state.step === 3 ? 'active' : '')
}, [
small({}, ['Step 3']),
'Research Purpose Statement',
span({ className: 'glyphicon glyphicon-chevron-right', 'aria-hidden': 'true' }, [])
]),
])
]),

a({
id: 'btn_step_4',
onClick: (() => this.goToStep(4, false)),
className: 'col-lg-3 col-md-3 col-sm-12 col-xs-12 access-color jumbotron box-vote multi-step-title '
+ (this.state.step === 4 ? 'active' : '')
div({ style: { clear: 'both' } }),
form({ name: 'form', 'noValidate': true, className: 'forms-v2' }, [
div({ className: 'multi-step-buttons-container' }, [
h(Tabs, {
value: this.state.step,
variant: 'scrollable',
scrollButtons: 'auto',
orientation: 'vertical',
TabIndicatorProps: {
style: { background: '#2BBD9B' }
},
onChange: (event, step) => {
this.goToStep(step);
}
}, [
small({}, ['Step 4']),
'Attestation & Agreements',
span({ className: 'glyphicon glyphicon-chevron-right', 'aria-hidden': 'true' }, [])
...ApplicationTabs.map((tabConfig, index) => {
const { name, showStep = true } = tabConfig;
return h(Tab, {
key: `step-${index}-${name}`,
label: div([
div({ isRendered: showStep, className: 'step' }, `Step ${index + 1}`),
div({ className: 'title' }, name)
]),
value: index + 1
});
})
])
])
]),
form({ name: 'form', 'noValidate': true }, [
div({ id: 'form-views' }, [
]),

div({ id: 'form-views' }, [
ConfirmationDialog({
title: 'Save changes?', disableOkBtn: this.state.disableOkBtn, disableNoBtn: this.state.disableOkBtn, color: 'access',
showModal: this.state.showDialogSave, action: { label: 'Yes', handler: this.dialogHandlerSave }
}, [
div({ className: 'dialog-description' },
['Are you sure you want to save this Data Access Request? Previous changes will be overwritten.'])
]),
div({ isRendered: this.state.step === 1 && (this.state.formData.researcher !== '') }, [
div({className: 'step-container'}, [
h(ResearcherInfo, ({
checkCollaborator: checkCollaborator,
checkNihDataOnly: checkNihDataOnly,
Expand Down Expand Up @@ -1000,7 +1031,7 @@ class DataAccessRequestApplicationNew extends Component {
}))
]),

div({ isRendered: this.state.step === 2 }, [
div({className: 'step-container'}, [
h(DataAccessRequest, {
darCode: darCode,
datasets: this.state.formData.datasets,
Expand Down Expand Up @@ -1033,7 +1064,7 @@ class DataAccessRequestApplicationNew extends Component {
})
]),

div({ isRendered: this.state.step === 3 }, [
div({className: 'step-container'}, [
h(ResearchPurposeStatement, {
addiction: this.state.formData.addiction,
darCode: darCode,
Expand Down Expand Up @@ -1064,7 +1095,7 @@ class DataAccessRequestApplicationNew extends Component {
})
]),

div({ isRendered: this.state.step === 4 }, [
div({className: 'step-container'}, [
h(DataUseAgreements, {
darCode: darCode,
problemSavingRequest,
Expand Down
7 changes: 2 additions & 5 deletions src/pages/dar_application/ResearcherInfo_new.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,7 @@ export default function ResearcherInfo(props) {
}, [props.signingOfficial, props.checkCollaborator, props.itDirector, props.piName, props.anvilUse, props.cloudUse, props.localUse, props.researcherUser, props.checkNihDataOnly]);

return (
div({
datacy: 'researcher-info',
className: 'col-lg-10 col-lg-offset-1 col-md-12 col-sm-12 col-xs-12' }, [

div({ datacy: 'researcher-info'}, [
div({ style: { backgroundColor: 'rgba(184, 205, 211, .15)', padding: '20px 30px' } }, [
div({
datacy: 'researcher-info-profile-submitted',
Expand Down Expand Up @@ -217,7 +214,7 @@ export default function ResearcherInfo(props) {
const formattedValue = isNil(value) ? '' : formatSOString(value.displayName, value.email);
formFieldChange({name, value: formattedValue});
},
selectOptions: allSigningOfficials,
selectOptions: allSigningOfficials || [''],
selectConfig: {
placeholder: 'Signing Official',
getOptionLabel: (option) => formatSOString(option.displayName, option.email), //formats labels on dropdown
Expand Down

0 comments on commit 875e43a

Please sign in to comment.