Skip to content

Commit

Permalink
Merge pull request #6380 from topcoder-platform/develop
Browse files Browse the repository at this point in the history
Release v1.17.3
  • Loading branch information
luizrrodrigues authored Jun 15, 2022
2 parents ed864e3 + a4123f9 commit 2904f64
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 53 deletions.
7 changes: 3 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -349,14 +349,14 @@ workflows:
filters:
branches:
only:
- reskin
- develop
# This is alternate dev env for parallel testing
- "build-test":
context : org-global
filters:
branches:
only:
- circleci-fix
- debug-CMS-error
# This is alternate dev env for parallel testing
- "build-qa":
context : org-global
Expand All @@ -370,7 +370,6 @@ workflows:
filters:
branches:
only:
- footer-update
- reskin
# This is stage env for production QA releases
- "build-prod-staging":
Expand All @@ -379,7 +378,7 @@ workflows:
branches:
only:
- develop
- stat_marathon_match_link
- fix-security-headers
# Production builds are exectuted
# when PR is merged to the master
# Don't change anything in this configuration
Expand Down
11 changes: 9 additions & 2 deletions src/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ ts = moment(ts.timestamp).valueOf();
const sw = `sw.js${process.env.NODE_ENV === 'production' ? '' : '?debug'}`;
const swScope = '/challenges'; // we are currently only interested in improving challenges pages

const tcoPattern = new RegExp(/^tco\d{2}\.topcoder(?:-dev)?\.com$/i);

