Skip to content

Commit 937aac1

Browse files
author
vikasrohit
authored
Merge pull request #997 from topcoder-platform/develop
Prod Update - Disabled review type option for Design challenges
2 parents d294f53 + 1e1a06d commit 937aac1

File tree

10 files changed

+86
-39
lines changed

10 files changed

+86
-39
lines changed

config/constants/development.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module.exports = {
2424
CONNECT_APP_URL: `https://connect.${DOMAIN}`,
2525
DIRECT_PROJECT_URL: `https://www.${DOMAIN}/direct`,
2626
ONLINE_REVIEW_URL: `https://software.${DOMAIN}`,
27-
DEFAULT_TERM_UUID: '64d6e249-d7a5-4591-8ff5-e872f8a051f9', // Terms & Conditions of Use at TopCoder
27+
DEFAULT_TERM_UUID: '317cd8f9-d66c-4f2a-8774-63c612d99cd4', // Terms & Conditions of Use at TopCoder
2828
DEFAULT_NDA_UUID: 'e5811a7b-43d1-407a-a064-69e5015b4900', // NDA v3.0
2929
SUBMITTER_ROLE_UUID: '732339e7-8e30-49d7-9198-cccf9451e221',
3030
DEV_TRACK_ID: '9b6fc876-f4d9-4ccb-9dfd-419247628825',

src/actions/challenges.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,11 @@ export function partiallyUpdateChallengeDetails (challengeId, partialChallengeDe
258258
type: UPDATE_CHALLENGE_DETAILS_SUCCESS,
259259
challengeDetails: challenge
260260
})
261-
}).catch(() => {
261+
}).catch((error) => {
262262
dispatch({
263263
type: UPDATE_CHALLENGE_DETAILS_FAILURE
264264
})
265+
throw error
265266
})
266267
}
267268
}

src/components/ChallengeEditor/ReviewType-Field/index.js

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,31 @@ import PropTypes from 'prop-types'
33
import Select from '../../Select'
44
import cn from 'classnames'
55
import styles from './ReviewType-Field.module.scss'
6+
import Tooltip from '../../Tooltip'
7+
import { DES_TRACK_ID, REVIEW_TYPES, MESSAGE } from '../../../config/constants'
68

