Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/constants/development.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ module.exports = {
CONNECT_APP_URL: `https://connect.${DOMAIN}`,
DIRECT_PROJECT_URL: `https://www.${DOMAIN}/direct`,
ONLINE_REVIEW_URL: `https://software.${DOMAIN}`,
DEFAULT_TERM_UUID: '64d6e249-d7a5-4591-8ff5-e872f8a051f9', // Terms & Conditions of Use at TopCoder
DEFAULT_TERM_UUID: '317cd8f9-d66c-4f2a-8774-63c612d99cd4', // Terms & Conditions of Use at TopCoder
DEFAULT_NDA_UUID: 'e5811a7b-43d1-407a-a064-69e5015b4900', // NDA v3.0
SUBMITTER_ROLE_UUID: '732339e7-8e30-49d7-9198-cccf9451e221',
DEV_TRACK_ID: '9b6fc876-f4d9-4ccb-9dfd-419247628825',
Expand Down
3 changes: 2 additions & 1 deletion src/actions/challenges.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,11 @@ export function partiallyUpdateChallengeDetails (challengeId, partialChallengeDe
type: UPDATE_CHALLENGE_DETAILS_SUCCESS,
challengeDetails: challenge
})
}).catch(() => {
}).catch((error) => {
dispatch({
type: UPDATE_CHALLENGE_DETAILS_FAILURE
})
throw error
})
}
}
Expand Down
49 changes: 31 additions & 18 deletions src/components/ChallengeEditor/ReviewType-Field/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,31 @@ import PropTypes from 'prop-types'
import Select from '../../Select'
import cn from 'classnames'
import styles from './ReviewType-Field.module.scss'
import Tooltip from '../../Tooltip'
import { DES_TRACK_ID, REVIEW_TYPES, MESSAGE } from '../../../config/constants'

