From 02c468e257c5ed970a9d215577fe337432bb2c71 Mon Sep 17 00:00:00 2001 From: Sushil Shinde Date: Mon, 31 Aug 2020 14:25:51 +0530 Subject: [PATCH 1/2] Merge pull request #4825 from cagdas001/fix-4782-workaround fix: my challenges bucket --- src/shared/actions/challenge-listing/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/actions/challenge-listing/index.js b/src/shared/actions/challenge-listing/index.js index 1971fead28..a33623e9b7 100644 --- a/src/shared/actions/challenge-listing/index.js +++ b/src/shared/actions/challenge-listing/index.js @@ -339,7 +339,7 @@ function getUserChallengesInit(uuid) { function getUserChallengesDone(userId, tokenV3) { const service = getService(tokenV3); - return service.getUserResources(userId) + return service.getUserResources(userId, 1, 10000) .then(item => item) .catch((error) => { fireErrorMessage('Error Getting User Challenges', error.content || error); From c0ba65d94323591e43f981365b84e2f516f504a1 Mon Sep 17 00:00:00 2001 From: Luiz Ricardo Rodrigues Date: Wed, 2 Sep 2020 02:27:59 -0300 Subject: [PATCH 2/2] Merge pull request #4842 from cagdas001/fix-4723 fix(challenge-detail): wrong dates/phases at deadlines panel --- .../Header/DeadlinesPanel/index.jsx | 7 +-- .../challenge-detail/Header/index.jsx | 43 +++++++++++-------- src/shared/utils/challenge-listing/helper.js | 6 ++- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/shared/components/challenge-detail/Header/DeadlinesPanel/index.jsx b/src/shared/components/challenge-detail/Header/DeadlinesPanel/index.jsx index fdf53200d5..cd8abc1e5c 100644 --- a/src/shared/components/challenge-detail/Header/DeadlinesPanel/index.jsx +++ b/src/shared/components/challenge-detail/Header/DeadlinesPanel/index.jsx @@ -6,14 +6,15 @@ import moment from 'moment-timezone'; import PT from 'prop-types'; import React from 'react'; +import { phaseEndDate, phaseStartDate } from 'utils/challenge-listing/helper'; import Card from './Card'; import './style.scss'; export default function DeadlinesPanel({ deadlines }) { /* Calculates challenge start time. */ let start = deadlines[0] || {}; - start = start.actualStartDate || start.scheduledStartDate; - const started = moment(start).isBefore(moment()); + start = phaseStartDate(start); + const started = moment(start).isBefore(); return (
@@ -29,7 +30,7 @@ export default function DeadlinesPanel({ deadlines }) { { deadlines.map((d, index) => ( ))} diff --git a/src/shared/components/challenge-detail/Header/index.jsx b/src/shared/components/challenge-detail/Header/index.jsx index 0a6594ea8f..fe2c2d47c7 100644 --- a/src/shared/components/challenge-detail/Header/index.jsx +++ b/src/shared/components/challenge-detail/Header/index.jsx @@ -15,6 +15,7 @@ import React from 'react'; import { DangerButton, PrimaryButton } from 'topcoder-react-ui-kit'; import { Link } from 'topcoder-react-utils'; import { COMPETITION_TRACKS } from 'utils/tc'; +import { phaseEndDate } from 'utils/challenge-listing/helper'; import LeftArrow from 'assets/images/arrow-prev.svg'; @@ -69,16 +70,17 @@ export default function ChallengeHeader(props) { numOfRegistrants, numOfCheckpointSubmissions, numOfSubmissions, - endDate, status, type, track, } = challenge; const tags = challenge.tags || []; - const appealsEndDate = endDate; const allPhases = challenge.phases || []; + const sortedAllPhases = _.cloneDeep(allPhases) + .sort((a, b) => moment(phaseEndDate(a)).diff(phaseEndDate(b))); + const { prizes } = prizeSets && prizeSets.length ? prizeSets[0] : []; const checkpointPrizes = _.find(prizeSets, { type: 'checkpoint' }); @@ -122,14 +124,14 @@ export default function ChallengeHeader(props) { */ const hasSubmissions = !_.isEmpty(mySubmissions); - let nextPhase = allPhases.filter(p => p.isOpen) - .sort((a, b) => moment(a.scheduledEndDate).diff(b.scheduledEndDate))[0]; - if (hasRegistered && allPhases[0] && allPhases[0].name === 'Registration') { - nextPhase = allPhases[1] || {}; + const openPhases = sortedAllPhases.filter(p => p.isOpen); + let nextPhase = openPhases[0]; + if (hasRegistered && openPhases[0] && openPhases[0].name === 'Registration') { + nextPhase = openPhases[1] || {}; } const nextDeadline = nextPhase && nextPhase.name; - const deadlineEnd = moment(nextPhase && nextPhase.scheduledEndDate); + const deadlineEnd = moment(nextPhase && phaseEndDate(nextPhase)); const currentTime = moment(); let timeLeft = deadlineEnd.isAfter(currentTime) @@ -147,8 +149,8 @@ export default function ChallengeHeader(props) { if (showDeadlineDetail) { relevantPhases = (allPhases || []).filter((phase) => { if (phase.name === 'Iterative Review') { - const end = phase.actualEndDate || phase.scheduledEndDate; - return moment(end).isAfter(moment()); + const end = phaseEndDate(phase); + return moment(end).isAfter(); } const phaseLowerCase = phase.name.toLowerCase(); if (phaseLowerCase.includes('screening') || phaseLowerCase.includes('specification')) { @@ -168,30 +170,34 @@ export default function ChallengeHeader(props) { if (b.name.toLowerCase().includes('registration')) { return 1; } - return (new Date(a.scheduledEndDate || a.actualEndDate)).getTime() - - (new Date(b.scheduledEndDate || b.actualEndDate)).getTime(); + const aEndDate = phaseEndDate(a); + const bEndDate = phaseEndDate(b); + return moment(aEndDate).diff(bEndDate); }); if (type === 'First2Finish' && status === 'Completed') { const phases2 = allPhases.filter(p => p.name === 'Iterative Review' && !p.isOpen); - const endPhaseDate = Math.max(...phases2.map(d => new Date(d.scheduledEndDate))); + const endPhaseDate = Math.max(...phases2.map(d => phaseEndDate(d))); relevantPhases = _.filter(relevantPhases, p => (p.name.toLowerCase().includes('registration') - || new Date(p.scheduledEndDate).getTime() < endPhaseDate)); + || phaseEndDate(p).getTime() < endPhaseDate)); relevantPhases.push({ id: -1, name: 'Winners', + isOpen: false, + actualEndDate: endPhaseDate, scheduledEndDate: endPhaseDate, }); } else if (relevantPhases.length > 1) { const lastPhase = relevantPhases[relevantPhases.length - 1]; - const lastPhaseTime = ( - new Date(lastPhase.actualEndDate || lastPhase.scheduledEndDate) - ).getTime(); + const lastPhaseTime = phaseEndDate(lastPhase).getTime(); - const appealsEnd = (new Date(appealsEndDate).getTime()); - if (lastPhaseTime < appealsEnd && lastPhase.name !== 'Review') { + const appealsEndDate = phaseEndDate(sortedAllPhases[sortedAllPhases.length - 1]); + const appealsEnd = appealsEndDate.getTime(); + if (lastPhaseTime < appealsEnd) { relevantPhases.push({ id: -1, name: 'Winners', + isOpen: false, + actualEndDate: appealsEndDate, scheduledEndDate: appealsEndDate, }); } @@ -495,7 +501,6 @@ ChallengeHeader.propTypes = { numOfCheckpointSubmissions: PT.any, numOfSubmissions: PT.any, status: PT.any, - endDate: PT.any, phases: PT.any, roundId: PT.any, prizeSets: PT.any, diff --git a/src/shared/utils/challenge-listing/helper.js b/src/shared/utils/challenge-listing/helper.js index 192dafcc04..765fed8af0 100644 --- a/src/shared/utils/challenge-listing/helper.js +++ b/src/shared/utils/challenge-listing/helper.js @@ -9,7 +9,11 @@ export function phaseEndDate(phase) { // Case 1: phase is still open. take the `scheduledEndDate` // Case 2: phase is not open but `scheduledStartDate` is a future date. // This means phase is not yet started. So take the `scheduledEndDate` - if (phase.isOpen || moment(phase.scheduledStartDate).isAfter()) { + // Case 3: phase is not open & `scheduledStartDate` is a past date, + // but the phase is `Iterative Review`. It will take the `scheduledEndDate` + // as it's a valid scenario for iterative review, + // there might not be any submission yet to open the phase + if (phase.isOpen || moment(phase.scheduledStartDate).isAfter() || phase.name === 'Iterative Review') { return new Date(phase.scheduledEndDate); } // for other cases, take the `actualEndDate` as phase is already closed