Skip to content

Commit 89b7109

Browse files
author
vikasrohit
authored
Merge pull request #1159 from topcoder-platform/develop
Prod Release - 0.9.0
2 parents 0df6294 + 51c2948 commit 89b7109

File tree

13 files changed

+111
-15
lines changed

13 files changed

+111
-15
lines changed

src/actions/projects.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import {
2+
LOAD_PROJECT_BILLING_ACCOUNT,
23
LOAD_CHALLENGE_MEMBERS_SUCCESS,
34
LOAD_PROJECT_DETAILS
45
} from '../config/constants'
5-
import { fetchProjectById } from '../services/projects'
6+
import { fetchProjectById, fetchBillingAccount } from '../services/projects'
67

78
/**
89
* Loads project details
@@ -19,6 +20,13 @@ export function loadProject (projectId) {
1920
members
2021
})
2122
}
23+
24+
// Loads billing account
25+
dispatch({
26+
type: LOAD_PROJECT_BILLING_ACCOUNT,
27+
payload: fetchBillingAccount(projectId)
28+
})
29+
2230
return project
2331
})
2432
})

src/components/ChallengeEditor/ChallengeEditor.module.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,11 @@
414414
}
415415
}
416416

417+
.expiredMessage {
418+
margin-left: 20px;
419+
color: $red;
420+
}
421+
417422
.bottomContainer {
418423
display: inline-flex;
419424
justify-content: space-between;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@
255255
}
256256
}
257257

258+
.expiredMessage {
259+
margin-left: 20px;
260+
color: $red;
261+
}
262+
258263
.button {
259264
height: 40px;
260265
span {

src/components/ChallengeEditor/ChallengeView/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const ChallengeView = ({
3131
projectDetail,
3232
challenge,
3333
attachments,
34+
isBillingAccountExpired,
3435
metadata,
3536
challengeResources,
3637
token,
@@ -197,6 +198,7 @@ const ChallengeView = ({
197198
<span className={styles.fieldTitle}>Billing Account Id:</span>
198199
{projectDetail.billingAccountId}
199200
</span>
201+
{isBillingAccountExpired && <span className={styles.expiredMessage}>Expired</span>}
200202
</div>
201203
</div>
202204
{isBetaMode() && (
@@ -278,6 +280,7 @@ ChallengeView.propTypes = {
278280
}).isRequired,
279281
projectDetail: PropTypes.object,
280282
challenge: PropTypes.object,
283+
isBillingAccountExpired: PropTypes.bool,
281284
attachments: PropTypes.array,
282285
metadata: PropTypes.object,
283286
token: PropTypes.string,

src/components/ChallengeEditor/index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,11 @@ class ChallengeEditor extends Component {
655655
toggleLaunch (e) {
656656
e.preventDefault()
657657
if (this.validateChallenge()) {
658-
this.setState({ isLaunch: true })
658+
if (!this.props.isBillingAccountExpired) {
659+
this.setState({ isLaunch: true })
660+
} else {
661+
this.setState({ isLaunch: true, error: 'Unable to activate challenge as Billing Account is not active.' })
662+
}
659663
}
660664
}
661665

@@ -1181,6 +1185,7 @@ class ChallengeEditor extends Component {
11811185
} = this.state
11821186
const {
11831187
isNew,
1188+
isBillingAccountExpired,
11841189
isLoading,
11851190
metadata,
11861191
uploadAttachments,
@@ -1278,6 +1283,7 @@ class ChallengeEditor extends Component {
12781283
errorMessage={this.state.error}
12791284
onCancel={this.resetModal}
12801285
onConfirm={this.onActiveChallenge}
1286+
disableConfirmButton={isBillingAccountExpired}
12811287
/>
12821288
)
12831289
}
@@ -1483,6 +1489,7 @@ class ChallengeEditor extends Component {
14831489
<span className={styles.fieldTitle}>Billing Account Id:</span>
14841490
{projectDetail.billingAccountId}
14851491
</span>
1492+
{isBillingAccountExpired && <span className={styles.expiredMessage}>Expired</span>}
14861493
</div>
14871494
</div>
14881495
{isBetaMode() && (
@@ -1606,6 +1613,7 @@ ChallengeEditor.propTypes = {
16061613
projectDetail: PropTypes.object,
16071614
challengeResources: PropTypes.arrayOf(PropTypes.object),
16081615
isNew: PropTypes.bool.isRequired,
1616+
isBillingAccountExpired: PropTypes.bool,
16091617
projectId: PropTypes.string.isRequired,
16101618
challengeId: PropTypes.string,
16111619
metadata: PropTypes.object.isRequired,

src/components/ChallengesComponent/ChallengeCard/index.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,11 @@ class ChallengeCard extends React.Component {
209209

210210
onUpdateLaunch () {
211211
if (!this.state.isLaunch) {
212-
this.setState({ isLaunch: true })
212+
if (!this.props.isBillingAccountExpired) {
213+
this.setState({ isLaunch: true })
214+
} else {
215+
this.setState({ isLaunch: true, error: 'Unable to activate challenge as Billing Account is not active.' })
216+
}
213217
}
214218
}
215219

@@ -272,7 +276,7 @@ class ChallengeCard extends React.Component {
272276

273277
render () {
274278
const { isLaunch, isConfirm, isSaving, isDeleteLaunch, isCheckChalengePermission, hasEditChallengePermission } = this.state
275-
const { challenge, shouldShowCurrentPhase, reloadChallengeList } = this.props
279+
const { challenge, shouldShowCurrentPhase, reloadChallengeList, isBillingAccountExpired } = this.props
276280
const { phaseMessage, endTime } = getPhaseInfo(challenge)
277281
const deleteMessage = isCheckChalengePermission
278282
? 'Checking permissions...'
@@ -305,6 +309,7 @@ class ChallengeCard extends React.Component {
305309
errorMessage={this.state.error}
306310
onCancel={this.resetModal}
307311
onConfirm={this.onLaunchChallenge}
312+
disableConfirmButton={isBillingAccountExpired}
308313
/>
309314
)
310315
}
@@ -364,7 +369,8 @@ ChallengeCard.propTypes = {
364369
shouldShowCurrentPhase: PropTypes.bool,
365370
reloadChallengeList: PropTypes.func,
366371
partiallyUpdateChallengeDetails: PropTypes.func.isRequired,
367-
deleteChallenge: PropTypes.func.isRequired
372+
deleteChallenge: PropTypes.func.isRequired,
373+
isBillingAccountExpired: PropTypes.bool
368374
}
369375

370376
export default withRouter(ChallengeCard)

src/components/ChallengesComponent/ChallengeList/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ class ChallengeList extends Component {
103103
perPage,
104104
totalChallenges,
105105
partiallyUpdateChallengeDetails,
106-
deleteChallenge
106+
deleteChallenge,
107+
isBillingAccountExpired
107108
} = this.props
108109
if (warnMessage) {
109110
return <Message warnMessage={warnMessage} />
@@ -215,6 +216,7 @@ class ChallengeList extends Component {
215216
reloadChallengeList={this.reloadChallengeList}
216217
partiallyUpdateChallengeDetails={partiallyUpdateChallengeDetails}
217218
deleteChallenge={deleteChallenge}
219+
isBillingAccountExpired={isBillingAccountExpired}
218220
/>
219221
</li>
220222
)
@@ -258,7 +260,8 @@ ChallengeList.propTypes = {
258260
perPage: PropTypes.number.isRequired,
259261
totalChallenges: PropTypes.number.isRequired,
260262
partiallyUpdateChallengeDetails: PropTypes.func.isRequired,
261-
deleteChallenge: PropTypes.func.isRequired
263+
deleteChallenge: PropTypes.func.isRequired,
264+
isBillingAccountExpired: PropTypes.bool
262265
}
263266

264267
export default ChallengeList

src/components/ChallengesComponent/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ const ChallengesComponent = ({
2727
perPage,
2828
totalChallenges,
2929
partiallyUpdateChallengeDetails,
30-
deleteChallenge
30+
deleteChallenge,
31+
isBillingAccountExpired
3132
}) => {
3233
return (
3334
<Sticky top={10}>
@@ -88,6 +89,7 @@ const ChallengesComponent = ({
8889
totalChallenges={totalChallenges}
8990
partiallyUpdateChallengeDetails={partiallyUpdateChallengeDetails}
9091
deleteChallenge={deleteChallenge}
92+
isBillingAccountExpired={isBillingAccountExpired}
9193
/>
9294
)}
9395
</div>
@@ -112,7 +114,8 @@ ChallengesComponent.propTypes = {
112114
perPage: PropTypes.number.isRequired,
113115
totalChallenges: PropTypes.number.isRequired,
114116
partiallyUpdateChallengeDetails: PropTypes.func.isRequired,
115-
deleteChallenge: PropTypes.func.isRequired
117+
deleteChallenge: PropTypes.func.isRequired,
118+
isBillingAccountExpired: PropTypes.bool
116119
}
117120

118121
ChallengesComponent.defaultProps = {

src/config/constants.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ export const LOAD_PROJECTS_SUCCESS = 'LOAD_PROJECTS_SUCCESS'
4444
export const LOAD_PROJECTS_PENDING = 'LOAD_PROJECTS_PENDING'
4545
export const LOAD_PROJECTS_FAILURE = 'LOAD_PROJECTS_FAILURE'
4646

47+
// project billingAccount
48+
export const LOAD_PROJECT_BILLING_ACCOUNT = 'LOAD_PROJECT_BILLING_ACCOUNT'
49+
export const LOAD_PROJECT_BILLING_ACCOUNT_PENDING = 'LOAD_PROJECT_BILLING_ACCOUNT_PENDING'
50+
export const LOAD_PROJECT_BILLING_ACCOUNT_FAILURE = 'LOAD_PROJECT_BILLING_ACCOUNT_FAILURE'
51+
export const LOAD_PROJECT_BILLING_ACCOUNT_SUCCESS = 'LOAD_PROJECT_BILLING_ACCOUNT_SUCCESS'
52+
4753
export const SET_ACTIVE_PROJECT = 'SET_ACTIVE_PROJECT'
4854

4955
export const LOAD_USER_SUCCESS = 'LOAD_USER_SUCCESS'

src/containers/ChallengeEditor/index.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,11 @@ class ChallengeEditor extends Component {
148148
}
149149

150150
onLaunchChallenge () {
151-
this.setState({ showLaunchModal: true })
151+
if (!this.props.isBillingAccountExpired) {
152+
this.setState({ showLaunchModal: true })
153+
} else {
154+
this.setState({ showLaunchModal: true, launchError: 'Unable to activate challenge as Billing Account is not active.' })
155+
}
152156
}
153157

154158
onCloseTask () {
@@ -236,6 +240,7 @@ class ChallengeEditor extends Component {
236240
const {
237241
match,
238242
isLoading,
243+
isBillingAccountExpired,
239244
isProjectLoading,
240245
// challengeDetails,
241246
challengeResources,
@@ -288,6 +293,7 @@ class ChallengeEditor extends Component {
288293
errorMessage={this.state.launchError}
289294
onCancel={this.closeLaunchModal}
290295
onConfirm={this.activateChallenge}
296+
disableConfirmButton={isBillingAccountExpired}
291297
/>
292298
const closeTaskModal = <ConfirmationModal
293299
title='Confirm Close Task'
@@ -316,6 +322,7 @@ class ChallengeEditor extends Component {
316322
<ChallengeEditorComponent
317323
isLoading={isLoading}
318324
challengeDetails={challengeDetails}
325+
isBillingAccountExpired={isBillingAccountExpired}
319326
challengeResources={challengeResources}
320327
metadata={metadata}
321328
projectId={_.get(match.params, 'projectId', null)}
@@ -343,6 +350,7 @@ class ChallengeEditor extends Component {
343350
render={({ match }) => ((
344351
<ChallengeEditorComponent
345352
isLoading={isLoading}
353+
isBillingAccountExpired={isBillingAccountExpired}
346354
challengeDetails={challengeDetails}
347355
challengeResources={challengeResources}
348356
metadata={metadata}
@@ -371,6 +379,7 @@ class ChallengeEditor extends Component {
371379
render={({ match }) => ((
372380
<ChallengeViewComponent
373381
isLoading={isLoading}
382+
isBillingAccountExpired={isBillingAccountExpired}
374383
metadata={metadata}
375384
projectDetail={projectDetail}
376385
challenge={challengeDetails}
@@ -418,6 +427,7 @@ ChallengeEditor.propTypes = {
418427
challengeTypes: PropTypes.array
419428
}),
420429
isLoading: PropTypes.bool,
430+
isBillingAccountExpired: PropTypes.bool,
421431
createAttachments: PropTypes.func,
422432
attachments: PropTypes.arrayOf(PropTypes.shape()),
423433
token: PropTypes.string,
@@ -441,6 +451,7 @@ const mapStateToProps = ({ projects, challenges: { challengeDetails, challengeRe
441451
challengeResources,
442452
metadata,
443453
isLoading,
454+
isBillingAccountExpired: projects.isBillingAccountExpired,
444455
isProjectLoading: projects.isLoading,
445456
attachments,
446457
token,

src/containers/Challenges/index.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ class Challenges extends Component {
8787
totalChallenges,
8888
setActiveProject,
8989
partiallyUpdateChallengeDetails,
90-
deleteChallenge
90+
deleteChallenge,
91+
isBillingAccountExpired
9192
} = this.props
9293
const { searchProjectName, onlyMyProjects } = this.state
9394
const projectInfo = _.find(projects, { id: activeProjectId }) || {}
@@ -149,6 +150,7 @@ class Challenges extends Component {
149150
totalChallenges={totalChallenges}
150151
partiallyUpdateChallengeDetails={partiallyUpdateChallengeDetails}
151152
deleteChallenge={deleteChallenge}
153+
isBillingAccountExpired={isBillingAccountExpired}
152154
/>
153155
}
154156
</Fragment>
@@ -176,16 +178,17 @@ Challenges.propTypes = {
176178
loadProjects: PropTypes.func.isRequired,
177179
setActiveProject: PropTypes.func.isRequired,
178180
partiallyUpdateChallengeDetails: PropTypes.func.isRequired,
179-
deleteChallenge: PropTypes.func.isRequired
181+
deleteChallenge: PropTypes.func.isRequired,
182+
isBillingAccountExpired: PropTypes.bool
180183
}
181184

182185
const mapStateToProps = ({ challenges, sidebar, projects }) => ({
183186
..._.omit(challenges, ['projectId']),
184187
challengeProjectId: challenges.projectId,
185188
activeProjectId: sidebar.activeProjectId,
186189
projects: sidebar.projects,
187-
projectDetail: projects.projectDetail
188-
190+
projectDetail: projects.projectDetail,
191+
isBillingAccountExpired: projects.isBillingAccountExpired
189192
})
190193

191194
const mapDispatchToProps = {

src/reducers/projects.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@
33
*/
44
import _ from 'lodash'
55
import {
6+
LOAD_PROJECT_BILLING_ACCOUNT_PENDING,
7+
LOAD_PROJECT_BILLING_ACCOUNT_SUCCESS,
8+
LOAD_PROJECT_BILLING_ACCOUNT_FAILURE,
69
LOAD_PROJECT_DETAILS_FAILURE,
710
LOAD_PROJECT_DETAILS_PENDING,
811
LOAD_PROJECT_DETAILS_SUCCESS
912
} from '../config/constants'
1013

