Skip to content

Commit ff33cc4

Browse files
author
vikasrohit
authored
Merge pull request #941 from topcoder-platform/develop
Prod update - Activate button on View page
2 parents f763b68 + 7c9e05d commit ff33cc4

File tree

5 files changed

+102
-6
lines changed

5 files changed

+102
-6
lines changed

config/constants/development.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ module.exports = {
2525
DIRECT_PROJECT_URL: `https://www.${DOMAIN}/direct`,
2626
ONLINE_REVIEW_URL: `https://software.${DOMAIN}`,
2727
DEFAULT_TERM_UUID: '64d6e249-d7a5-4591-8ff5-e872f8a051f9', // Terms & Conditions of Use at TopCoder
28-
DEFAULT_NDA_UUID: '77f558c1-56fb-427c-b974-61ea0a060ca7', // Appirio NDA v2.0
28+
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',
3131
DES_TRACK_ID: '5fa04185-041f-49a6-bfd1-fe82533cd6c8',

src/components/ChallengeEditor/ChallengeView/ChallengeView.module.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@
245245
.actionButtonsRight {
246246
right: 20px;
247247

248-
button:not(:last-child),
248+
249+
.button:not(:last-child),
249250
a:not(:last-child) {
250251
margin-right: 20px;
251252
}

src/components/ChallengeEditor/ChallengeView/index.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import PhaseInput from '../../PhaseInput'
2121
import LegacyLinks from '../../LegacyLinks'
2222
import AssignedMemberField from '../AssignedMember-Field'
2323
import { getResourceRoleByName } from '../../../util/tc'
24+
import Tooltip from '../../Tooltip'
2425

2526
const ChallengeView = ({
2627
projectDetail,
@@ -31,7 +32,8 @@ const ChallengeView = ({
3132
isLoading,
3233
challengeId,
3334
assignedMemberDetails,
34-
enableEdit }) => {
35+
enableEdit,
36+
onLaunchChallenge }) => {
3537
const selectedType = _.find(metadata.challengeTypes, { id: challenge.typeId })
3638
const challengeTrack = _.find(metadata.challengeTracks, { id: challenge.trackId })
3739

@@ -70,6 +72,20 @@ const ChallengeView = ({
7072
</div>
7173
<div className={styles.title}>View Details</div>
7274
<div className={cn(styles.actionButtons, styles.button, styles.actionButtonsRight)}>
75+
{
76+
challenge.status === 'Draft' && (
77+
<div className={styles.button}>
78+
{challenge.legacyId ? (
79+
<PrimaryButton text={'Launch'} type={'info'} onClick={onLaunchChallenge} />
80+
) : (
81+
<Tooltip content='Legacy project is not yet created'>
82+
{/* Don't disable button for real inside tooltip, otherwise mouseEnter/Leave events work not good */}
83+
<PrimaryButton text={'Launch'} type={'disabled'} />
84+
</Tooltip>
85+
)}
86+
</div>
87+
)
88+
}
7389
{ enableEdit && <PrimaryButton text={'Edit'} type={'info'} submit link={`./edit`} /> }
7490
<PrimaryButton text={'Back'} type={'info'} submit link={`..`} />
7591
</div>
@@ -218,7 +234,8 @@ ChallengeView.propTypes = {
218234
challengeId: PropTypes.string.isRequired,
219235
challengeResources: PropTypes.arrayOf(PropTypes.object),
220236
assignedMemberDetails: PropTypes.shape(),
221-
enableEdit: PropTypes.bool
237+
enableEdit: PropTypes.bool,
238+
onLaunchChallenge: PropTypes.func
222239
}
223240

224241
export default withRouter(ChallengeView)

src/containers/ChallengeEditor/ChallengeEditor.module.scss

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,25 @@
44
.errorContainer {
55
color: $red;
66
padding: 10px;
7+
}
8+
9+
.modalContainer {
10+
padding: 0;
11+
position: fixed;
12+
overflow: auto;
13+
z-index: 10000;
14+
top: 0;
15+
right: 0;
16+
bottom: 0;
17+
left: 0;
18+
box-sizing: border-box;
19+
width: auto;
20+
max-width: none;
21+
transform: none;
22+
background: transparent;
23+
color: $text-color;
24+
opacity: 1;
25+
display: flex;
26+
justify-content: center;
27+
align-items: center;
728
}

src/containers/ChallengeEditor/index.js

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,24 @@ import {
3030

3131
import { connect } from 'react-redux'
3232
import { SUBMITTER_ROLE_UUID } from '../../config/constants'
33+
import { patchChallenge } from '../../services/challenges'
34+
import ConfirmationModal from '../../components/Modal/ConfirmationModal'
35+
import AlertModal from '../../components/Modal/AlertModal'
36+
37+
const theme = {
38+
container: styles.modalContainer
39+
}
3340

3441
class ChallengeEditor extends Component {
3542
constructor (props) {
3643
super(props)
3744
const mountedWithCreatePage = props.match.path.endsWith('/new')
38-
this.state = { mountedWithCreatePage }
45+
this.state = { mountedWithCreatePage, isLaunching: false, showSuccessModal: false, showLaunchModal: false }
46+
47+
this.onLaunchChallenge = this.onLaunchChallenge.bind(this)
48+
this.activateChallenge = this.activateChallenge.bind(this)
49+
this.closeLaunchModal = this.closeLaunchModal.bind(this)
50+
this.closeSuccessModal = this.closeSuccessModal.bind(this)
3951
}
4052
componentDidMount () {
4153
const {
@@ -108,6 +120,31 @@ class ChallengeEditor extends Component {
108120
return _.some(userResourceRoles, urr => urr.fullWriteAccess && urr.isActive)
109121
}
110122

123+
onLaunchChallenge () {
124+
this.setState({ showLaunchModal: true })
125+
}
126+
127+
closeLaunchModal () {
128+
this.setState({ showLaunchModal: false })
129+
}
130+
131+
closeSuccessModal () {
132+
this.setState({ showSuccessModal: false })
133+
}
134+
135+
async activateChallenge () {
136+
if (this.state.isLaunching) return
137+
const { challengeDetails } = this.props
138+
try {
139+
this.setState({ isLaunching: true })
140+
await patchChallenge(challengeDetails.id, { status: 'Active' })
141+
this.setState({ isLaunching: false, showLaunchModal: false, showSuccessModal: true })
142+
} catch (e) {
143+
const error = _.get(e, 'response.data.message', 'Unable to activate the challenge')
144+
this.setState({ isLaunching: false, showLaunchModal: false, launchError: error })
145+
}
146+
}
147+
111148
render () {
112149
const {
113150
match,
@@ -128,7 +165,7 @@ class ChallengeEditor extends Component {
128165
replaceResourceInRole
129166
// members
130167
} = this.props
131-
const { mountedWithCreatePage } = this.state
168+
const { mountedWithCreatePage, isLaunching, showLaunchModal, showSuccessModal } = this.state
132169
if (isProjectLoading || isLoading) return <Loader />
133170
const challengeId = _.get(match.params, 'challengeId', null)
134171
if (challengeId && (!challengeDetails || !challengeDetails.id)) {
@@ -144,7 +181,26 @@ class ChallengeEditor extends Component {
144181
}
145182
const enableEdit = this.isEditable()
146183
const isCreatePage = this.props.match.path.endsWith('/new')
184+
185+
const activateModal = <ConfirmationModal
186+
title='Confirm Launch'
187+
message={`Do you want to launch "${challengeDetails.name}"?`}
188+
theme={theme}
189+
isProcessing={isLaunching}
190+
errorMessage={this.state.launchError}
191+
onCancel={this.closeLaunchModal}
192+
onConfirm={this.activateChallenge}
193+
/>
194+
const successModal = <AlertModal
195+
title='Success'
196+
message='Challenge is activated successfully'
197+
theme={theme}
198+
closeText='Ok'
199+
onClose={this.closeSuccessModal}
200+
/>
147201
return <div>
202+
{ showLaunchModal && activateModal }
203+
{ showSuccessModal && successModal }
148204
<Route
149205
exact
150206
path={this.props.match.path}
@@ -212,6 +268,7 @@ class ChallengeEditor extends Component {
212268
challengeId={challengeId}
213269
assignedMemberDetails={assignedMemberDetails}
214270
enableEdit={enableEdit}
271+
onLaunchChallenge={this.onLaunchChallenge}
215272
/>
216273
))
217274
} />

0 commit comments

Comments
 (0)