const ReviewTypeField = ({ reviewers, challenge, onUpdateOthers, onUpdateSelect }) => {
const reviewType = challenge.reviewType ? challenge.reviewType.toLowerCase() : 'community'
const isCommunity = reviewType === 'community'
const isInternal = reviewType === 'internal'
const isDesignChallenge = challenge.trackId === DES_TRACK_ID
const defaultReviewType = isDesignChallenge ? REVIEW_TYPES.INTERNAL : REVIEW_TYPES.COMMUNITY
const reviewType = challenge.reviewType ? challenge.reviewType.toLowerCase() : defaultReviewType
const isCommunity = reviewType === REVIEW_TYPES.COMMUNITY
const isInternal = reviewType === REVIEW_TYPES.INTERNAL
const communityOption = (disabled) => (<div className={styles.tcRadioButton}>
<input
name='community'
type='radio'
id='community'
checked={isCommunity}
disabled={disabled}
onChange={(e) => e.target.checked && onUpdateOthers({ field: 'reviewType', value: 'community' })}
/>
<label htmlFor='community'>
<div className={styles.radioButtonLabel}>
Community
</div>
<input type='hidden' />
</label>
</div>)
return (
<div>
<div className={styles.row}>
Expand All @@ -17,21 +37,14 @@ const ReviewTypeField = ({ reviewers, challenge, onUpdateOthers, onUpdateSelect
<div className={cn(styles.field, styles.col2)}>
<div className={styles.subGroup}>
<div className={styles.subRow}>
<div className={styles.tcRadioButton}>
<input
name='community'
type='radio'
id='community'
checked={isCommunity}
onChange={(e) => e.target.checked && onUpdateOthers({ field: 'reviewType', value: 'community' })}
/>
<label htmlFor='community'>
<div className={styles.radioButtonLabel}>
Community
</div>
<input type='hidden' />
</label>
</div>
{ isDesignChallenge &&
<Tooltip content={MESSAGE.COMMUNITY_REVIEW_DISABLED}>
{ communityOption(true) }
</Tooltip>
}
{ !isDesignChallenge &&
communityOption()
}
</div>
<div className={styles.subRow}>
<div className={styles.tcRadioButton}>
Expand Down
7 changes: 5 additions & 2 deletions src/components/ChallengeEditor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import {
SUBMITTER_ROLE_UUID,
CREATE_FORUM_TYPE_IDS,
MESSAGE,
COMMUNITY_APP_URL
COMMUNITY_APP_URL,
DES_TRACK_ID,
REVIEW_TYPES
} from '../../config/constants'
import { PrimaryButton, OutlineButton } from '../Buttons'
import TrackField from './Track-Field'
Expand Down Expand Up @@ -784,6 +786,7 @@ class ChallengeEditor extends Component {
const { metadata, createChallenge } = this.props
const { name, trackId, typeId } = this.state.challenge
const { timelineTemplates } = metadata
const isDesignChallenge = trackId === DES_TRACK_ID

// indicate that creating process has started
this.setState({ isSaving: true })
Expand All @@ -802,7 +805,7 @@ class ChallengeEditor extends Component {
trackId,
startDate: moment().add(1, 'days').format(),
legacy: {
reviewType: 'community'
reviewType: isDesignChallenge ? REVIEW_TYPES.INTERNAL : REVIEW_TYPES.COMMUNITY
},
descriptionFormat: 'markdown',
timelineTemplateId: defaultTemplate.id,
Expand Down
12 changes: 8 additions & 4 deletions src/components/ChallengesComponent/ChallengeCard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import ChallengeTag from '../ChallengeTag'
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 { patchChallenge } from '../../../services/challenges'
import ConfirmationModal from '../../Modal/ConfirmationModal'
import AlertModal from '../../Modal/AlertModal'
import Tooltip from '../../Tooltip'
Expand Down Expand Up @@ -201,12 +200,16 @@ class ChallengeCard extends React.Component {
}

async onLaunchChallenge () {
const { partiallyUpdateChallengeDetails } = this.props
if (this.state.isSaving) return
const { challenge } = this.props
try {
this.setState({ isSaving: true })
const response = await patchChallenge(challenge.id, { status: 'Active' })
this.setState({ isLaunch: true, isConfirm: response.id, isSaving: false })
// call action to update the challenge with a new status
await partiallyUpdateChallengeDetails(challenge.id, {
status: 'Active'
})
this.setState({ isLaunch: true, isConfirm: challenge.id, isSaving: false })
} catch (e) {
const error = _.get(e, 'response.data.message', 'Unable to activate the challenge')
this.setState({ isSaving: false, error })
Expand Down Expand Up @@ -287,7 +290,8 @@ ChallengeCard.propTypes = {
challenge: PropTypes.object,
shouldShowCurrentPhase: PropTypes.bool,
showError: PropTypes.func,
reloadChallengeList: PropTypes.func
reloadChallengeList: PropTypes.func,
partiallyUpdateChallengeDetails: PropTypes.func.isRequired
}

export default withRouter(ChallengeCard)
15 changes: 12 additions & 3 deletions src/components/ChallengesComponent/ChallengeList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ class ChallengeList extends Component {
status,
page,
perPage,
totalChallenges } = this.props
totalChallenges,
partiallyUpdateChallengeDetails
} = this.props
if (warnMessage) {
return <Message warnMessage={warnMessage} />
}
Expand Down Expand Up @@ -206,7 +208,13 @@ class ChallengeList extends Component {
map(challenges, (c) => {
return (
<li className={styles.challengeItem} key={`challenge-card-${c.id}`}>
<ChallengeCard shouldShowCurrentPhase={selectedTab === 0} challenge={c} showError={this.showError} reloadChallengeList={this.reloadChallengeList} />
<ChallengeCard
shouldShowCurrentPhase={selectedTab === 0}
challenge={c}
showError={this.showError}
reloadChallengeList={this.reloadChallengeList}
partiallyUpdateChallengeDetails={partiallyUpdateChallengeDetails}
/>
</li>
)
})
Expand Down Expand Up @@ -247,7 +255,8 @@ ChallengeList.propTypes = {
loadChallengesByPage: PropTypes.func.isRequired,
page: PropTypes.number.isRequired,
perPage: PropTypes.number.isRequired,
totalChallenges: PropTypes.number.isRequired
totalChallenges: PropTypes.number.isRequired,
partiallyUpdateChallengeDetails: PropTypes.func.isRequired
}

export default ChallengeList
7 changes: 5 additions & 2 deletions src/components/ChallengesComponent/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ const ChallengesComponent = ({
activeProjectId,
page,
perPage,
totalChallenges
totalChallenges,
partiallyUpdateChallengeDetails
}) => {
return (
<Sticky top={10}>
Expand Down Expand Up @@ -84,6 +85,7 @@ const ChallengesComponent = ({
page={page}
perPage={perPage}
totalChallenges={totalChallenges}
partiallyUpdateChallengeDetails={partiallyUpdateChallengeDetails}
/>
)}
</div>
Expand All @@ -106,7 +108,8 @@ ChallengesComponent.propTypes = {
loadChallengesByPage: PropTypes.func.isRequired,
page: PropTypes.number.isRequired,
perPage: PropTypes.number.isRequired,
totalChallenges: PropTypes.number.isRequired
totalChallenges: PropTypes.number.isRequired,
partiallyUpdateChallengeDetails: PropTypes.func.isRequired
}

ChallengesComponent.defaultProps = {
Expand Down
8 changes: 7 additions & 1 deletion src/config/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ export const PRIZE_SETS_TYPE = {
CHECKPOINT_PRIZES: 'checkpoint'
}

export const REVIEW_TYPES = {
INTERNAL: 'internal',
COMMUNITY: 'community'
}

// List of subtracks that should be considered as Marathon Matches
export const MARATHON_MATCH_SUBTRACKS = [
'DEVELOP_MARATHON_MATCH'
Expand Down Expand Up @@ -186,5 +191,6 @@ export const MESSAGE = {
NO_LEGACY_CHALLENGE: 'Legacy challenge is not yet created',
NO_TASK_ASSIGNEE: 'Task is not assigned yet',
TASK_CLOSE_SUCCESS: 'Task closed successfully',
CHALLENGE_LAUNCH_SUCCESS: 'Challenge activated successfully'
CHALLENGE_LAUNCH_SUCCESS: 'Challenge activated successfully',
COMMUNITY_REVIEW_DISABLED: 'Community review is NOT available for design challenges'
}
10 changes: 7 additions & 3 deletions src/containers/ChallengeEditor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,21 +153,25 @@ class ChallengeEditor extends Component {
}

async activateChallenge () {
const { partiallyUpdateChallengeDetails } = this.props
if (this.state.isLaunching) return
const { challengeDetails } = this.props
try {
this.setState({ isLaunching: true })
const response = await patchChallenge(challengeDetails.id, { status: 'Active' })
// call action to update the challenge status
const action = await partiallyUpdateChallengeDetails(challengeDetails.id, {
status: 'Active'
})
this.setState({
isLaunching: false,
showLaunchModal: false,
showSuccessModal: true,
suceessMessage: MESSAGE.CHALLENGE_LAUNCH_SUCCESS,
challengeDetails: { ...challengeDetails, status: response.status }
challengeDetails: action.challengeDetails
})
} catch (e) {
const error = _.get(e, 'response.data.message', 'Unable to activate the challenge')
this.setState({ isLaunching: false, showLaunchModal: false, launchError: error })
this.setState({ isLaunching: false, launchError: error })
}
}

Expand Down
12 changes: 8 additions & 4 deletions src/containers/Challenges/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { DebounceInput } from 'react-debounce-input'
import ChallengesComponent from '../../components/ChallengesComponent'
import ProjectCard from '../../components/ProjectCard'
import Loader from '../../components/Loader'
import { loadChallengesByPage } from '../../actions/challenges'
import { loadChallengesByPage, partiallyUpdateChallengeDetails } from '../../actions/challenges'
import { loadProject } from '../../actions/projects'
import { loadProjects, setActiveProject, resetSidebarActiveParams } from '../../actions/sidebar'
import {
Expand Down Expand Up @@ -85,7 +85,8 @@ class Challenges extends Component {
page,
perPage,
totalChallenges,
setActiveProject
setActiveProject,
partiallyUpdateChallengeDetails
} = this.props
const { searchProjectName, onlyMyProjects } = this.state
const projectInfo = _.find(projects, { id: activeProjectId }) || {}
Expand Down Expand Up @@ -145,6 +146,7 @@ class Challenges extends Component {
page={page}
perPage={perPage}
totalChallenges={totalChallenges}
partiallyUpdateChallengeDetails={partiallyUpdateChallengeDetails}
/>
}
</Fragment>
Expand All @@ -170,7 +172,8 @@ Challenges.propTypes = {
perPage: PropTypes.number.isRequired,
totalChallenges: PropTypes.number.isRequired,
loadProjects: PropTypes.func.isRequired,
setActiveProject: PropTypes.func.isRequired
setActiveProject: PropTypes.func.isRequired,
partiallyUpdateChallengeDetails: PropTypes.func.isRequired
}

const mapStateToProps = ({ challenges, sidebar, projects }) => ({
Expand All @@ -187,7 +190,8 @@ const mapDispatchToProps = {
resetSidebarActiveParams,
loadProject,
loadProjects,
setActiveProject
setActiveProject,
partiallyUpdateChallengeDetails
}

export default connect(mapStateToProps, mapDispatchToProps)(Challenges)