Skip to content

Commit cb326e5

Browse files
authored
Merge pull request #3629 from topcoder-platform/hot-fix-past-challenge-search
Hot fix past challenge search
2 parents aa5a722 + 764b663 commit cb326e5

File tree

9 files changed

+57
-6
lines changed

9 files changed

+57
-6
lines changed

.circleci/config.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ workflows:
175175
branches:
176176
only:
177177
- develop
178-
- hot-fix-no-result
178+
- hot-fix-past-challenge-search
179+
# This is alternate dev env for parallel testing
179180
- "build-test":
180181
context : org-global
181182
filters:

__tests__/shared/components/challenge-listing/ChallengeCard/__snapshots__/index.jsx.snap

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ exports[`Matches shallow shapshot shapshot 1 1`] = `
3737
"users": Object {},
3838
}
3939
}
40+
domRef={null}
4041
expandTag={null}
4142
expandedTags={Array []}
4243
newChallengeDetails={false}
@@ -74,6 +75,7 @@ exports[`Matches shallow shapshot shapshot 2 1`] = `
7475
"users": Object {},
7576
}
7677
}
78+
domRef={null}
7779
expandTag={null}
7880
expandedTags={Array []}
7981
newChallengeDetails={false}
@@ -109,6 +111,7 @@ exports[`Matches shallow shapshot shapshot 3 1`] = `
109111
"users": Object {},
110112
}
111113
}
114+
domRef={null}
112115
expandTag={null}
113116
expandedTags={Array []}
114117
newChallengeDetails={false}

__tests__/shared/components/challenge-listing/Listing/__snapshots__/Bucket.jsx.snap

+3
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ exports[`Matches shallow shapshot 1`] = `
7777
loading={false}
7878
newChallengeDetails={false}
7979
openChallengesInNewTabs={false}
80+
searchTimestamp={0}
8081
setFilterState={[MockFunction]}
8182
setSort={[MockFunction]}
8283
sort=""
@@ -226,6 +227,7 @@ exports[`Matches shallow shapshot 2`] = `
226227
loading={true}
227228
newChallengeDetails={false}
228229
openChallengesInNewTabs={false}
230+
searchTimestamp={0}
229231
setFilterState={[MockFunction]}
230232
setSort={[MockFunction]}
231233
sort=""
@@ -262,6 +264,7 @@ exports[`Matches shallow shapshot 3`] = `
262264
loading={true}
263265
newChallengeDetails={false}
264266
openChallengesInNewTabs={false}
267+
searchTimestamp={0}
265268
setFilterState={[MockFunction]}
266269
setSort={[MockFunction]}
267270
sort=""

config/default.js

