diff --git a/client/src/components/projects/ProjectView.jsx b/client/src/components/projects/ProjectView.jsx index 1594dcde..241b061d 100644 --- a/client/src/components/projects/ProjectView.jsx +++ b/client/src/components/projects/ProjectView.jsx @@ -67,7 +67,8 @@ import { constructProjectTeam, checkCanViewProjectDetails, checkProjectAdminPermission, - checkProjectMemberPermission + checkProjectMemberPermission, + PROJECT_ROLE_SORT_ORDER } from '../util/ProjectHelpers.js'; import { licenseOptions, @@ -104,6 +105,7 @@ const ProjectView = (props) => { const [showFiles, setShowFiles] = useState(true); const [showReviewerCrumb, setShowReviewerCrumb] = useState(false); const [showJoinComingSoon, setShowJoinComingSoon] = useState(false); + const [showAllTeamMembers, setShowAllTeamMembers] = useState(false); // Project Data const [project, setProject] = useState({}); @@ -1718,31 +1720,74 @@ const ProjectView = (props) => { } }; - const renderTeamList = (projData) => { - const renderListItem = (item, role, idx) => { + const renderTeamList = (projData, showAll) => { + const transformMembers = (role, roleDisplay) => (item) => ({ + ...item, + name: `${item.firstName} ${item.lastName}`, + role, + roleDisplay, + }); + + const allTeamMembers = [ + ...projData.leads.map(transformMembers('lead', 'Lead')), + ...projData.liaisons.map(transformMembers('liaison', 'Liaison')), + ...projData.members.map(transformMembers('member', 'Member')), + ...projData.auditors.map(transformMembers('auditor', 'Auditor')), + ]; + allTeamMembers.sort((a, b) => { + if (PROJECT_ROLE_SORT_ORDER[a.role] < PROJECT_ROLE_SORT_ORDER[b.role]) { + return -1; + } + if (PROJECT_ROLE_SORT_ORDER[a.role] > PROJECT_ROLE_SORT_ORDER[b.role]) { + return 1; + } + return a.name.localeCompare(b.name); + }); + + const moreThanFive = allTeamMembers.length > 5; + const teamToDisplay = (!showAll && moreThanFive) ? allTeamMembers.slice(0, 5): allTeamMembers; + + const renderListItem = (item, idx) => { return ( - + - {item.firstName} {item.lastName} ({role}) + + {item.firstName} {item.lastName}{" "} + ({item.roleDisplay}) + ); }; + return ( - - {(projData.hasOwnProperty('leads') && Array.isArray(projData.leads)) && - sortUsersByName(project.leads).map((item, idx) => renderListItem(item, 'Lead', idx)) - } - {(projData.hasOwnProperty('liaisons') && Array.isArray(projData.liaisons)) && - sortUsersByName(project.liaisons).map((item, idx) => renderListItem(item, 'Liaison', idx)) - } - {(projData.hasOwnProperty('members') && Array.isArray(projData.members)) && - sortUsersByName(project.members).map((item, idx) => renderListItem(item, 'Member', idx)) - } - {(projData.hasOwnProperty('auditors') && Array.isArray(projData.auditors)) && - sortUsersByName(project.auditors).map((item, idx) => renderListItem(item, 'Auditor', idx)) - } + + {teamToDisplay.map((item, idx) => renderListItem(item, idx))} + {!showAll && moreThanFive && ( + + +

+ Team list collapsed for brevity.{" "} + setShowAllTeamMembers(!showAllTeamMembers)}> + Click to show all... + +

+
+
+ )} + {showAll && moreThanFive && ( + + +

+ Showing all team members.{" "} + setShowAllTeamMembers(!showAllTeamMembers)}> + Click to collapse... + +

+
+
+ )}
- ) + ); }; return ( @@ -2103,7 +2148,7 @@ const ProjectView = (props) => {
Team
{(Object.keys(project).length > 0) && - renderTeamList(project) + renderTeamList(project, showAllTeamMembers) }
diff --git a/client/src/components/util/ProjectHelpers.js b/client/src/components/util/ProjectHelpers.js index c3ca7f83..d712fc23 100644 --- a/client/src/components/util/ProjectHelpers.js +++ b/client/src/components/util/ProjectHelpers.js @@ -48,6 +48,13 @@ const classificationDescriptions = [ } ]; +const PROJECT_ROLE_SORT_ORDER = { + lead: 1, + liaison: 2, + member: 3, + auditor: 4, +}; + const projectRoleOptions = [ { key: 'lead', text: 'Team Lead', value: 'lead' }, { key: 'liaison', text: 'Project Liaison', value: 'liaison' }, @@ -376,6 +383,7 @@ const getFilesAccessText = (access) => { export { PROJECT_FILES_ACCESS_SETTINGS, + PROJECT_ROLE_SORT_ORDER, visibilityOptions, statusOptions, createTaskOptions,