1114
const initialState = {
1215
isLoading: false,
13-
projectDetail: {}
16+
projectDetail: {},
17+
isBillingAccountExpired: false,
18+
isBillingAccountLoading: false
1419
}
1520

1621
export default function (state = initialState, action) {
@@ -28,6 +33,24 @@ export default function (state = initialState, action) {
2833
hasProjectAccess: true,
2934
isLoading: false
3035
}
36+
case LOAD_PROJECT_BILLING_ACCOUNT_PENDING:
37+
return {
38+
...state,
39+
isBillingAccountLoading: true,
40+
isBillingAccountExpired: false
41+
}
42+
case LOAD_PROJECT_BILLING_ACCOUNT_SUCCESS:
43+
return {
44+
...state,
45+
isBillingAccountLoading: false,
46+
isBillingAccountExpired: !action.payload.active
47+
}
48+
case LOAD_PROJECT_BILLING_ACCOUNT_FAILURE:
49+
return {
50+
...state,
51+
isBillingAccountLoading: false,
52+
isBillingAccountExpired: false
53+
}
3154
default:
3255
return state
3356
}

src/services/projects.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ import { axiosInstance } from './axiosWithAuth'
33
import * as queryString from 'query-string'
44
const { PROJECT_API_URL } = process.env
55

6+
/**
7+
* Get billing account based on project id
8+
*
9+
* @param {String} projectId Id of the project
10+
*
11+
* @returns {Promise<Object>} Billing account data
12+
*/
13+
export async function fetchBillingAccount (projectId) {
14+
const response = await axiosInstance.get(`${PROJECT_API_URL}/${projectId}/billingAccount`)
15+
return _.get(response, 'data')
16+
}
17+
618
/**
719
* Api request for fetching member's projects
820
* @returns {Promise<*>}

0 commit comments

Comments
 (0)