79
const ReviewTypeField = ({ reviewers, challenge, onUpdateOthers, onUpdateSelect }) => {
8-
const reviewType = challenge.reviewType ? challenge.reviewType.toLowerCase() : 'community'
9-
const isCommunity = reviewType === 'community'
10-
const isInternal = reviewType === 'internal'
10+
const isDesignChallenge = challenge.trackId === DES_TRACK_ID
11+
const defaultReviewType = isDesignChallenge ? REVIEW_TYPES.INTERNAL : REVIEW_TYPES.COMMUNITY
12+
const reviewType = challenge.reviewType ? challenge.reviewType.toLowerCase() : defaultReviewType
13+
const isCommunity = reviewType === REVIEW_TYPES.COMMUNITY
14+
const isInternal = reviewType === REVIEW_TYPES.INTERNAL
15+
const communityOption = (disabled) => (<div className={styles.tcRadioButton}>
16+
<input
17+
name='community'
18+
type='radio'
19+
id='community'
20+
checked={isCommunity}
21+
disabled={disabled}
22+
onChange={(e) => e.target.checked && onUpdateOthers({ field: 'reviewType', value: 'community' })}
23+
/>
24+
<label htmlFor='community'>
25+
<div className={styles.radioButtonLabel}>
26+
Community
27+
</div>
28+
<input type='hidden' />
29+
</label>
30+
</div>)
1131
return (
1232
<div>
1333
<div className={styles.row}>
@@ -17,21 +37,14 @@ const ReviewTypeField = ({ reviewers, challenge, onUpdateOthers, onUpdateSelect
1737
<div className={cn(styles.field, styles.col2)}>
1838
<div className={styles.subGroup}>
1939
<div className={styles.subRow}>
20-
<div className={styles.tcRadioButton}>
21-
<input
22-
name='community'
23-
type='radio'
24-
id='community'
25-
checked={isCommunity}
26-
onChange={(e) => e.target.checked && onUpdateOthers({ field: 'reviewType', value: 'community' })}
27-
/>
28-
<label htmlFor='community'>
29-
<div className={styles.radioButtonLabel}>
30-
Community
31-
</div>
32-
<input type='hidden' />
33-
</label>
34-
</div>
40+
{ isDesignChallenge &&
41+
<Tooltip content={MESSAGE.COMMUNITY_REVIEW_DISABLED}>
42+
{ communityOption(true) }
43+
</Tooltip>
44+
}
45+
{ !isDesignChallenge &&
46+
communityOption()
47+
}
3548
</div>
3649
<div className={styles.subRow}>
3750
<div className={styles.tcRadioButton}>

src/components/ChallengeEditor/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ import {
1818
SUBMITTER_ROLE_UUID,
1919
CREATE_FORUM_TYPE_IDS,
2020
MESSAGE,
21-
COMMUNITY_APP_URL
21+
COMMUNITY_APP_URL,
22+
DES_TRACK_ID,
23+
REVIEW_TYPES
2224
} from '../../config/constants'
2325
import { PrimaryButton, OutlineButton } from '../Buttons'
2426
import TrackField from './Track-Field'
@@ -784,6 +786,7 @@ class ChallengeEditor extends Component {
784786
const { metadata, createChallenge } = this.props
785787
const { name, trackId, typeId } = this.state.challenge
786788
const { timelineTemplates } = metadata
789+
const isDesignChallenge = trackId === DES_TRACK_ID
787790

788791
// indicate that creating process has started
789792
this.setState({ isSaving: true })
@@ -802,7 +805,7 @@ class ChallengeEditor extends Component {
802805
trackId,
803806
startDate: moment().add(1, 'days').format(),
804807
legacy: {
805-
reviewType: 'community'
808+
reviewType: isDesignChallenge ? REVIEW_TYPES.INTERNAL : REVIEW_TYPES.COMMUNITY
806809
},
807810
descriptionFormat: 'markdown',
808811
timelineTemplateId: defaultTemplate.id,

src/components/ChallengesComponent/ChallengeCard/index.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import ChallengeTag from '../ChallengeTag'
1515
import styles from './ChallengeCard.module.scss'
1616
import { getFormattedDuration, formatDate } from '../../../util/date'
1717
import { CHALLENGE_STATUS, COMMUNITY_APP_URL, DIRECT_PROJECT_URL, MESSAGE, ONLINE_REVIEW_URL } from '../../../config/constants'
18-
import { patchChallenge } from '../../../services/challenges'
1918
import ConfirmationModal from '../../Modal/ConfirmationModal'
2019
import AlertModal from '../../Modal/AlertModal'
2120
import Tooltip from '../../Tooltip'
@@ -201,12 +200,16 @@ class ChallengeCard extends React.Component {
201200
}
202201

203202
async onLaunchChallenge () {
203+
const { partiallyUpdateChallengeDetails } = this.props
204204
if (this.state.isSaving) return
205205
const { challenge } = this.props
206206
try {
207207
this.setState({ isSaving: true })
208-
const response = await patchChallenge(challenge.id, { status: 'Active' })
209-
this.setState({ isLaunch: true, isConfirm: response.id, isSaving: false })
208+
// call action to update the challenge with a new status
209+
await partiallyUpdateChallengeDetails(challenge.id, {
210+
status: 'Active'
211+
})
212+
this.setState({ isLaunch: true, isConfirm: challenge.id, isSaving: false })
210213
} catch (e) {
211214
const error = _.get(e, 'response.data.message', 'Unable to activate the challenge')
212215
this.setState({ isSaving: false, error })
@@ -287,7 +290,8 @@ ChallengeCard.propTypes = {
287290
challenge: PropTypes.object,
288291
shouldShowCurrentPhase: PropTypes.bool,
289292
showError: PropTypes.func,
290-
reloadChallengeList: PropTypes.func
293+
reloadChallengeList: PropTypes.func,
294+
partiallyUpdateChallengeDetails: PropTypes.func.isRequired
291295
}
292296

293297
export default withRouter(ChallengeCard)

src/components/ChallengesComponent/ChallengeList/index.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ class ChallengeList extends Component {
101101
status,
102102
page,
103103
perPage,
104-
totalChallenges } = this.props
104+
totalChallenges,
105+
partiallyUpdateChallengeDetails
106+
} = this.props
105107
if (warnMessage) {
106108
return <Message warnMessage={warnMessage} />
107109
}
@@ -206,7 +208,13 @@ class ChallengeList extends Component {
206208
map(challenges, (c) => {
207209
return (
208210
<li className={styles.challengeItem} key={`challenge-card-${c.id}`}>
209-
<ChallengeCard shouldShowCurrentPhase={selectedTab === 0} challenge={c} showError={this.showError} reloadChallengeList={this.reloadChallengeList} />
211+
<ChallengeCard
212+
shouldShowCurrentPhase={selectedTab === 0}
213+
challenge={c}
214+
showError={this.showError}
215+
reloadChallengeList={this.reloadChallengeList}
216+
partiallyUpdateChallengeDetails={partiallyUpdateChallengeDetails}
217+
/>
210218
</li>
211219
)
212220
})
@@ -247,7 +255,8 @@ ChallengeList.propTypes = {
247255
loadChallengesByPage: PropTypes.func.isRequired,
248256
page: PropTypes.number.isRequired,
249257
perPage: PropTypes.number.isRequired,
250-
totalChallenges: PropTypes.number.isRequired
258+
totalChallenges: PropTypes.number.isRequired,
259+
partiallyUpdateChallengeDetails: PropTypes.func.isRequired
251260
}
252261

253262
export default ChallengeList

src/components/ChallengesComponent/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ const ChallengesComponent = ({
2525
activeProjectId,
2626
page,
2727
perPage,
28-
totalChallenges
28+
totalChallenges,
29+
partiallyUpdateChallengeDetails
2930
}) => {
3031
return (
3132
<Sticky top={10}>
@@ -84,6 +85,7 @@ const ChallengesComponent = ({
8485
page={page}
8586
perPage={perPage}
8687
totalChallenges={totalChallenges}
88+
partiallyUpdateChallengeDetails={partiallyUpdateChallengeDetails}
8789
/>
8890
)}
8991
</div>
@@ -106,7 +108,8 @@ ChallengesComponent.propTypes = {
106108
loadChallengesByPage: PropTypes.func.isRequired,
107109
page: PropTypes.number.isRequired,
108110
perPage: PropTypes.number.isRequired,
109-
totalChallenges: PropTypes.number.isRequired
111+
totalChallenges: PropTypes.number.isRequired,
112+
partiallyUpdateChallengeDetails: PropTypes.func.isRequired
110113
}
111114

112115
ChallengesComponent.defaultProps = {

src/config/constants.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ export const PRIZE_SETS_TYPE = {
110110
CHECKPOINT_PRIZES: 'checkpoint'
111111
}
112112

113+
export const REVIEW_TYPES = {
114+
INTERNAL: 'internal',
115+
COMMUNITY: 'community'
116+
}
117+
113118
// List of subtracks that should be considered as Marathon Matches
114119
export const MARATHON_MATCH_SUBTRACKS = [
115120
'DEVELOP_MARATHON_MATCH'
@@ -186,5 +191,6 @@ export const MESSAGE = {
186191
NO_LEGACY_CHALLENGE: 'Legacy challenge is not yet created',
187192
NO_TASK_ASSIGNEE: 'Task is not assigned yet',
188193
TASK_CLOSE_SUCCESS: 'Task closed successfully',
189-
CHALLENGE_LAUNCH_SUCCESS: 'Challenge activated successfully'
194+
CHALLENGE_LAUNCH_SUCCESS: 'Challenge activated successfully',
195+
COMMUNITY_REVIEW_DISABLED: 'Community review is NOT available for design challenges'
190196
}

src/containers/ChallengeEditor/index.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,21 +153,25 @@ class ChallengeEditor extends Component {
153153
}
154154

155155
async activateChallenge () {
156+
const { partiallyUpdateChallengeDetails } = this.props
156157
if (this.state.isLaunching) return
157158
const { challengeDetails } = this.props
158159
try {
159160
this.setState({ isLaunching: true })
160-
const response = await patchChallenge(challengeDetails.id, { status: 'Active' })
161+
// call action to update the challenge status
162+
const action = await partiallyUpdateChallengeDetails(challengeDetails.id, {
163+
status: 'Active'
164+
})
161165
this.setState({
162166
isLaunching: false,
163167
showLaunchModal: false,
164168
showSuccessModal: true,
165169
suceessMessage: MESSAGE.CHALLENGE_LAUNCH_SUCCESS,
166-
challengeDetails: { ...challengeDetails, status: response.status }
170+
challengeDetails: action.challengeDetails
167171
})
168172
} catch (e) {
169173
const error = _.get(e, 'response.data.message', 'Unable to activate the challenge')
170-
this.setState({ isLaunching: false, showLaunchModal: false, launchError: error })
174+
this.setState({ isLaunching: false, launchError: error })
171175
}
172176
}
173177

src/containers/Challenges/index.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { DebounceInput } from 'react-debounce-input'
1010
import ChallengesComponent from '../../components/ChallengesComponent'
1111
import ProjectCard from '../../components/ProjectCard'
1212
import Loader from '../../components/Loader'
13-
import { loadChallengesByPage } from '../../actions/challenges'
13+
import { loadChallengesByPage, partiallyUpdateChallengeDetails } from '../../actions/challenges'
1414
import { loadProject } from '../../actions/projects'
1515
import { loadProjects, setActiveProject, resetSidebarActiveParams } from '../../actions/sidebar'
1616
import {
@@ -85,7 +85,8 @@ class Challenges extends Component {
8585
page,
8686
perPage,
8787
totalChallenges,
88-
setActiveProject
88+
setActiveProject,
89+
partiallyUpdateChallengeDetails
8990
} = this.props
9091
const { searchProjectName, onlyMyProjects } = this.state
9192
const projectInfo = _.find(projects, { id: activeProjectId }) || {}
@@ -145,6 +146,7 @@ class Challenges extends Component {
145146
page={page}
146147
perPage={perPage}
147148
totalChallenges={totalChallenges}
149+
partiallyUpdateChallengeDetails={partiallyUpdateChallengeDetails}
148150
/>
149151
}
150152
</Fragment>
@@ -170,7 +172,8 @@ Challenges.propTypes = {
170172
perPage: PropTypes.number.isRequired,
171173
totalChallenges: PropTypes.number.isRequired,
172174
loadProjects: PropTypes.func.isRequired,
173-
setActiveProject: PropTypes.func.isRequired
175+
setActiveProject: PropTypes.func.isRequired,
176+
partiallyUpdateChallengeDetails: PropTypes.func.isRequired
174177
}
175178

176179
const mapStateToProps = ({ challenges, sidebar, projects }) => ({
@@ -187,7 +190,8 @@ const mapDispatchToProps = {
187190
resetSidebarActiveParams,
188191
loadProject,
189192
loadProjects,
190-
setActiveProject
193+
setActiveProject,
194+
partiallyUpdateChallengeDetails
191195
}
192196

193197
export default connect(mapStateToProps, mapDispatchToProps)(Challenges)

0 commit comments

Comments
 (0)