Skip to content

Issue#4408 : Fix registrants and submissions tabs in challenge details #4431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jun 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Application from 'shared';
import config from 'config';
import express from 'express';
import fetch from 'isomorphic-fetch';
import { logger } from 'topcoder-react-lib';
import { logger, services } from 'topcoder-react-lib';
import fs from 'fs';
import moment from 'moment';
import path from 'path';
Expand Down Expand Up @@ -160,19 +160,21 @@ async function onExpressJsSetup(server) {

/* Proxy endpoint for GET requests (to fetch data from resources prohibiting
* cross-origin requests). */
/* server.use(
server.use(
'/community-app-assets/api/proxy-get',
checkAuthorizationHeader, async (req, res, next) => {
const tokenM2M = await services.api.getTcM2mToken();
try {
let data = await fetch(req.query.url);
let data = await fetch(req.query.url, {
headers: { Authorization: `Bearer ${tokenM2M}` },
});
data = await data.text();
res.send(data);
} catch (err) {
next(err);
}
},
);
*/

/* Proxy endpoint for POST requests (to fetch data from resources prohibiting
* cross-origin requests). */
Expand Down
2 changes: 1 addition & 1 deletion src/server/sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ workbox.routing.registerRoute(/\/challenges(\/)?(\?.*)?$/, async ({ event, url }
}, 'GET');

// Serve challenge details pages like: /challenges/12345678
workbox.routing.registerRoute(/\/challenges\/\d+(\/)?(.*)/, async ({ event, url }) => {
workbox.routing.registerRoute(/\/challenges\/(([\w]{4,12}-?){5}|\d+)\/?(\?.*)?/, async ({ event, url }) => {
if (url.pathname.endsWith('/')) {
// Remove ending '/' char
url.pathname = url.pathname.substring(0, url.pathname.length - 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export default function ChallengeViewSelector(props) {
const {
challenge,
checkpointCount,
numRegistrants,
numSubmissions,
numOfRegistrants,
numOfSubmissions,
numWinners,
onSelectorClicked,
selectedView,
Expand Down Expand Up @@ -86,7 +86,7 @@ export default function ChallengeViewSelector(props) {
DETAILS
</a>
{
numRegistrants ? (
numOfRegistrants ? (
<a
tabIndex="0"
role="tab"
Expand All @@ -100,7 +100,7 @@ export default function ChallengeViewSelector(props) {
styleName={getSelectorStyle(selectedView, DETAIL_TABS.REGISTRANTS)}
>
REGISTRANTS (
{numRegistrants}
{numOfRegistrants}
)
</a>
) : null
Expand All @@ -123,7 +123,7 @@ export default function ChallengeViewSelector(props) {
)
}
{
numSubmissions ? (
numOfSubmissions ? (
<a
tabIndex="0"
role="tab"
Expand All @@ -133,7 +133,7 @@ export default function ChallengeViewSelector(props) {
styleName={getSelectorStyle(selectedView, DETAIL_TABS.SUBMISSIONS)}
>
SUBMISSIONS (
{numSubmissions}
{numOfSubmissions}
)
</a>
) : null
Expand Down Expand Up @@ -188,8 +188,8 @@ export default function ChallengeViewSelector(props) {
ChallengeViewSelector.defaultProps = {
challenge: {},
checkpointCount: 0,
numRegistrants: 0,
numSubmissions: 0,
numOfRegistrants: 0,
numOfSubmissions: 0,
// hasRegistered: false,
};

Expand All @@ -204,8 +204,8 @@ ChallengeViewSelector.propTypes = {
}),
}),
checkpointCount: PT.number,
numRegistrants: PT.number,
numSubmissions: PT.number,
numOfRegistrants: PT.number,
numOfSubmissions: PT.number,
numWinners: PT.number.isRequired,
onSelectorClicked: PT.func.isRequired,
selectedView: PT.string.isRequired,
Expand Down
12 changes: 6 additions & 6 deletions src/shared/components/challenge-detail/Header/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export default function ChallengeHeader(props) {
prizeSets,
reliabilityBonus,
userDetails,
numRegistrants,
numSubmissions,
numOfRegistrants,
numOfSubmissions,
appealsEndDate,
} = challenge;

Expand Down Expand Up @@ -451,10 +451,10 @@ export default function ChallengeHeader(props) {
onSelectorClicked={onSelectorClicked}
trackLower={trackLower}
selectedView={selectedView}
numRegistrants={numRegistrants}
numOfRegistrants={numOfRegistrants}
numWinners={numWinners}
hasCheckpoints={checkpoints && checkpoints.length > 0}
numSubmissions={numSubmissions}
numOfSubmissions={numOfSubmissions}
hasRegistered={hasRegistered}
checkpointCount={checkpointCount}
mySubmissions={mySubmissions}
Expand Down Expand Up @@ -492,8 +492,8 @@ ChallengeHeader.propTypes = {
reliabilityBonus: PT.any,
userDetails: PT.any,
currentPhases: PT.any,
numRegistrants: PT.any,
numSubmissions: PT.any,
numOfRegistrants: PT.any,
numOfSubmissions: PT.any,
status: PT.any,
appealsEndDate: PT.any,
allPhases: PT.any,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default function ChallengesCard({
<TrackIcon
track={track}
subTrack={challenge.subTrack}
tcoEligible={challenge.events && challenge.events.length > 0 ? challenge.events[0].eventName : ''}
tcoEligible={!_.isEmpty(challenge.events) ? challenge.events[0].eventName : ''}
isDataScience={challenge.isDataScience}
challengesUrl={challengesUrl}
/>
Expand Down
46 changes: 26 additions & 20 deletions src/shared/components/challenge-detail/Registrants/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function formatDate(date) {
}

function getDate(arr, handle) {
const results = arr.filter(a => _.toString(a.submitter || a.handle) === _.toString(handle))
const results = arr.filter(a => _.toString(a.submitter || a.memberHandle) === _.toString(handle))
.sort((a, b) => new Date(b.submissionTime || b.submissionDate).getTime()
- new Date(a.submissionTime || a.submissionDate).getTime());
return results[0] ? (results[0].submissionTime || results[0].submissionDate) : '';
Expand All @@ -32,7 +32,7 @@ function passedCheckpoint(checkpoints, handle, results) {
}

function getPlace(results, handle, places) {
const found = _.find(results, w => _.toString(w.handle) === _.toString(handle)
const found = _.find(results, w => _.toString(w.memberHandle) === _.toString(handle)
&& w.placement <= places && w.submissionStatus !== 'Failed Review');

if (found) {
Expand Down Expand Up @@ -99,7 +99,7 @@ export default class Registrants extends React.Component {

let checkpoint;
if (twoRounds) {
checkpoint = getDate(checkpoints, registrant.handle);
checkpoint = getDate(checkpoints, registrant.memberHandle);
if (!checkpoint
&& moment(registrant.submissionDate).isBefore(checkpointDate)) {
checkpoint = registrant.submissionDate;
Expand Down Expand Up @@ -188,8 +188,8 @@ export default class Registrants extends React.Component {
break;
}
case 'Username': {
valueA = `${a.handle}`.toLowerCase();
valueB = `${b.handle}`.toLowerCase();
valueA = `${a.memberHandle}`.toLowerCase();
valueB = `${b.memberHandle}`.toLowerCase();
valueIsString = true;
break;
}
Expand Down Expand Up @@ -239,22 +239,22 @@ export default class Registrants extends React.Component {
onSortChange,
} = this.props;
const {
prizes,
prizeSets,
legacy,
} = challenge;
const { track } = legacy;
const { sortedRegistrants } = this.state;
const { field, sort } = this.getRegistrantsSortParam();
const revertSort = (sort === 'desc') ? 'asc' : 'desc';
const isDesign = track.toLowerCase() === 'design';
const isF2F = challenge.subTrack.indexOf('FIRST_2_FINISH') > -1;
const isBugHunt = challenge.subTrack.indexOf('BUG_HUNT') > -1;
const isF2F = challenge.type.toLowerCase().indexOf('first2finish') > -1;
const isBugHunt = challenge.type.toLowerCase() === 'bug hunt';

const checkpoints = challenge.checkpoints || [];

const twoRounds = challenge.round1Introduction
&& challenge.round2Introduction;
const places = prizes.length;
const places = prizeSets.find(ps => ps.type === 'placement').prizes.lenght;
return (
<div styleName={`container ${twoRounds ? 'design' : ''}`} role="table" aria-label="Registrants">
<div styleName="head" role="row">
Expand Down Expand Up @@ -379,8 +379,14 @@ export default class Registrants extends React.Component {
<div styleName="body" role="rowgroup">
{
sortedRegistrants.map((r) => {
const placement = getPlace(results, r.handle, places);
const colorStyle = JSON.parse(r.colorStyle.replace(/(\w+):\s*([^;]*)/g, '{"$1": "$2"}'));
const placement = getPlace(results, r.memberHandle, places);
/*
* TODO: Need check as get this back, currenlty V5 API missing this data
* = JSON.parse(r.colorStyle.replace(/(\w+):\s*([^;]*)/g, '{"$1": "$2"}'));
*/
const colorStyle = {
color: '#000000',
};
let checkpoint = this.getCheckPoint(r);
if (checkpoint) {
checkpoint = formatDate(checkpoint);
Expand All @@ -393,7 +399,7 @@ export default class Registrants extends React.Component {
}

return (
<div styleName="row" key={r.handle} role="row">
<div styleName="row" key={r.memberHandle} role="row">
{
!isDesign && !isF2F && !isBugHunt && (
<div styleName="col-2">
Expand All @@ -411,19 +417,19 @@ export default class Registrants extends React.Component {
<div styleName="col-3">
<span role="cell">
<a
href={`${window.origin}/members/${r.handle}`}
href={`${window.origin}/members/${r.memberHandle}`}
style={colorStyle}
target={`${_.includes(window.origin, 'www') ? '_self' : '_blank'}`}
>
{r.handle}
{r.memberHandle}
</a>
</span>
</div>
<div styleName="col-4">
<div styleName="sm-only title">
Registration Date
</div>
<span role="cell">{formatDate(r.registrationDate)}</span>
<span role="cell">{formatDate(r.created)}</span>
</div>
{
twoRounds
Expand All @@ -437,7 +443,7 @@ export default class Registrants extends React.Component {
{checkpoint}
</span>
{
passedCheckpoint(checkpoints, r.handle, checkpointResults)
passedCheckpoint(checkpoints, r.memberHandle, checkpointResults)
&& <CheckMark styleName="passed" />
}
</div>
Expand Down Expand Up @@ -482,16 +488,16 @@ Registrants.propTypes = {
challenge: PT.shape({
phases: PT.arrayOf(PT.shape({
actualEndDate: PT.string,
phaseType: PT.string.isRequired,
name: PT.string.isRequired,
scheduledEndDate: PT.string,
})).isRequired,
allPhases: PT.arrayOf(PT.shape()),
checkpoints: PT.arrayOf(PT.shape()),
legacy: PT.shape({
track: PT.any,
track: PT.string,
}),
subTrack: PT.any,
prizes: PT.arrayOf(PT.number).isRequired,
type: PT.string,
prizeSets: PT.arrayOf(PT.shape()).isRequired,
registrants: PT.arrayOf(PT.shape()).isRequired,
round1Introduction: PT.string,
round2Introduction: PT.string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function SideBar({
const faqURL = config.URL.INFO.DESIGN_CHALLENGE_SUBMISSION;
let submissionLimitDisplay = 'Unlimited';
const submissionLimit = _.find(metadata, { type: 'submissionLimit' });
const fileTypes = _.find(metadata, { type: 'fileTypes' });
const fileTypes = _.find(metadata, { name: 'fileTypes' });

if (submissionLimit) {
if (submissionLimit.value === 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,8 @@ class SubmissionsComponent extends React.Component {
</div>
);

const isF2F = challenge.subTrack.indexOf('FIRST_2_FINISH') > -1;
const isBugHunt = challenge.subTrack.indexOf('BUG_HUNT') > -1;
const isF2F = challenge.type.toLowerCase().indexOf('first2finish') > -1;
const isBugHunt = challenge.type.toLowerCase() === 'bug hunt';

// copy colorStyle from registrants to submissions
_.forEach(sortedSubmissions, (s) => {
Expand Down Expand Up @@ -785,7 +785,7 @@ SubmissionsComponent.propTypes = {
registrants: PT.any,
allPhases: PT.any,
phases: PT.any,
subTrack: PT.any,
type: PT.any,
}).isRequired,
toggleSubmissionHistory: PT.func.isRequired,
submissionHistoryOpen: PT.shape({}).isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function ChallengeCard({
<TrackIcon
track={track}
subTrack={subTrack}
tcoEligible={challenge.events && challenge.events.length > 0 ? challenge.events[0].eventName : ''}
tcoEligible={!_.isEmpty(challenge.events) ? challenge.events[0].eventName : ''}
isDataScience={challenge.isDataScience}
/>
</span>
Expand Down
7 changes: 4 additions & 3 deletions src/shared/containers/challenge-detail/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ function isRegistered(details, registrants, handle) {
if (details && details.roles && details.roles.includes('Submitter')) {
return true;
}
if (_.find(registrants, r => _.toString(r.handle) === _.toString(handle))) {
if (_.find(registrants, r => _.toString(r.memberHandle) === _.toString(handle))) {
return true;
}
return false;
Expand Down Expand Up @@ -231,6 +231,7 @@ class ChallengeDetailPageContainer extends React.Component {
challenge
&& challenge.id === challengeId
&& !loadingRecommendedChallengesUUID
&& recommendedTechnology
&& (
!recommendedChallenges[recommendedTechnology]
|| (
Expand Down Expand Up @@ -731,15 +732,15 @@ function mapStateToProps(state, props) {
if (challenge.submissions) {
challenge.submissions = challenge.submissions.map(submission => ({
...submission,
registrant: _.find(challenge.registrants, { handle: submission.submitter }),
registrant: _.find(challenge.registrants, { memberHandle: submission.createdBy }),
}));
}

if (mmSubmissions) {
mmSubmissions = mmSubmissions.map((submission) => {
let registrant;
let { member } = submission;
if (auth.user.handle === submission.member) {
if (auth.user.handle === submission.memberHandle) {
mySubmissions = submission.submissions || [];
mySubmissions = mySubmissions.map((mySubmission, index) => {
// eslint-disable-next-line no-param-reassign
Expand Down
Loading