diff --git a/circle.yml b/circle.yml index ecf14c803..2084eb9ca 100644 --- a/circle.yml +++ b/circle.yml @@ -19,7 +19,7 @@ compile: deployment: development: - branch: [dev, 'feature/performance-testing'] + branch: dev owner: appirio-tech commands: - ./deploy.sh DEV diff --git a/src/actions/loadUser.js b/src/actions/loadUser.js index 23f3e1991..2194920ac 100644 --- a/src/actions/loadUser.js +++ b/src/actions/loadUser.js @@ -1,5 +1,14 @@ import _ from 'lodash' -import { ACCOUNTS_APP_CONNECTOR_URL, LOAD_USER_SUCCESS, LOAD_USER_FAILURE, ROLE_ADMINISTRATOR, ROLE_CONNECT_COPILOT, ROLE_TOPCODER_USER, ROLE_CONNECT_MANAGER } from '../config/constants' +import { + ACCOUNTS_APP_CONNECTOR_URL, + LOAD_USER_SUCCESS, + LOAD_USER_FAILURE, + ROLE_ADMINISTRATOR, + ROLE_CONNECT_COPILOT, + ROLE_TOPCODER_USER, + ROLE_CONNECT_MANAGER, + ROLE_CONNECT_ADMIN +} from '../config/constants' import { getFreshToken, configureConnector, decodeToken } from 'tc-accounts' import { getUserProfile } from '../api/users' import { EventTypes } from 'redux-segment' @@ -46,6 +55,8 @@ export function loadUserSuccess(dispatch, token) { let userRole if (_.indexOf(currentUser.roles, ROLE_ADMINISTRATOR) > -1) { userRole = ROLE_ADMINISTRATOR + } else if (_.indexOf(currentUser.roles, ROLE_CONNECT_ADMIN) > -1) { + userRole = ROLE_CONNECT_ADMIN } else if (_.indexOf(currentUser.roles, ROLE_CONNECT_MANAGER) > -1) { userRole = ROLE_CONNECT_MANAGER } else if (_.indexOf(currentUser.roles, ROLE_CONNECT_COPILOT) > -1) { diff --git a/src/components/TeamManagement/MemberRow.jsx b/src/components/TeamManagement/MemberRow.jsx index 676747855..992c8bdb1 100644 --- a/src/components/TeamManagement/MemberRow.jsx +++ b/src/components/TeamManagement/MemberRow.jsx @@ -20,7 +20,7 @@ const ActionBtn = (props) => { ) } -const MemberRow = ({ member, currentMember, onMemberDelete, onChangeOwner }) => { +const MemberRow = ({ member, currentMember, currentUser, onMemberDelete, onChangeOwner }) => { let title // rendered member const isOwner = member.isPrimary && member.isCustomer @@ -44,14 +44,14 @@ const MemberRow = ({ member, currentMember, onMemberDelete, onChangeOwner }) => if (!isCurrentOwner && !member.isCopilot) { buttons.push() } - } else if (currentMember) { + } else if (currentMember || currentUser.isAdmin) { // owner can remove only customers if (isCurrentOwner && member.isCustomer) { buttons.push() } // manager can remove all except owner - if (currentMember.isManager && !isOwner) { + if ((currentMember && currentMember.isManager) || currentUser.isAdmin) { let tooltip = 'Remove team member from project' if (member.isCopilot) { tooltip = 'Remove copilot from project' @@ -59,6 +59,9 @@ const MemberRow = ({ member, currentMember, onMemberDelete, onChangeOwner }) => if (member.isManager) { tooltip = 'Remove manager from project' } + if (member.isCustomer && isOwner) { + tooltip = 'Remove owner from project' + } buttons.push() } diff --git a/src/components/TeamManagement/TeamManagement.jsx b/src/components/TeamManagement/TeamManagement.jsx index edc5f62ed..0e129c311 100644 --- a/src/components/TeamManagement/TeamManagement.jsx +++ b/src/components/TeamManagement/TeamManagement.jsx @@ -61,7 +61,7 @@ const TeamManagement = (props) => { return (
- {currentMember && onToggleAddTeamMember(true)}>Add Team Member} + {(currentMember || currentUser.isAdmin) && onToggleAddTeamMember(true)}>Add Team Member} {modalActive &&
} @@ -114,7 +114,7 @@ const TeamManagement = (props) => { })} {canJoin && } - {currentMember && } + {(currentMember || currentUser.isAdmin) && } { showNewMemberConfirmation && } diff --git a/src/components/TopBar/TopBarContainer.js b/src/components/TopBar/TopBarContainer.js index a2fb81386..daf80a6cf 100644 --- a/src/components/TopBar/TopBarContainer.js +++ b/src/components/TopBar/TopBarContainer.js @@ -10,6 +10,7 @@ import { ROLE_CONNECT_COPILOT, ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR, + ROLE_CONNECT_ADMIN, DOMAIN } from '../../config/constants' require('./TopBarContainer.scss') @@ -122,7 +123,7 @@ class TopBarContainer extends React.Component { const mapStateToProps = ({ loadUser }) => { let isPowerUser = false - const roles = [ROLE_CONNECT_COPILOT, ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR] + const roles = [ROLE_CONNECT_COPILOT, ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR, ROLE_CONNECT_ADMIN] if (loadUser.user) { isPowerUser = loadUser.user.roles.some((role) => roles.indexOf(role) !== -1) } diff --git a/src/config/constants.js b/src/config/constants.js index f4a7e4cd5..6a938d308 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -217,6 +217,7 @@ export const EVENT_ROUTE_CHANGE = 'event.route_change' export const ROLE_TOPCODER_USER = 'Topcoder User' export const ROLE_CONNECT_COPILOT = 'Connect Copilot' export const ROLE_CONNECT_MANAGER = 'Connect Manager' +export const ROLE_CONNECT_ADMIN = 'Connect Admin' export const ROLE_ADMINISTRATOR = 'administrator' // FIXME .. remove defaults diff --git a/src/projects/actions/loadProjects.js b/src/projects/actions/loadProjects.js index 441f048e4..7fda7b5cd 100644 --- a/src/projects/actions/loadProjects.js +++ b/src/projects/actions/loadProjects.js @@ -3,7 +3,7 @@ import { PROJECT_SEARCH, GET_PROJECTS, PROJECT_STATUS, PROJECT_STATUS_CANCELLED, SET_SEARCH_TERM, GET_PROJECTS_SEARCH_CRITERIA, CLEAR_PROJECT_SUGGESTIONS_SEARCH, PROJECT_SUGGESTIONS_SEARCH_SUCCESS, - ROLE_CONNECT_COPILOT, ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR + ROLE_CONNECT_COPILOT, ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR, ROLE_CONNECT_ADMIN } from '../../config/constants' import { getProjects } from '../../api/projects' import { loadMembers } from '../../actions/members' @@ -23,7 +23,7 @@ const getProjectsWithMembers = (dispatch, getState, criteria, pageNum) => { let isPowerUser = false const loadUser = getState().loadUser // power user roles - const roles = [ROLE_CONNECT_COPILOT, ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR] + const roles = [ROLE_CONNECT_COPILOT, ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR, ROLE_CONNECT_ADMIN] if (loadUser.user) { // determine if user is a power user isPowerUser = loadUser.user.roles.some((role) => roles.indexOf(role) !== -1) diff --git a/src/projects/detail/ProjectDetail.jsx b/src/projects/detail/ProjectDetail.jsx index a692ab781..3495c640b 100644 --- a/src/projects/detail/ProjectDetail.jsx +++ b/src/projects/detail/ProjectDetail.jsx @@ -7,7 +7,7 @@ import { renderComponent, branch, compose, withProps } from 'recompose' import { loadProjectDashboard } from '../actions/projectDashboard' import { LOAD_PROJECT_FAILURE, PROJECT_ROLE_CUSTOMER, PROJECT_ROLE_OWNER, - ROLE_ADMINISTRATOR + ROLE_ADMINISTRATOR, ROLE_CONNECT_ADMIN } from '../../config/constants' import spinnerWhileLoading from '../../components/LoadingSpinner' import CoderBot from '../../components/CoderBot/CoderBot' @@ -71,7 +71,7 @@ class ProjectDetail extends Component { render() { const currentMemberRole = this.getProjectRoleForCurrentUser(this.props) - const powerRoles = [ROLE_ADMINISTRATOR] + const powerRoles = [ROLE_ADMINISTRATOR, ROLE_CONNECT_ADMIN] const isSuperUser = this.props.currentUserRoles.some((role) => powerRoles.indexOf(role) !== -1) return ( { - const powerUserRoles = [ROLE_CONNECT_COPILOT, ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR] - const managerRoles = [ ROLE_ADMINISTRATOR, ROLE_CONNECT_MANAGER ] + const adminRoles = [ROLE_ADMINISTRATOR, ROLE_CONNECT_ADMIN] + const powerUserRoles = [ROLE_CONNECT_COPILOT, ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR, ROLE_CONNECT_ADMIN] + const managerRoles = [ ROLE_ADMINISTRATOR, ROLE_CONNECT_ADMIN, ROLE_CONNECT_MANAGER ] return { currentUser: { userId: parseInt(loadUser.user.id), isCopilot: _.indexOf(loadUser.user.roles, ROLE_CONNECT_COPILOT) > -1, + isAdmin: _.intersection(loadUser.user.roles, adminRoles).length > 0, isManager: loadUser.user.roles.some((role) => managerRoles.indexOf(role) !== -1), isCustomer: !loadUser.user.roles.some((role) => powerUserRoles.indexOf(role) !== -1) }, diff --git a/src/projects/list/components/Projects/Projects.jsx b/src/projects/list/components/Projects/Projects.jsx index a9b293c23..4b79bd018 100755 --- a/src/projects/list/components/Projects/Projects.jsx +++ b/src/projects/list/components/Projects/Projects.jsx @@ -9,7 +9,12 @@ import ProjectsCardView from './ProjectsCardView' import { loadProjects } from '../../../actions/loadProjects' import _ from 'lodash' import querystring from 'query-string' -import { ROLE_CONNECT_MANAGER, ROLE_CONNECT_COPILOT, ROLE_ADMINISTRATOR } from '../../../../config/constants' +import { + ROLE_CONNECT_MANAGER, + ROLE_CONNECT_COPILOT, + ROLE_ADMINISTRATOR, + ROLE_CONNECT_ADMIN +} from '../../../../config/constants' // This handles showing a spinner while the state is being loaded async import spinnerWhileLoading from '../../../../components/LoadingSpinner' @@ -172,7 +177,7 @@ class Projects extends Component { const mapStateToProps = ({ projectSearch, members, loadUser }) => { let isPowerUser = false - const roles = [ROLE_CONNECT_COPILOT, ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR] + const roles = [ROLE_CONNECT_COPILOT, ROLE_CONNECT_MANAGER, ROLE_ADMINISTRATOR, ROLE_CONNECT_ADMIN] if (loadUser.user) { isPowerUser = loadUser.user.roles.some((role) => roles.indexOf(role) !== -1) }