({ label: item, value: item });
+ const mapSubtracks = item => ({ label: item.name, value: item.subTrack });
return (
@@ -98,7 +99,7 @@ export default function FiltersPanel({
const subtracks = value ? value.split(',') : undefined;
setFilterState(Filter.setSubtracks(filterState, subtracks));
}}
- options={validSubtracks.map(mapOps)}
+ options={validSubtracks.map(mapSubtracks)}
simpleValue
value={
filterState.subtracks ? filterState.subtracks.join(',') : null
@@ -162,6 +163,6 @@ FiltersPanel.propTypes = {
setFilterState: PT.func.isRequired,
setSearchText: PT.func.isRequired,
validKeywords: PT.arrayOf(PT.string).isRequired,
- validSubtracks: PT.arrayOf(PT.string).isRequired,
+ validSubtracks: PT.arrayOf(PT.shape()).isRequired,
onClose: PT.func,
};
diff --git a/src/shared/containers/challenge-detail/index.jsx b/src/shared/containers/challenge-detail/index.jsx
index 96b759f7f7..c6dac9a08d 100644
--- a/src/shared/containers/challenge-detail/index.jsx
+++ b/src/shared/containers/challenge-detail/index.jsx
@@ -54,7 +54,8 @@ class ChallengeDetailPageContainer extends React.Component {
componentDidMount() {
const { challenge, loadChallengeDetails, loadTerms,
- openTermsModal, authTokens, challengeId } = this.props;
+ openTermsModal, authTokens, challengeId,
+ challengeSubtracksMap, getSubtracks } = this.props;
if (challenge.id !== challengeId) {
loadChallengeDetails(authTokens, challengeId);
@@ -65,6 +66,10 @@ class ChallengeDetailPageContainer extends React.Component {
if (authTokens.tokenV2 && location.search.indexOf('showTerms=true') > 0) {
openTermsModal();
}
+
+ if (_.isEmpty(challengeSubtracksMap)) {
+ getSubtracks();
+ }
}
componentWillReceiveProps(nextProps) {
@@ -147,6 +152,7 @@ class ChallengeDetailPageContainer extends React.Component {
unregistering={this.props.unregistering}
checkpoints={this.props.checkpoints}
hasRegistered={hasRegistered}
+ challengeSubtracksMap={this.props.challengeSubtracksMap}
/>
}
{
@@ -282,6 +288,8 @@ ChallengeDetailPageContainer.propTypes = {
agreedTerms: PT.shape(),
loadingDocuSignUrl: PT.string,
setChallengeListingFilter: PT.func.isRequired,
+ challengeSubtracksMap: PT.shape().isRequired,
+ getSubtracks: PT.func.isRequired,
};
function extractChallengeDetail(v3, v2, challengeId) {
@@ -388,6 +396,7 @@ const mapStateToProps = (state, props) => ({
agreeingTerm: state.terms.agreeingTerm,
agreedTerms: state.terms.agreedTerms,
isLoadingTerms: state.terms.loadingTermsForChallengeId === props.match.params.challengeId,
+ challengeSubtracksMap: state.challengeListing.challengeSubtracksMap,
});
const mapDispatchToProps = (dispatch) => {
@@ -456,6 +465,11 @@ const mapDispatchToProps = (dispatch) => {
dispatch(t.agreeTermInit(termId));
dispatch(t.agreeTermDone(termId, tokens.tokenV2));
},
+ getSubtracks: () => {
+ const cl = challengeListingActions.challengeListing;
+ dispatch(cl.getChallengeSubtracksInit());
+ dispatch(cl.getChallengeSubtracksDone());
+ },
};
};
diff --git a/src/shared/containers/challenge-listing/Listing/index.jsx b/src/shared/containers/challenge-listing/Listing/index.jsx
index 327ee359da..7e9f22f14a 100644
--- a/src/shared/containers/challenge-listing/Listing/index.jsx
+++ b/src/shared/containers/challenge-listing/Listing/index.jsx
@@ -224,7 +224,7 @@ ListingContainer.propTypes = {
allDraftChallengesLoaded: PT.bool.isRequired,
allPastChallengesLoaded: PT.bool.isRequired,
challenges: PT.arrayOf(PT.shape({})).isRequired,
- challengeSubtracks: PT.arrayOf(PT.string).isRequired,
+ challengeSubtracks: PT.arrayOf(PT.shape()).isRequired,
challengeTags: PT.arrayOf(PT.string).isRequired,
communityFilters: PT.arrayOf(PT.shape({
challengeFilter: PT.shape(),
diff --git a/src/shared/reducers/challenge-listing/index.js b/src/shared/reducers/challenge-listing/index.js
index 18b762adb2..0c50d4a77c 100644
--- a/src/shared/reducers/challenge-listing/index.js
+++ b/src/shared/reducers/challenge-listing/index.js
@@ -52,6 +52,7 @@ function onGetChallengeSubtracksDone(state, action) {
return {
...state,
challengeSubtracks: action.error ? [] : action.payload,
+ challengeSubtracksMap: action.error ? {} : _.keyBy(action.payload, 'subTrack'),
loadingChallengeSubtracks: false,
};
}
@@ -237,6 +238,7 @@ function create(initialState) {
challenges: [],
challengeSubtracks: [],
+ challengeSubtracksMap: {},
challengeTags: [],
filter: {},
diff --git a/src/shared/services/challenges.js b/src/shared/services/challenges.js
index af35c1e150..ce0139442c 100644
--- a/src/shared/services/challenges.js
+++ b/src/shared/services/challenges.js
@@ -140,12 +140,13 @@ class ChallengesService {
* @return {Promise} Resolves to the array of subtrack names.
*/
getChallengeSubtracks() {
- return Promise.all([
- this.private.apiV2.get('/design/challengetypes')
- .then(res => (res.ok ? res.json() : new Error(res.statusText))),
- this.private.apiV2.get('/develop/challengetypes')
- .then(res => (res.ok ? res.json() : new Error(res.statusText))),
- ]).then(([a, b]) => a.concat(b));
+ return this.private.api.get('/challenge-types')
+ .then(res => (res.ok ? res.json() : new Error(res.statusText)))
+ .then(res => (
+ res.result.status === 200 ?
+ res.result.content :
+ new Error(res.result.content)
+ ));
}
/**
From a6e8d5ee203440854dbba79ece974a08dfdb0200 Mon Sep 17 00:00:00 2001
From: Colin Hunt
Date: Mon, 28 Aug 2017 10:28:23 +0700
Subject: [PATCH 32/87] implemented requested changes
---
src/shared/utils/challenge-listing/buckets.js | 4 +--
src/shared/utils/challenge-listing/filter.js | 2 +-
src/shared/utils/challenge-listing/sort.js | 27 ++++++++-----------
3 files changed, 14 insertions(+), 19 deletions(-)
diff --git a/src/shared/utils/challenge-listing/buckets.js b/src/shared/utils/challenge-listing/buckets.js
index b662078a69..0e2445812c 100644
--- a/src/shared/utils/challenge-listing/buckets.js
+++ b/src/shared/utils/challenge-listing/buckets.js
@@ -40,7 +40,7 @@ export function getBuckets(userHandle) {
name: 'My Challenges',
sorts: [
SORTS.MOST_RECENT,
- SORTS.PHASE_END_TIME,
+ SORTS.TIME_TO_SUBMIT,
SORTS.NUM_REGISTRANTS,
SORTS.NUM_SUBMISSIONS,
SORTS.PRIZE_HIGH_TO_LOW,
@@ -58,7 +58,7 @@ export function getBuckets(userHandle) {
sorts: [
SORTS.MOST_RECENT,
SORTS.TIME_TO_REGISTER,
- SORTS.PHASE_END_TIME,
+ SORTS.TIME_TO_SUBMIT,
SORTS.NUM_REGISTRANTS,
SORTS.NUM_SUBMISSIONS,
SORTS.PRIZE_HIGH_TO_LOW,
diff --git a/src/shared/utils/challenge-listing/filter.js b/src/shared/utils/challenge-listing/filter.js
index b02236aee6..74f2be57f4 100644
--- a/src/shared/utils/challenge-listing/filter.js
+++ b/src/shared/utils/challenge-listing/filter.js
@@ -73,7 +73,7 @@ function filterByGroupIds(challenge, state) {
function filterByRegistrationOpen(challenge, state) {
if (_.isUndefined(state.registrationOpen)) return true;
const isRegOpen = () => {
- if ('registrationOpen' in challenge) {
+ if (challenge.registrationOpen) {
return challenge.registrationOpen === 'Yes';
}
if (challenge.subTrack === 'MARATHON_MATCH') {
diff --git a/src/shared/utils/challenge-listing/sort.js b/src/shared/utils/challenge-listing/sort.js
index cdfd90db2d..cbfe9fd1be 100644
--- a/src/shared/utils/challenge-listing/sort.js
+++ b/src/shared/utils/challenge-listing/sort.js
@@ -9,7 +9,6 @@ export const SORTS = {
MOST_RECENT: 'most-recent',
NUM_REGISTRANTS: 'num-registrants',
NUM_SUBMISSIONS: 'num-submissions',
- PHASE_END_TIME: 'phase-end-time',
PRIZE_HIGH_TO_LOW: 'prize-high-to-low',
TIME_TO_REGISTER: 'time-to-register',
TIME_TO_SUBMIT: 'time-to-submit',
@@ -33,10 +32,19 @@ export default {
func: (a, b) => b.numSubmissions - a.numSubmissions,
name: '# of submissions',
},
- [SORTS.PHASE_END_TIME]: {
+ [SORTS.PRIZE_HIGH_TO_LOW]: {
+ func: (a, b) => b.totalPrize - a.totalPrize,
+ name: 'Prize high to low',
+ },
+ [SORTS.TIME_TO_REGISTER]: {
+ func: (a, b) => moment(a.registrationEndDate || a.submissionEndDate)
+ .diff(b.registrationEndDate || b.submissionEndDate),
+ name: 'Time to register',
+ },
+ [SORTS.TIME_TO_SUBMIT]: {
func: (a, b) => {
function nextSubEndDate(o) {
- if (("checkpointSubmissionEndDate" in o) && moment(o.checkpointSubmissionEndDate).isAfter()) {
+ if (o.checkpointSubmissionEndDate && moment(o.checkpointSubmissionEndDate).isAfter()) {
return o.checkpointSubmissionEndDate;
}
return o.submissionEndDate;
@@ -48,19 +56,6 @@ export default {
},
name: 'Time to submit',
},
- [SORTS.PRIZE_HIGH_TO_LOW]: {
- func: (a, b) => b.totalPrize - a.totalPrize,
- name: 'Prize high to low',
- },
- [SORTS.TIME_TO_REGISTER]: {
- func: (a, b) => moment(a.registrationEndDate || a.submissionEndDate)
- .diff(b.registrationEndDate || b.submissionEndDate),
- name: 'Time to register',
- },
- [SORTS.TIME_TO_SUBMIT]: {
- func: (a, b) => moment(a.submissionEndDate).diff(b.submissionEndDate),
- name: 'Time to submit',
- },
[SORTS.TITLE_A_TO_Z]: {
func: (a, b) => a.name.localeCompare(b.name),
name: 'Title A-Z',
From dad8bfd57ff379fd76ec62ecab910594c667644d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BB=BB=E5=BA=86=E4=BC=9F?=
Date: Mon, 28 Aug 2017 13:14:08 +0800
Subject: [PATCH 33/87] update issue 212's fix logic as suggested
---
.../components/challenge-listing/index.jsx | 25 ++-----------------
.../reducers/challenge-listing/index.js | 7 ++++++
src/shared/utils/url.js | 6 +++++
3 files changed, 15 insertions(+), 23 deletions(-)
diff --git a/src/shared/components/challenge-listing/index.jsx b/src/shared/components/challenge-listing/index.jsx
index bce829d022..1989c3e551 100755
--- a/src/shared/components/challenge-listing/index.jsx
+++ b/src/shared/components/challenge-listing/index.jsx
@@ -16,35 +16,14 @@ import Listing from './Listing';
import ChallengeCardPlaceholder from './placeholders/ChallengeCard';
import SRMCard from './SRMCard';
+import { updateQuery } from 'utils/url';
import './style.scss';
// Number of challenge placeholder card to display
const CHALLENGE_PLACEHOLDER_COUNT = 8;
export default function ChallengeListing(props) {
- function CheckDateTime(str) {
- const reg = /^(\d{4})-(\d{1,2})-(\d{1,2})T(\d{1,2}):(\d{1,2}):(\d{1,2})\.(\d{3})Z$/;
- const r = str.match(reg);
- if (r == null) return false;
- r[2] -= 1;
- const d = new Date(r[1], r[2], r[3], r[4], r[5], r[6]);
- if (d.getFullYear() !== r[1]) return false;
- if (d.getMonth() !== r[2]) return false;
- if (d.getDate() !== r[3]) return false;
- if (d.getHours() !== r[4]) return false;
- if (d.getMinutes() !== r[5]) return false;
- if (d.getSeconds() !== r[6]) return false;
- return true;
- }
- const filterState = props.filterState;
- if (filterState) {
- if (!!filterState.startDate && CheckDateTime(filterState.startDate) === false) {
- delete filterState.startDate;
- }
- if (!!filterState.endDate && CheckDateTime(filterState.endDate) === false) {
- delete filterState.endDate;
- }
- }
+ updateQuery({ });
let challenges = props.challenges;
if (props.communityFilter) {
diff --git a/src/shared/reducers/challenge-listing/index.js b/src/shared/reducers/challenge-listing/index.js
index 18b762adb2..f67d048dc8 100644
--- a/src/shared/reducers/challenge-listing/index.js
+++ b/src/shared/reducers/challenge-listing/index.js
@@ -8,6 +8,7 @@ import logger from 'utils/logger';
import { handleActions } from 'redux-actions';
import { combine, resolveReducers } from 'utils/redux';
import { updateQuery } from 'utils/url';
+import moment from 'moment';
import filterPanel from '../challenge-listing/filter-panel';
import sidebar, { factory as sidebarFactory } from '../challenge-listing/sidebar';
@@ -270,6 +271,12 @@ export function factory(req) {
if (req) {
state.filter = req.query.filter;
+ if (!!state.filter.startDate && moment(state.filter.startDate).isValid() === false) {
+ delete state.filter.startDate;
+ }
+ if (!!state.filter.endDate && moment(state.filter.endDate).isValid() === false) {
+ delete state.filter.endDate;
+ }
state.selectedCommunityId = req.query.communityId;
}
diff --git a/src/shared/utils/url.js b/src/shared/utils/url.js
index c5717aca23..fc3512d691 100644
--- a/src/shared/utils/url.js
+++ b/src/shared/utils/url.js
@@ -6,6 +6,7 @@
import _ from 'lodash';
import qs from 'qs';
+import moment from 'moment';
/**
* If executed client-side (determined in this case by the presence of global
@@ -28,6 +29,11 @@ export function updateQuery(update) {
if (_.isUndefined(value)) delete query[key];
else query[key] = value;
});
+ if (!!query.filter.startDate && moment(query.filter.startDate).isValid() === false) {
+ delete query.filter.startDate; console.log('delete start date');
+ } else if (query.filter.endDate && moment(query.filter.endDate).isValid() === false) {
+ delete query.filter.endDate; console.log('delete end date');
+ }
query = `?${qs.stringify(query, { encode: false })}`;
window.history.replaceState(window.history.state, '', query);
From a2940ddef65893792793eb375998ace00369745e Mon Sep 17 00:00:00 2001
From: shubhu
Date: Mon, 28 Aug 2017 10:49:12 +0530
Subject: [PATCH 34/87] cleaned code into conditional blocks
---
.../SubmissionManagement/index.jsx | 21 ++++++++++---------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/src/shared/components/SubmissionManagement/SubmissionManagement/index.jsx b/src/shared/components/SubmissionManagement/SubmissionManagement/index.jsx
index cc76c7cd98..0244974113 100644
--- a/src/shared/components/SubmissionManagement/SubmissionManagement/index.jsx
+++ b/src/shared/components/SubmissionManagement/SubmissionManagement/index.jsx
@@ -72,16 +72,17 @@ export default function SubmissionManagement(props) {
{currentPhase.phaseType}
- {challenge.status !== 'COMPLETED' &&
-
-
- {days > 0 && (`${days}D`)} {hours}H {minutes}M
-
-
left
-
- }
- {challenge.status === 'COMPLETED' &&
-
The challenge has ended
+ {
+ challenge.status !== 'COMPLETED' ? (
+
+
+ {days > 0 && (`${days}D`)} {hours}H {minutes}M
+
+
left
+
+ ) : (
+
The challenge has ended
+ )
}