+6
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ module.exports = {
158158
* object should be considered outdated, and updated as soon as possible. */
159159
USER_GROUP_MAXAGE: 24 * 60 * 60 * 1000,
160160

161+
/* Maximum time to wait before timeout on searching past challenges (seconds)
162+
* when no result at all.
163+
* Default: 30 seconds.
164+
*/
165+
SEARCH_TIMEOUT: 30 * 1000,
166+
161167
/* Filestack configuration for uploading Submissions
162168
* These are for the development back end */
163169
FILESTACK: {

src/shared/components/challenge-listing/ChallengeCard/index.jsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ function ChallengeCard({
5050
sampleWinnerProfile,
5151
selectChallengeDetailsTab,
5252
userHandle,
53+
domRef,
5354
}) {
5455
const challenge = passedInChallenge;
5556
const {
@@ -110,7 +111,7 @@ function ChallengeCard({
110111
}
111112

112113
return (
113-
<div styleName="challengeCard">
114+
<div ref={domRef} styleName="challengeCard">
114115
<div styleName="left-panel">
115116
<div styleName="challenge-track">
116117
<TrackAbbreviationTooltip track={challenge.track} subTrack={challenge.subTrack}>
@@ -200,6 +201,7 @@ ChallengeCard.defaultProps = {
200201
userHandle: '',
201202
expandedTags: [],
202203
expandTag: null,
204+
domRef: null,
203205
};
204206

205207
ChallengeCard.propTypes = {
@@ -214,6 +216,7 @@ ChallengeCard.propTypes = {
214216
userHandle: PT.string,
215217
expandedTags: PT.arrayOf(PT.number),
216218
expandTag: PT.func,
219+
domRef: PT.func,
217220
};
218221

219222
export default ChallengeCard;

src/shared/components/challenge-listing/Listing/Bucket/index.jsx

+22-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
import _ from 'lodash';
88
import PT from 'prop-types';
99
import qs from 'qs';
10-
import React from 'react';
10+
import React, { useRef } from 'react';
11+
import { config } from 'topcoder-react-utils';
1112
import Sort from 'utils/challenge-listing/sort';
1213
import { NO_LIVE_CHALLENGES_CONFIG, BUCKETS } from 'utils/challenge-listing/buckets';
1314
import SortingSelectBar from 'components/SortingSelectBar';
@@ -44,7 +45,15 @@ export default function Bucket({
4445
expandedTags,
4546
expandTag,
4647
activeBucket,
48+
searchTimestamp,
4749
}) {
50+
const refs = useRef([]);
51+
refs.current = [];
52+
const addToRefs = (el) => {
53+
if (el) {
54+
refs.current.push(el);
55+
}
56+
};
4857
const filter = Filter.getFilterFunction(bucket.filter);
4958
const activeSort = sort || bucket.sorts[0];
5059

@@ -69,7 +78,15 @@ export default function Bucket({
6978
}
7079
}
7180

72-
if (!filteredChallenges.length && !loadMore) {
81+
let noPastResult = false;
82+
// check if no past challenge is found after configurable amount of time has passed
83+
if (activeBucket === BUCKETS.PAST && searchTimestamp > 0
84+
&& !filteredChallenges.length && !refs.current.length) {
85+
const elapsedTime = Date.now() - searchTimestamp;
86+
noPastResult = elapsedTime > config.SEARCH_TIMEOUT;
87+
}
88+
89+
if (noPastResult || (!filteredChallenges.length && !loadMore)) {
7390
if (activeBucket === BUCKETS.ALL) {
7491
return null;
7592
}
@@ -93,6 +110,7 @@ export default function Bucket({
93110
userHandle={userHandle}
94111
expandedTags={expandedTags}
95112
expandTag={expandTag}
113+
domRef={addToRefs}
96114
/>
97115
));
98116

@@ -170,6 +188,7 @@ Bucket.defaultProps = {
170188
expandedTags: [],
171189
expandTag: null,
172190
activeBucket: '',
191+
searchTimestamp: 0,
173192
};
174193

175194
Bucket.propTypes = {
@@ -195,4 +214,5 @@ Bucket.propTypes = {
195214
expandedTags: PT.arrayOf(PT.number),
196215
expandTag: PT.func,
197216
activeBucket: PT.string,
217+
searchTimestamp: PT.number,
198218
};

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

+7
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ function Listing({
4242
sorts,
4343
expandedTags,
4444
expandTag,
45+
pastSearchTimestamp,
4546
}) {
4647
const buckets = getBuckets(_.get(auth.user, 'handle'));
4748
const isChallengesAvailable = (bucket) => {
@@ -59,11 +60,13 @@ function Listing({
5960
let keepPlaceholders = false;
6061
let loading;
6162
let loadMore;
63+
let searchTimestamp;
6264
switch (bucket) {
6365
case BUCKETS.PAST:
6466
keepPlaceholders = keepPastPlaceholders;
6567
loading = loadingPastChallenges;
6668
loadMore = loadMorePast;
69+
searchTimestamp = pastSearchTimestamp;
6770
break;
6871
default:
6972
break;
@@ -113,6 +116,7 @@ function Listing({
113116
sort={sorts[bucket]}
114117
userHandle={_.get(auth, 'user.handle')}
115118
activeBucket={activeBucket}
119+
searchTimestamp={searchTimestamp}
116120
/>
117121
)
118122
);
@@ -167,6 +171,7 @@ Listing.defaultProps = {
167171
// onTechTagClicked: _.noop,
168172
// onExpandFilterResult: _.noop,
169173
openChallengesInNewTabs: false,
174+
pastSearchTimestamp: 0,
170175
};
171176

172177
Listing.propTypes = {
@@ -200,12 +205,14 @@ Listing.propTypes = {
200205
setFilterState: PT.func.isRequired,
201206
setSort: PT.func.isRequired,
202207
sorts: PT.shape().isRequired,
208+
pastSearchTimestamp: PT.number,
203209
};
204210

205211
const mapStateToProps = (state) => {
206212
const cl = state.challengeListing;
207213
return {
208214
allActiveChallengesLoaded: cl.allActiveChallengesLoaded,
215+
pastSearchTimestamp: cl.pastSearchTimestamp,
209216
};
210217
};
211218

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

+8
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,16 @@ function onGetPastChallengesDone(state, { error, payload }) {
216216
keepPastPlaceholders = challenges.filter(ff).length - state.challenges.filter(ff).length < 10;
217217
}
218218

219+
const pastSearchTimestamp = state.pastSearchTimestamp && state.pastSearchTimestamp > 0
220+
? state.pastSearchTimestamp : Date.now();
221+
219222
return {
220223
...state,
221224
allPastChallengesLoaded: loaded.length === 0,
222225
challenges,
223226
keepPastPlaceholders,
224227
loadingPastChallengesUUID: '',
228+
pastSearchTimestamp,
225229
};
226230
}
227231

@@ -237,6 +241,7 @@ function onSelectCommunity(state, { payload }) {
237241
* challenges). */
238242
allPastChallengesLoaded: false,
239243
lastRequestedPageOfPastChallenges: -1,
244+
pastSearchTimestamp: -1,
240245
};
241246
}
242247

@@ -273,6 +278,7 @@ function onSetFilter(state, { payload }) {
273278
* the code simple we just reset them each time a filter is modified. */
274279
allPastChallengesLoaded: false,
275280
lastRequestedPageOfPastChallenges: -1,
281+
pastSearchTimestamp: -1,
276282
};
277283
}
278284

@@ -488,6 +494,8 @@ function create(initialState) {
488494
openChallengesCount: 0,
489495
totalCount: 0,
490496
},
497+
498+
pastSearchTimestamp: -1,
491499
}));
492500
}
493501

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ const BUCKET_DATA = {
122122
export const NO_LIVE_CHALLENGES_CONFIG = {
123123
[BUCKETS.ALL]: 'No Live Challenges found in All Challenges',
124124
[BUCKETS.MY]: 'No challenges found in My Challenges',
125-
[BUCKETS.OPEN_FOR_REGISTRATION]: 'No challenges found in Open for Registration',
125+
[BUCKETS.OPEN_FOR_REGISTRATION]: 'No challenges found in Open for Registration Challenges',
126126
[BUCKETS.ONGOING]: 'No challenges found in Ongoing Challenges',
127-
[BUCKETS.PAST]: 'No challenges found in Past',
127+
[BUCKETS.PAST]: 'No challenges found in Past Challenges',
128128
[BUCKETS.SAVED_FILTER]: 'No challenges found in Saved filter Challenges',
129129
[BUCKETS.UPCOMING]: 'No challenges found in Upcoming Challenges',
130130
};

0 commit comments

Comments
 (0)