diff --git a/src/components/ChallengesComponent/ChallengeCard/index.js b/src/components/ChallengesComponent/ChallengeCard/index.js index 786e70c9..5a1258ae 100644 --- a/src/components/ChallengesComponent/ChallengeCard/index.js +++ b/src/components/ChallengesComponent/ChallengeCard/index.js @@ -16,6 +16,7 @@ import styles from './ChallengeCard.module.scss' import { getFormattedDuration, formatDate } from '../../../util/date' import { CHALLENGE_STATUS, COMMUNITY_APP_URL, DIRECT_PROJECT_URL, MESSAGE, ONLINE_REVIEW_URL } from '../../../config/constants' import ConfirmationModal from '../../Modal/ConfirmationModal' +import { checkChallengeEditPermission } from '../../../util/tc' import AlertModal from '../../Modal/AlertModal' import Tooltip from '../../Tooltip' @@ -28,6 +29,9 @@ const DRAFT_MSG = 'In Draft' const STALLED_TIME_LEFT_MSG = 'Challenge is currently on hold' const FF_TIME_LEFT_MSG = 'Winner is working on fixes' +const PERMISSION_DELETE_MESSAGE_ERROR = + "You don't have permission to delete this challenge" + /** * Format the remaining time of a challenge phase * @param phase Challenge phase @@ -187,7 +191,9 @@ class ChallengeCard extends React.Component { isConfirm: false, isLaunch: false, isDeleteLaunch: false, - isSaving: false + isSaving: false, + isCheckChalengePermission: false, + hasEditChallengePermission: false } this.onUpdateConfirm = this.onUpdateConfirm.bind(this) this.onUpdateLaunch = this.onUpdateLaunch.bind(this) @@ -208,8 +214,19 @@ class ChallengeCard extends React.Component { } deleteModalLaunch () { + const { challenge } = this.props if (!this.state.isDeleteLaunch) { - this.setState({ isDeleteLaunch: true }) + checkChallengeEditPermission(challenge.id).then(hasPermission => { + this.setState({ + isCheckChalengePermission: false, + hasEditChallengePermission: hasPermission + }) + }) + this.setState({ + isDeleteLaunch: true, + isCheckChalengePermission: true, + hasEditChallengePermission: false + }) } } @@ -254,25 +271,32 @@ class ChallengeCard extends React.Component { } render () { - const { isLaunch, isConfirm, isSaving, isDeleteLaunch } = this.state + const { isLaunch, isConfirm, isSaving, isDeleteLaunch, isCheckChalengePermission, hasEditChallengePermission } = this.state const { challenge, shouldShowCurrentPhase, reloadChallengeList } = this.props const { phaseMessage, endTime } = getPhaseInfo(challenge) + const deleteMessage = isCheckChalengePermission + ? 'Checking permissions...' + : `Do you want to delete "${challenge.name}"?` + return (
- { - isDeleteLaunch && !isConfirm && ( - - ) - } - { isLaunch && !isConfirm && ( + {isDeleteLaunch && !isConfirm && ( + + )} + {isLaunch && !isConfirm && ( ( +const ConfirmationModal = ({ title, message, errorMessage, theme, isProcessing, onCancel, onConfirm, disableConfirmButton }) => (
{title}
@@ -23,6 +23,7 @@ const ConfirmationModal = ({ title, message, errorMessage, theme, isProcessing,
@@ -39,6 +40,7 @@ ConfirmationModal.propTypes = { errorMessage: PropTypes.string, theme: PropTypes.shape(), isProcessing: PropTypes.bool, + disableConfirmButton: PropTypes.bool, onCancel: PropTypes.func, onConfirm: PropTypes.func } diff --git a/src/util/tc.js b/src/util/tc.js index 9dc63376..b0b95e03 100644 --- a/src/util/tc.js +++ b/src/util/tc.js @@ -4,6 +4,8 @@ import { MARATHON_MATCH_SUBTRACKS, CHALLENGE_TRACKS, ALLOWED_USER_ROLES, ADMIN_ROLES, SUBMITTER_ROLE_UUID } from '../config/constants' import _ from 'lodash' import { decodeToken } from 'tc-auth-lib' +import { fetchResources, fetchResourceRoles } from '../services/challenges' +import store from '../config/store' export const RATING_COLORS = [{ color: '#9D9FA0' /* Grey */, @@ -77,3 +79,40 @@ export const getResourceRoleByName = (resourceRoles, name) => { return _.find(resourceRoles, { name }) || null } } + +/** + * check edit permission + * @param {number} challengeId challenge Id + * + * @returns {boolean} hasPermission + */ +export const checkChallengeEditPermission = async (challengeId) => { + const state = store.getState() + const token = state.auth.token + const loggedInUser = state.auth.user + const hasProjectAccess = state.projects.hasProjectAccess + + const isAdmin = checkAdmin(token) + if (isAdmin) { + return true + } + if (!hasProjectAccess) { + return false + } + + return Promise.all([fetchResources(challengeId), fetchResourceRoles()]).then( + ([challengeResources, resourceRoles]) => { + const userRoles = _.filter( + challengeResources, + cr => cr.memberId === `${loggedInUser.userId}` + ) + const userResourceRoles = _.filter(resourceRoles, rr => + _.some(userRoles, ur => ur.roleId === rr.id) + ) + return _.some( + userResourceRoles, + urr => urr.fullWriteAccess && urr.isActive + ) + } + ) +}