const EXTRA_SCRIPTS = [
`<script type="application/javascript">
if('serviceWorker' in navigator){
Expand Down Expand Up @@ -135,13 +137,14 @@ async function onExpressJsSetup(server) {
res.header('Referrer-Policy', 'strict-origin-when-cross-origin');
res.header('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');

if (req.url.startsWith('/__community__/veterans') || req.hostname === 'veterans.topcoder.com') {
if (req.url.startsWith('/__community__/veterans') || req.hostname === 'veterans.topcoder.com' || req.url.startsWith('/__community__/tco') || tcoPattern.test(req.hostname)) {
res.header(
'Content-Security-Policy',
"default-src 'self';"
+ " script-src 'report-sample' 'self' 'unsafe-inline' 'unsafe-eval'"
+ ` ${config.CDN.PUBLIC}`
+ ' http://www.google-analytics.com'
+ ' https://www.google-analytics.com'
+ ' https://43d132d5dbff47c59d9d53ad448f93c2.js.ubembed.com'
+ ' https://assets.ubembed.com'
+ ' https://assets.zendesk.com'
Expand Down Expand Up @@ -187,6 +190,7 @@ async function onExpressJsSetup(server) {
+ ` ${config.URL.AUTH}`
+ ' https://www.youtube.com;'
+ " img-src 'self'"
+ ' data:'
+ ` ${config.CDN.PUBLIC}`
+ ' https://cdn.segment.com'
+ ' https://d1of0acg2orgco.cloudfront.net'
Expand All @@ -196,11 +200,14 @@ async function onExpressJsSetup(server) {
+ ' https://heapanalytics.com'
+ ' https://q.quora.com'
+ ' https://topcoder-prod-media.s3.amazonaws.com'
+ ' https://topcoder-dev-media.s3.amazonaws.com'
+ ' https://www.facebook.com'
+ ' https://www.google-analytics.com'
+ ' https://www.google.com'
+ ' https://www.googletagmanager.com'
+ ' https://i.ytimg.com;'
+ ' https://i.ytimg.com'
+ ' https://images.contentful.com'
+ ' https://d0.awsstatic.com/logos/;'
+ " manifest-src 'self';"
+ " media-src 'self';"
+ ' report-uri https://623d4c23f90d055298b24042.endpoint.csper.io/?v=0;'
Expand Down
46 changes: 27 additions & 19 deletions src/shared/actions/contentful.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getService } from 'services/contentful';
import { config, redux } from 'topcoder-react-utils';
import { removeTrailingSlash } from 'utils/url';
import { menuItemBuilder, target as urlTarget } from 'utils/contentful';
import { services } from 'topcoder-react-lib';
import { services, logger } from 'topcoder-react-lib';

const ERRMSG_UNKNOWN_TARGET = 'Unknown action target';

Expand Down Expand Up @@ -91,15 +91,19 @@ async function getContentDone(operationId, contentId, target, preview, spaceName
environment,
});
let content;
switch (target) {
case TARGETS.ASSETS:
content = await service.getAsset(contentId);
break;
case TARGETS.ENTRIES:
content = await service.getEntry(contentId);
break;
default:
throw new Error(ERRMSG_UNKNOWN_TARGET);
try {
switch (target) {
case TARGETS.ASSETS:
content = await service.getAsset(contentId);
break;
case TARGETS.ENTRIES:
content = await service.getEntry(contentId);
break;
default:
throw new Error(ERRMSG_UNKNOWN_TARGET);
}
} catch (e) {
logger.error('getContentDone error', e);
}

return {
Expand Down Expand Up @@ -141,15 +145,19 @@ async function queryContentDone(operationId, queryId, target,
environment,
});
let data;
switch (target) {
case TARGETS.ASSETS:
data = await service.queryAssets(query);
break;
case TARGETS.ENTRIES:
data = await service.queryEntries(query);
break;
default:
throw new Error(ERRMSG_UNKNOWN_TARGET);
try {
switch (target) {
case TARGETS.ASSETS:
data = await service.queryAssets(query);
break;
case TARGETS.ENTRIES:
data = await service.queryEntries(query);
break;
default:
throw new Error(ERRMSG_UNKNOWN_TARGET);
}
} catch (e) {
logger.error('queryContentDone error', e);
}

return {
Expand Down
2 changes: 1 addition & 1 deletion src/shared/components/Contentful/Route.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function ChildRoutesLoader(props) {
<React.Fragment>
<MetaTags
description={fields.description}
image={fields.thumbnail}
image={fields.socialThumbnail}
siteName={fields.socialSiteName}
socialDescription={fields.socialDescription}
socialTitle={fields.socialTitle}
Expand Down
5 changes: 4 additions & 1 deletion src/shared/components/MetaTags.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ function MetaTags({
feed,
feedTitle,
}) {
const img = `${domain}${image}`;
let img = `${domain}${image}`;
if (image && (image.indexOf('http://') === 0 || image.indexOf('https://') === 0)) {
img = `${image}`;
}
const socTitle = socialTitle || title;
const socDesc = socialDescription || description;
return (
Expand Down
97 changes: 73 additions & 24 deletions src/shared/components/challenge-detail/MMDashboard/Graph/index.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
/* eslint-disable react/no-this-in-sfc */
import React from 'react';
import React, { useState } from 'react';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
import PT from 'prop-types';
import moment from 'moment';
import { getRatingColor } from 'utils/tc';
import { getHighlightedColor, getRatingColor, getUnSelectedColors } from 'utils/tc';
import DefaultUserImage from 'assets/images/ico-user-default.png';

import './styles.scss';
import _ from 'lodash';
import styles from './styles.scss';

export default function Graph({ statisticsData, baseline, awardLine }) {
const [point, setPoint] = useState(null);

const flatData = [];
const dates = [];
_.each(statisticsData, (entry) => {
Expand All @@ -24,28 +26,71 @@ export default function Graph({ statisticsData, baseline, awardLine }) {
});
});

const pointDatas = _.map(flatData, (data) => {
let color;
let isSelected = false;
if (point) {
isSelected = point.customData.handle === data.handle;
if (isSelected) {
color = getHighlightedColor(data.rating || 0);
} else {
color = getUnSelectedColors(data.rating || 0);
}
} else {
color = data.ratingColor || getRatingColor(data.rating || 0);
}
return {
x: moment(data.created).valueOf(),
y: _.max([0, data.score ? (parseFloat(data.score)) : 0]),
name: data.handle,
color,
customData: data,
marker: {
enabled: true,
width: 'circle',
radius: isSelected ? 6 : 4,
},
className: !isSelected && point ? styles.selectedPoint : '',
};
});

const options = {
plotOptions: {
line: {
events: {
click() {
this.group.toFront();
},
},
},
},
chart: {
type: 'scatter',
backgroundColor: '#fff',
events: {
click: () => {
setPoint(null);
},
},
},
title: {
text: '',
},
series: [
{
data: _.map(flatData, data => ({
x: moment(data.created).valueOf(),
y: _.max([0, data.score ? (parseFloat(data.score)) : 0]),
name: data.handle,
color: data.ratingColor
|| getRatingColor(data.rating
|| 0),
customData: data,
})),
data: pointDatas,
pointStart: moment(_.min(dates)).valueOf(),
pointInterval: 24 * 3600 * 1000,
backgroundColor: 'rgb(51,51,51)',
point: {
events: {
click: (e) => {
if (e && e.point) {
setPoint(e.point);
}
},
},
},
},
],
legend: {
Expand Down Expand Up @@ -106,23 +151,27 @@ export default function Graph({ statisticsData, baseline, awardLine }) {
},
tooltip: {
formatter() {
const str = `
<div style="border-radius:4px; padding-top: 15px; padding-left: 10px;">
<img height="30" width="30" src="${this.point.customData.photoUrl || DefaultUserImage}" style="position: absolute; border-radius: 50%;" />
<p style="margin-left: 50px">${this.point.customData.handle}</p>
<br />
<p style="margin-left: 50px;">${this.point.customData.submissionCount} submissions</p>
<p style="margin-left: 50px;">Score: ${this.y}</p>
<p style="margin-left: 50px;">Submitted: ${moment(this.point.customData.created).format('MM/DD/YYYY')} </p>
</div>
`;
return str;
const currentPointer = this.point || point;
if (currentPointer) {
const str = `
<div style="border-radius:4px; padding-top: 15px; padding-left: 10px;">
<img height="30" width="30" src="${currentPointer.customData.photoUrl || DefaultUserImage}" style="position: absolute; border-radius: 50%;" />
<p style="margin-left: 50px">${currentPointer.customData.handle}</p>
<br />
<p style="margin-left: 50px;">${currentPointer.customData.submissionCount} submissions</p>
<p style="margin-left: 50px;">Score: ${this.y}</p>
<p style="margin-left: 50px;">Submitted: ${moment(currentPointer.customData.created).format('MM/DD/YYYY')} </p>
</div>
`;
return str;
}
return false;
},
useHTML: true,
style: {
color: '#fff',
},
backgroundColor: 'rgb(51,51,51)',
backgroundColor: point ? '#2e2e2e' : 'rgb(51,51,51)',
shared: true,
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,8 @@
padding-right: 16px;
}
}

.selectedPoint {
z-index: 1000 !important;
opacity: 0.9;
}
4 changes: 2 additions & 2 deletions src/shared/reducers/contentful/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ function create(init) {
const spaceName = _.get(payload, 'spaceName') || config.CONTENTFUL.DEFAULT_SPACE_NAME;
const environment = _.get(payload, 'environment') || config.CONTENTFUL.DEFAULT_ENVIRONMENT;
const res = _.get(newState, `${spaceName}.${environment}`);
if (error || !res) {
logger.log('CMS-related error');
if ((error && payload && payload.sys && payload.sys.id !== 'NotFound') || !res) {
logger.log('CMS-related error', JSON.stringify(action), config.CONTENTFUL.DEFAULT_SPACE_NAME, config.CONTENTFUL.DEFAULT_ENVIRONMENT, JSON.stringify(res), JSON.stringify(newState));
return state;
}
const st = state[spaceName][environment];
Expand Down
45 changes: 45 additions & 0 deletions src/shared/utils/tc.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,57 @@ export const RATING_COLORS = [{
color: '#EF3A3A' /* Red */,
limit: Infinity,
}];

export function getRatingColor(rating) {
let i = 0; const r = Number(rating);
while (RATING_COLORS[i].limit <= r) i += 1;
return RATING_COLORS[i].color || 'black';
}

export const HIGHLIGHTED_RATING_COLORS = [{
color: '#464646' /* Grey */,
limit: 900,
}, {
color: '#00ab00' /* Green */,
limit: 1200,
}, {
color: '#3748ff' /* Blue */,
limit: 1500,
}, {
color: '#ffe879' /* Yellow */,
limit: 2200,
}, {
color: '#ff2a2a' /* Red */,
limit: Infinity,
}];
export function getHighlightedColor(rating) {
let i = 0; const r = Number(rating);
while (HIGHLIGHTED_RATING_COLORS[i].limit <= r) i += 1;
return HIGHLIGHTED_RATING_COLORS[i].color || 'black';
}

export const UNSELECTED_RATING_COLORS = [{
color: '#f3f3f3' /* Grey */,
limit: 900,
}, {
color: '#e6f6e6' /* Green */,
limit: 1200,
}, {
color: '#c5c8ef' /* Blue */,
limit: 1500,
}, {
color: '#fff5c4' /* Yellow */,
limit: 2200,
}, {
color: '#f47d7d' /* Red */,
limit: Infinity,
}];
export function getUnSelectedColors(rating) {
let i = 0; const r = Number(rating);
while (UNSELECTED_RATING_COLORS[i].limit <= r) i += 1;
return UNSELECTED_RATING_COLORS[i].color || 'black';
}

/**
* Given ExpressJS HTTP request it extracts Topcoder auth tokens from cookies,
* if they are present there and are not expired.
Expand Down

0 comments on commit 2904f64

Please sign in to comment.