Skip to content

Commit 4809a95

Browse files
authored
Merge pull request topcoder-platform#247 from chqy24/issue_200
fixes topcoder-platform#200
2 parents 601ba7d + 05a342d commit 4809a95

File tree

12 files changed

+51
-22
lines changed

12 files changed

+51
-22
lines changed

__tests__/shared/actions/challenge-listing/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ describe('challengeListing.getPastChallengesInit', () => {
8282
});
8383

8484
describe('challengeListing.getChallengeSubtracksDone', () => {
85-
global.fetch = mockFetch(true, [{ description: 'dummy' }]);
85+
global.fetch = mockFetch(true, { result: { status: 200, content: [{ description: 'dummy' }] } });
8686

8787
const a = actions.getChallengeSubtracksDone();
8888

@@ -91,7 +91,7 @@ describe('challengeListing.getChallengeSubtracksDone', () => {
9191
});
9292

9393
test('payload is a promise which resolves to the expected object', () =>
94-
a.payload.then(res => expect(res).toEqual(['dummy', 'dummy'])));
94+
a.payload.then(res => expect(res).toEqual([{ description: 'dummy' }])));
9595
});
9696

9797
describe('challengeListing.getChallengeTagsDone', () => {

__tests__/shared/components/challenge-listing/Filters/FiltersPanel.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const mockDatas = [{
2525
setFilterState,
2626
setSearchText,
2727
validKeywords: ['key', 'word'],
28-
validSubtracks: ['sub', 'track'],
28+
validSubtracks: [{ name: 'sub', subTrack: 'sub' }, { name: 'track', subTrack: 'track' }],
2929
onClose,
3030
}, {
3131
communityFilters: [

__tests__/shared/reducers/challenge-listing/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ let expectedState = {
8181

8282
challenges: [],
8383
challengeSubtracks: [],
84+
challengeSubtracksMap: {},
8485
challengeTags: [],
8586

8687
filter: {},

src/shared/actions/challenge-listing/index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ function getChallengeSubtracksDone() {
4646
return getService()
4747
.getChallengeSubtracks()
4848
.then(res =>
49-
res.map(item => item.description)
50-
.sort((a, b) => a.localeCompare(b)),
49+
res.sort((a, b) => a.name.localeCompare(b.name)),
5150
);
5251
}
5352

src/shared/components/challenge-detail/Header/ChallengeTags.jsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import React from 'react';
1010
import PT from 'prop-types';
11+
import _ from 'lodash';
1112
import { Link } from 'utils/router';
1213

1314
import './style.scss';
@@ -20,8 +21,17 @@ export default function ChallengeTags(props) {
2021
subTrackStyle,
2122
eventStyle,
2223
setChallengeListingFilter,
24+
challengeSubtracksMap,
2325
} = props;
2426

27+
const stylizedSubTrack = (t) => {
28+
if (challengeSubtracksMap[t]) {
29+
return challengeSubtracksMap[t].name;
30+
}
31+
return (t || '').replace(/_/g, ' ')
32+
.replace(/\w\S*/g, txt => _.capitalize(txt));
33+
};
34+
2535
return (
2636
<div styleName="tag-holder">
2737
{
@@ -30,7 +40,7 @@ export default function ChallengeTags(props) {
3040
onClick={() => setChallengeListingFilter({ subtracks: [subTrack] })}
3141
to="/challenges"
3242
styleName={`tag-common ${subTrackStyle}`}
33-
>{subTrack}</Link>
43+
>{stylizedSubTrack(subTrack)}</Link>
3444
}
3545
{
3646
events.map(event => (
@@ -71,4 +81,5 @@ ChallengeTags.propTypes = {
7181
subTrackStyle: PT.string.isRequired,
7282
eventStyle: PT.string.isRequired,
7383
setChallengeListingFilter: PT.func.isRequired,
84+
challengeSubtracksMap: PT.shape().isRequired,
7485
};

src/shared/components/challenge-detail/Header/index.jsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export default function ChallengeHeader(props) {
3434
setChallengeListingFilter,
3535
unregisterFromChallenge,
3636
unregistering,
37+
challengeSubtracksMap,
3738
} = props;
3839

3940
const {
@@ -66,8 +67,6 @@ export default function ChallengeHeader(props) {
6667

6768
const theme = themeFactory(trackLower);
6869

69-
const stylizedSubTrack = (subTrack || '').replace('_', ' ')
70-
.replace(/\w\S*/g, txt => _.capitalize(txt));
7170
const subTrackStyle = `${trackLower}-accent-background`;
7271
const eventStyle = `${trackLower}-accent-color`;
7372
const eventNames = (events || []).map((event => (event.eventName || '').toUpperCase()));
@@ -181,7 +180,8 @@ export default function ChallengeHeader(props) {
181180
<div styleName="important-detail">
182181
<h1 styleName="challenge-header">{name}</h1>
183182
<ChallengeTags
184-
subTrack={stylizedSubTrack}
183+
subTrack={subTrack}
184+
challengeSubtracksMap={challengeSubtracksMap}
185185
events={eventNames}
186186
technPlatforms={miscTags}
187187
subTrackStyle={subTrackStyle}
@@ -303,4 +303,5 @@ ChallengeHeader.propTypes = {
303303
showDeadlineDetail: PT.bool.isRequired,
304304
unregisterFromChallenge: PT.func.isRequired,
305305
unregistering: PT.bool.isRequired,
306+
challengeSubtracksMap: PT.shape().isRequired,
306307
};

src/shared/components/challenge-listing/Filters/FiltersPanel/index.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export default function FiltersPanel({
5252
}));
5353

5454
const mapOps = item => ({ label: item, value: item });
55-
55+
const mapSubtracks = item => ({ label: item.name, value: item.subTrack });
5656
return (
5757
<div styleName={className}>
5858
<div styleName="header">
@@ -100,7 +100,7 @@ export default function FiltersPanel({
100100
const subtracks = value ? value.split(',') : undefined;
101101
setFilterState(Filter.setSubtracks(filterState, subtracks));
102102
}}
103-
options={validSubtracks.map(mapOps)}
103+
options={validSubtracks.map(mapSubtracks)}
104104
simpleValue
105105
value={
106106
filterState.subtracks ? filterState.subtracks.join(',') : null
@@ -166,6 +166,6 @@ FiltersPanel.propTypes = {
166166
setFilterState: PT.func.isRequired,
167167
setSearchText: PT.func.isRequired,
168168
validKeywords: PT.arrayOf(PT.string).isRequired,
169-
validSubtracks: PT.arrayOf(PT.string).isRequired,
169+
validSubtracks: PT.arrayOf(PT.shape()).isRequired,
170170
onClose: PT.func,
171171
};

src/shared/containers/challenge-detail/index.jsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ class ChallengeDetailPageContainer extends React.Component {
5454

5555
componentDidMount() {
5656
const { challenge, loadChallengeDetails, loadTerms,
57-
openTermsModal, authTokens, challengeId } = this.props;
57+
openTermsModal, authTokens, challengeId,
58+
challengeSubtracksMap, getSubtracks } = this.props;
5859

5960
if (challenge.id !== challengeId) {
6061
loadChallengeDetails(authTokens, challengeId);
@@ -65,6 +66,10 @@ class ChallengeDetailPageContainer extends React.Component {
6566
if (authTokens.tokenV2 && location.search.indexOf('showTerms=true') > 0) {
6667
openTermsModal();
6768
}
69+
70+
if (_.isEmpty(challengeSubtracksMap)) {
71+
getSubtracks();
72+
}
6873
}
6974

7075
componentWillReceiveProps(nextProps) {
@@ -147,6 +152,7 @@ class ChallengeDetailPageContainer extends React.Component {
147152
unregistering={this.props.unregistering}
148153
checkpoints={this.props.checkpoints}
149154
hasRegistered={hasRegistered}
155+
challengeSubtracksMap={this.props.challengeSubtracksMap}
150156
/>
151157
}
152158
{
@@ -286,6 +292,8 @@ ChallengeDetailPageContainer.propTypes = {
286292
agreedTerms: PT.shape(),
287293
loadingDocuSignUrl: PT.string,
288294
setChallengeListingFilter: PT.func.isRequired,
295+
challengeSubtracksMap: PT.shape().isRequired,
296+
getSubtracks: PT.func.isRequired,
289297
};
290298

291299
function extractChallengeDetail(v3, v2, challengeId) {
@@ -392,6 +400,7 @@ const mapStateToProps = (state, props) => ({
392400
agreeingTerm: state.terms.agreeingTerm,
393401
agreedTerms: state.terms.agreedTerms,
394402
isLoadingTerms: state.terms.loadingTermsForChallengeId === props.match.params.challengeId,
403+
challengeSubtracksMap: state.challengeListing.challengeSubtracksMap,
395404
});
396405

397406
const mapDispatchToProps = (dispatch) => {
@@ -463,6 +472,11 @@ const mapDispatchToProps = (dispatch) => {
463472
dispatch(t.agreeTermInit(termId));
464473
dispatch(t.agreeTermDone(termId, tokens.tokenV2));
465474
},
475+
getSubtracks: () => {
476+
const cl = challengeListingActions.challengeListing;
477+
dispatch(cl.getChallengeSubtracksInit());
478+
dispatch(cl.getChallengeSubtracksDone());
479+
},
466480
};
467481
};
468482

src/shared/containers/challenge-listing/Listing/index.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ ListingContainer.propTypes = {
224224
allDraftChallengesLoaded: PT.bool.isRequired,
225225
allPastChallengesLoaded: PT.bool.isRequired,
226226
challenges: PT.arrayOf(PT.shape({})).isRequired,
227-
challengeSubtracks: PT.arrayOf(PT.string).isRequired,
227+
challengeSubtracks: PT.arrayOf(PT.shape()).isRequired,
228228
challengeTags: PT.arrayOf(PT.string).isRequired,
229229
communityFilters: PT.arrayOf(PT.shape({
230230
challengeFilter: PT.shape(),

src/shared/reducers/challenge-listing/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ function onGetChallengeSubtracksDone(state, action) {
5252
return {
5353
...state,
5454
challengeSubtracks: action.error ? [] : action.payload,
55+
challengeSubtracksMap: action.error ? {} : _.keyBy(action.payload, 'subTrack'),
5556
loadingChallengeSubtracks: false,
5657
};
5758
}
@@ -237,6 +238,7 @@ function create(initialState) {
237238

238239
challenges: [],
239240
challengeSubtracks: [],
241+
challengeSubtracksMap: {},
240242
challengeTags: [],
241243

242244
filter: {},

src/shared/services/challenges.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,13 @@ class ChallengesService {
140140
* @return {Promise} Resolves to the array of subtrack names.
141141
*/
142142
getChallengeSubtracks() {
143-
return Promise.all([
144-
this.private.apiV2.get('/design/challengetypes')
145-
.then(res => (res.ok ? res.json() : new Error(res.statusText))),
146-
this.private.apiV2.get('/develop/challengetypes')
147-
.then(res => (res.ok ? res.json() : new Error(res.statusText))),
148-
]).then(([a, b]) => a.concat(b));
143+
return this.private.api.get('/challenge-types')
144+
.then(res => (res.ok ? res.json() : new Error(res.statusText)))
145+
.then(res => (
146+
res.result.status === 200 ?
147+
res.result.content :
148+
new Error(res.result.content)
149+
));
149150
}
150151

151152
/**

src/shared/utils/challenge-listing/filter.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ function filterBySubtracks(challenge, state) {
114114
* why challenge subtracks in challenge objects are different from those
115115
* return from the API as the list of possible subtracks. */
116116
const filterSubtracks = state.subtracks.map(item =>
117-
item.toLowerCase().replace(/ /g, ''));
118-
const challengeSubtrack = challenge.subTrack.toLowerCase().replace(/_/g, '');
117+
item.toLowerCase().replace(/[_ ]/g, ''));
118+
const challengeSubtrack = challenge.subTrack.toLowerCase().replace(/[_ ]/g, '');
119119
return filterSubtracks.includes(challengeSubtrack);
120120
}
121121

0 commit comments

Comments
 (0)