-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Duos UI 2602 affiliation and roles (#2290)
* added email text field * added new user page * stopped page from reloading * removed sections that are not needed * removed all sections except name/email * removed props * removed functions that were not needed * created user profile directory * changed fields to read-only * used read-only form fields * initialized controlled access grants page * affiliation and roles * completed affiliation and roles component * removed unnecessary files * deleted ControlledAccessGrants * Update ChairConsole.js * Update ajax.js * Update src/Routes.js Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com> * Update Routes.js * Update Routes.js * Update src/Routes.js Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com> * Update src/Routes.js Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com> * added new role component * Revert "Update src/Routes.js" This reverts commit 86b2511. * Update src/Routes.js Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com> * Update src/pages/user_profile/NewRole.js Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com> * Update Routes.js * Delete NewRole.js * Update UserProfile.js * Update UserProfile.js * Update UserProfile.js * Update package.json * Update package-lock.json * fix: ensure lockfile uses lf instead of crlf --------- Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com> Co-authored-by: Florian Boulnois <fboulnoi@broadinstitute.org>
- Loading branch information
1 parent
cc77769
commit 50cec31
Showing
4 changed files
with
286 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,4 +103,4 @@ export default function ChairConsole(props) { | |
consoleType: consoleTypes.CHAIR | ||
}), | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
import { useEffect, useState } from 'react'; | ||
import { Institution, User } from '../../libs/ajax'; | ||
import { find, isNil, isNumber } from 'lodash'; | ||
import { div, p, h1, h, input, button } from 'react-hyperscript-helpers'; | ||
import { Notifications } from '../../libs/utils'; | ||
import { FormField, FormFieldTypes } from '../../components/forms/forms'; | ||
|
||
|
||
export default function AffiliationAndRole(props) { | ||
|
||
const { | ||
user, | ||
userProps, | ||
institutions | ||
} = props; | ||
|
||
const [profile, setProfile] = useState({ | ||
roles: '', | ||
institutionId: undefined, | ||
suggestedInstitution: undefined, | ||
selectedSigningOfficialId: undefined, | ||
suggestedSigningOfficial: undefined, | ||
id: undefined | ||
}); | ||
|
||
const [selectedInstitution, setSelectedInstitution] = useState(); | ||
|
||
useEffect(() => { | ||
const init = async () => { | ||
try { | ||
const rolesList = []; | ||
if (!isNil(user) && !isNil(user.roles)) { | ||
for (let i = 0; i < user.roles.length; i++) { | ||
const newRole = user.roles[i].name; | ||
rolesList.push(newRole); | ||
} | ||
const allRoles = rolesList.join(', '); | ||
setProfile({ | ||
roles: allRoles, | ||
institutionId: user.institutionId || userProps.institutionId, | ||
suggestedInstitution: userProps.suggestedInstitution, | ||
selectedSigningOfficialId: parseInt(userProps.selectedSigningOfficialId), | ||
suggestedSigningOfficial: userProps.suggestedSigningOfficial, | ||
id: user.userId | ||
}); | ||
} | ||
} catch (error) { | ||
Notifications.showError({ text: 'Error: Unable to retrieve user data from server' }); | ||
} | ||
}; | ||
|
||
init(); | ||
|
||
}, [user, userProps]); | ||
|
||
useEffect(() => { | ||
if (profile.institutionId) { | ||
Institution.getById(profile.institutionId).then((institution) => { | ||
if (!institution) { | ||
return; | ||
} | ||
setSelectedInstitution(institution); | ||
}); | ||
} else { | ||
setSelectedInstitution(null); | ||
} | ||
}, [profile.institutionId]); | ||
|
||
|
||
const hasInstitution = () => { | ||
return (isNumber(profile.institutionId) && profile.institutionId !== 0) || (profile.suggestedInstitution !== undefined && profile.suggestedInstitution !== ''); | ||
}; | ||
|
||
const isSigningOfficial = () => { | ||
return user.isSigningOfficial; | ||
}; | ||
|
||
const submitForm = async (event) => { | ||
event.preventDefault(); | ||
await updateInstitution(); | ||
}; | ||
|
||
const formIsValid = () => { | ||
return !hasInstitution() || !isSigningOfficial(); | ||
}; | ||
|
||
const updateInstitution = async () => { | ||
const payload = { | ||
institutionId: profile.institutionId, | ||
suggestedInstitution: profile.suggestedInstitution | ||
}; | ||
|
||
let updatedUser = await User.updateSelf(payload); | ||
return updatedUser; | ||
}; | ||
|
||
const generateInstitutionSelectionDisplay = () => { | ||
if (!isSigningOfficial() || (isNil(profile.institutionId) && isNil(profile.suggestedInstitution))) { | ||
return div({}, | ||
[ | ||
h(FormField, { | ||
id: 'institutionId', | ||
type: FormFieldTypes.SELECT, | ||
selectOptions: (institutions).map((i) => { | ||
return { | ||
institutionId: i.id, | ||
displayText: i.name, | ||
}; | ||
}), | ||
placeholder: 'Search for Institution...', | ||
isCreatable: true, | ||
defaultValue: { | ||
institutionId: selectedInstitution?.institutionId, | ||
suggestedInstitution: profile.suggestedInstitution, | ||
displayText: ( | ||
(!isNil(selectedInstitution) | ||
? `${selectedInstitution.name}` | ||
: (!isNil(profile.suggestedInstitution) | ||
? `${profile.suggestedInstitution}` | ||
: '')) | ||
), | ||
}, | ||
selectConfig: { | ||
clearValue: () => { | ||
setProfile(Object.assign({}, | ||
profile, | ||
{ | ||
institutionId: undefined, | ||
suggestedInstitution: undefined | ||
})); | ||
}, | ||
}, | ||
onChange: ({ value }) => { | ||
if (!isNil(value?.institutionId)) { | ||
setProfile(Object.assign({}, profile, { | ||
institutionId: value?.institutionId, | ||
suggestedInstitution: undefined | ||
})); | ||
} else { | ||
setProfile(Object.assign({}, profile, { | ||
institutionId: undefined, | ||
suggestedInstitution: value?.displayText | ||
})); | ||
} | ||
} | ||
}), | ||
] | ||
); | ||
} else { | ||
let institution = (profile.institutionId ? find(institutions, { id: profile.institutionId }) : null); | ||
const institutionName = (institution ? institution.name : profile.suggestedInstitution); | ||
|
||
|
||
return div({ | ||
className: '', | ||
style: { padding: 0 }, | ||
}, [ | ||
input({ | ||
id: 'profileInstitution', | ||
name: 'institution', | ||
type: 'text', | ||
disabled: true, | ||
className: 'form-control', | ||
value: institutionName, | ||
}), | ||
]); | ||
} | ||
}; | ||
|
||
return div({}, [ | ||
h1({ | ||
style: { | ||
color: '#01549F', | ||
fontSize: '20px', | ||
fontWeight: '600', | ||
} | ||
}, ['Affiliation & Role']), | ||
div({ className: '', style: { 'marginTop': '20px' } }, []), | ||
div({ | ||
style: | ||
{ | ||
color: '#000', | ||
fontFamily: 'Montserrat', | ||
fontSize: '16px', | ||
fontStyle: 'normal', | ||
fontWeight: '600', | ||
lineHeight: 'normal' | ||
} | ||
}, | ||
[ | ||
p({}, ['Institution']), | ||
div({ style: { marginBottom: '15px' } }, []), | ||
generateInstitutionSelectionDisplay(), | ||
button({ | ||
id: 'btn_submit', | ||
onClick: submitForm, | ||
className: 'f-right btn-primary common-background', | ||
style: { | ||
marginTop: '2rem', | ||
}, | ||
disabled: !formIsValid(), | ||
}, ['Save']), | ||
div({ className: '', style: { 'marginTop': '83px' } }, []), | ||
p({}, ['Role']), | ||
]), | ||
p({}, [profile.roles]), | ||
]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,96 @@ | ||
import {useState, useEffect} from 'react'; | ||
import {div, h, h1, hr} from 'react-hyperscript-helpers'; | ||
import {FormField, FormFieldTypes} from '../../components/forms/forms'; | ||
import {PageHeading} from '../../components/PageHeading'; | ||
import {Notification} from '../../components/Notification'; | ||
import {User} from '../../libs/ajax'; | ||
import {NotificationService} from '../../libs/notificationService'; | ||
import { Notifications} from '../../libs/utils'; | ||
|
||
import { useState, useEffect } from 'react'; | ||
import { div, h, h1, hr } from 'react-hyperscript-helpers'; | ||
import { FormField, FormFieldTypes } from '../../components/forms/forms'; | ||
import { PageHeading } from '../../components/PageHeading'; | ||
import { Notification } from '../../components/Notification'; | ||
import AffiliationAndRoles from './AffiliationAndRoles'; | ||
import { Institution } from '../../libs/ajax'; | ||
import { Storage } from '../../libs/storage'; | ||
import { NotificationService } from '../../libs/notificationService'; | ||
import { Notifications, getPropertyValuesFromUser } from '../../libs/utils'; | ||
|
||
export default function UserProfile() { | ||
|
||
const [user, setUser] = useState({}); | ||
const [userProps, setUserProps] = useState({}); | ||
const [institutions, setInstitutions] = useState([]); | ||
|
||
const [profile, setProfile] = useState({ | ||
profileName: '', | ||
email: undefined, | ||
id: undefined | ||
}); | ||
|
||
const [notificationData, setNotificationData] = useState(); | ||
const [notificationData, setNotificationData] = useState({}); | ||
|
||
useEffect(() => { | ||
const init = async () => { | ||
try { | ||
await getUserProfile(); | ||
|
||
const user = Storage.getCurrentUser(); | ||
setUser(user); | ||
setUserProps(getPropertyValuesFromUser(user)); | ||
setProfile({ | ||
profileName: user.displayName, | ||
email: user.email, | ||
id: user.userId | ||
}); | ||
const institutions = await Institution.list(); | ||
setInstitutions(institutions); | ||
setNotificationData(await NotificationService.getBannerObjectById('eRACommonsOutage')); | ||
} catch (error) { | ||
Notifications.showError({text: 'Error: Unable to retrieve user data from server'}); | ||
Notifications.showError({ text: 'Error: Unable to retrieve user data from server' }); | ||
} | ||
}; | ||
|
||
init(); | ||
}, []); | ||
|
||
const getUserProfile = async () => { | ||
const user = await User.getMe(); | ||
|
||
setProfile({ | ||
profileName: user.displayName, | ||
email: user.email, | ||
id: user.userId | ||
}); | ||
}; | ||
|
||
return ( | ||
div({ | ||
className: 'container', | ||
return div({ | ||
className: '', | ||
style: { | ||
flexDirection: 'column', | ||
padding: '20px 240px 20px' | ||
} | ||
}, [ | ||
div({ className: '' }, [ | ||
Notification({notificationData}), | ||
PageHeading({ | ||
id: 'researcherProfile', | ||
color: 'common', | ||
title: 'Your Profile', | ||
description: 'Please complete the form below to start using DUOS.' | ||
}), | ||
hr({ className: 'section-separator' }) | ||
]), | ||
h1({ | ||
style: { | ||
color: '#333F52', | ||
}, | ||
}, [ | ||
div({ className: 'row no-margin'}, [ | ||
div({ className: 'col-md-10 col-md-offset-1 col-sm-12 col-xs-12' }, [ | ||
Notification({notificationData}), | ||
PageHeading({ | ||
id: 'researcherProfile', | ||
color: 'common', | ||
title: 'Your Profile', | ||
description: 'Please complete the form below to start using DUOS.' | ||
}), | ||
hr({ className: 'section-separator' }) | ||
]), | ||
div({ | ||
className: 'col-md-10 col-md-offset-1 col-xs-12 no-padding', | ||
style: { | ||
fontFamily: 'Montserrat', | ||
} }, [ | ||
h1({style: { | ||
color: '#01549F', | ||
fontSize: '20px', | ||
fontWeight: '600', | ||
} }, ['Full Name:']), | ||
div({ className: '', style: { 'marginTop': '10px' } }, []), | ||
h(FormField, { | ||
id: 'profileName', | ||
type: FormFieldTypes.TEXT, | ||
defaultValue: profile.profileName, | ||
readOnly: true, | ||
}), | ||
div({ className: '', style: { 'marginTop': '10px' } }, []), | ||
h(FormField, { | ||
id: 'profileEmail', | ||
type: FormFieldTypes.TEXT, | ||
defaultValue: profile.email, | ||
readOnly: true, | ||
}), | ||
]) | ||
]) | ||
]) | ||
); | ||
} | ||
color: '#01549F', | ||
fontSize: '20px', | ||
fontWeight: '600', | ||
marginBottom: '15px', | ||
marginTop: '40px' | ||
} | ||
}, ['Full Name']), | ||
h(FormField, { | ||
type: FormFieldTypes.TEXT, | ||
id: 'profileName', | ||
defaultValue: profile.profileName, | ||
readOnly: true, | ||
}), | ||
div({ className: '', style: { 'marginTop': '10px' } }, []), | ||
h(FormField, { | ||
type: FormFieldTypes.TEXT, | ||
id: 'profileEmail', | ||
defaultValue: profile.email, | ||
readOnly: true, | ||
}), | ||
div({ className: '', style: { 'marginTop': '60px' } }, []), | ||
AffiliationAndRoles({ | ||
user: user, | ||
userProps: userProps, | ||
institutions: institutions | ||
}), | ||
]); | ||
|
||
} |