diff --git a/src/components/ChallengeEditor/ChallengeView/index.js b/src/components/ChallengeEditor/ChallengeView/index.js index b8d1d266..b34550c9 100644 --- a/src/components/ChallengeEditor/ChallengeView/index.js +++ b/src/components/ChallengeEditor/ChallengeView/index.js @@ -21,6 +21,7 @@ import PhaseInput from '../../PhaseInput' import LegacyLinks from '../../LegacyLinks' import AssignedMemberField from '../AssignedMember-Field' import { getResourceRoleByName } from '../../../util/tc' +import { isBetaMode } from '../../../util/cookie' import { loadGroupDetails } from '../../../actions/challenges' import Tooltip from '../../Tooltip' import { MESSAGE, REVIEW_TYPES } from '../../../config/constants' @@ -37,7 +38,8 @@ const ChallengeView = ({ assignedMemberDetails, enableEdit, onLaunchChallenge, - onCloseTask }) => { + onCloseTask +}) => { const selectedType = _.find(metadata.challengeTypes, { id: challenge.typeId }) const challengeTrack = _.find(metadata.challengeTracks, { id: challenge.trackId }) @@ -148,7 +150,6 @@ const ChallengeView = ({ Challenge Name: {challenge.name} - {isTask && } - {openAdvanceSettings && (
-
- Groups: {groups} -
-
)} + {openAdvanceSettings && ( + <> + +
+
+ Groups: {groups} +
+
+ {isBetaMode() && ( +
+
+ + Billing Account Id: + {projectDetail.billingAccountId} + +
+
+ )} + + )} {
{ const isRequiredNda = challenge.terms && _.some(challenge.terms, { id: DEFAULT_NDA_UUID }) + + if (readOnly) { + return ( +
+
NDA Required :
+
+ { isRequiredNda ? 'Yes' : 'No' } +
+
+ ) + } + return (
-
- - +
NDA Required :
+
+
+ + +
+
+ + +
) diff --git a/src/components/ChallengeEditor/index.js b/src/components/ChallengeEditor/index.js index 9dca0d00..b08a5bfa 100644 --- a/src/components/ChallengeEditor/index.js +++ b/src/components/ChallengeEditor/index.js @@ -50,6 +50,7 @@ import LegacyLinks from '../LegacyLinks' import AssignedMemberField from './AssignedMember-Field' import Tooltip from '../Tooltip' import { getResourceRoleByName } from '../../util/tc' +import { isBetaMode } from '../../util/cookie' const theme = { container: styles.modalContainer @@ -195,7 +196,8 @@ class ChallengeEditor extends Component { challengeData.copilot = copilot || copilotFromResources challengeData.reviewer = reviewer || reviewerFromResources const challengeDetail = { ...challengeData } - const isOpenAdvanceSettings = challengeDetail.groups.length > 0 + const isRequiredNda = challengeDetail.terms && _.some(challengeDetail.terms, { id: DEFAULT_NDA_UUID }) + const isOpenAdvanceSettings = challengeDetail.groups.length > 0 || isRequiredNda setState({ challenge: challengeDetail, assignedMemberDetails, @@ -809,7 +811,7 @@ class ChallengeEditor extends Component { async createNewChallenge () { if (!this.props.isNew) return - const { metadata, createChallenge } = this.props + const { metadata, createChallenge, projectDetail } = this.props const { name, trackId, typeId } = this.state.challenge const { timelineTemplates } = metadata const isDesignChallenge = trackId === DES_TRACK_ID @@ -838,6 +840,14 @@ class ChallengeEditor extends Component { terms: [{ id: DEFAULT_TERM_UUID, roleId: SUBMITTER_ROLE_UUID }] // prizeSets: this.getDefaultPrizeSets() } + if (isBetaMode() && projectDetail.terms) { + const currTerms = new Set(newChallenge.terms.map(term => term.id)) + newChallenge.terms.push( + ...projectDetail.terms + .filter(term => !currTerms.has(term)) + .map(term => ({ id: term, roleId: SUBMITTER_ROLE_UUID })) + ) + } const discussions = this.getDiscussionsConfig(newChallenge) if (discussions) { newChallenge.discussions = discussions @@ -1359,7 +1369,6 @@ class ChallengeEditor extends Component {
- {isTask && ( { isOpenAdvanceSettings && ( + {/* remove terms field and use default term */} {false && ()} + {isBetaMode() && ( +
+
+ + Billing Account Id: + {projectDetail.billingAccountId} + +
+
+ )}
)} {!isTask && ( diff --git a/src/components/Sidebar/Sidebar.module.scss b/src/components/Sidebar/Sidebar.module.scss index 4a53d4d2..72c29e64 100644 --- a/src/components/Sidebar/Sidebar.module.scss +++ b/src/components/Sidebar/Sidebar.module.scss @@ -25,6 +25,15 @@ color: $white; margin-bottom: 37px; padding-left: 30px; + + .beta { + font-size: 16px; + color: $red; + font-weight: bold; + position: relative; + top: -12px; + left: 12px; + } } .homeLink { diff --git a/src/components/Sidebar/index.js b/src/components/Sidebar/index.js index cd38bb9a..023f7fef 100644 --- a/src/components/Sidebar/index.js +++ b/src/components/Sidebar/index.js @@ -8,13 +8,18 @@ import cn from 'classnames' import TopcoderLogo from '../../assets/images/topcoder-logo.png' import styles from './Sidebar.module.scss' +import { isBetaMode } from '../../util/cookie' + const Sidebar = ({ projectId, resetSidebarActiveParams }) => { return (
-
Work Manager
+
+ Work Manager + {isBetaMode() && beta} +
All Work diff --git a/src/config/constants.js b/src/config/constants.js index e8eab683..9cafe92f 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -113,6 +113,8 @@ export const SET_FILTER_CHALLENGE_VALUE = 'SET_FILTER_CHALLENGE_VALUE' export const RESET_SIDEBAR_ACTIVE_PARAMS = 'RESET_SIDEBAR_ACTIVE_PARAMS' +export const BETA_MODE_COOKIE_TAG = 'beta-mode' + // Name of challenge tracks export const CHALLENGE_TRACKS = { DESIGN: DES_TRACK_ID, diff --git a/src/containers/ChallengeEditor/index.js b/src/containers/ChallengeEditor/index.js index 51ffaa26..910c2f01 100644 --- a/src/containers/ChallengeEditor/index.js +++ b/src/containers/ChallengeEditor/index.js @@ -30,6 +30,8 @@ import { replaceResourceInRole } from '../../actions/challenges' +import { loadProject } from '../../actions/projects' + import { connect } from 'react-redux' import { SUBMITTER_ROLE_UUID, MESSAGE } from '../../config/constants' import { patchChallenge } from '../../services/challenges' @@ -59,6 +61,7 @@ class ChallengeEditor extends Component { this.closeSuccessModal = this.closeSuccessModal.bind(this) this.onCloseTask = this.onCloseTask.bind(this) this.closeTask = this.closeTask.bind(this) + this.fetchProjectDetails = this.fetchProjectDetails.bind(this) } componentDidMount () { @@ -86,7 +89,6 @@ class ChallengeEditor extends Component { loadGroups() loadResourceRoles() this.fetchChallengeDetails(match, loadChallengeDetails, loadResources) - // this.unlisten = this.props.history.listen(() => { // const { isLoading } = this.props // if (!isLoading) { @@ -112,12 +114,23 @@ class ChallengeEditor extends Component { } } + async fetchProjectDetails (newMatch) { + let projectId = _.get(newMatch.params, 'projectId', null) + projectId = projectId ? parseInt(projectId) : null + if (projectId) { + await this.props.loadProject(projectId) + } + } + async fetchChallengeDetails (newMatch, loadChallengeDetails, loadResources) { let projectId = _.get(newMatch.params, 'projectId', null) projectId = projectId ? parseInt(projectId) : null const challengeId = _.get(newMatch.params, 'challengeId', null) await loadResources(challengeId) loadChallengeDetails(projectId, challengeId) + if (!challengeId) { + this.fetchProjectDetails(newMatch) + } } isEditable () { @@ -413,7 +426,8 @@ ChallengeEditor.propTypes = { partiallyUpdateChallengeDetails: PropTypes.func.isRequired, createChallenge: PropTypes.func.isRequired, deleteChallenge: PropTypes.func.isRequired, - replaceResourceInRole: PropTypes.func + replaceResourceInRole: PropTypes.func, + loadProject: PropTypes.func // members: PropTypes.arrayOf(PropTypes.shape()) } @@ -450,7 +464,8 @@ const mapDispatchToProps = { partiallyUpdateChallengeDetails, deleteChallenge, createChallenge, - replaceResourceInRole + replaceResourceInRole, + loadProject } export default withRouter(connect(mapStateToProps, mapDispatchToProps)(ChallengeEditor)) diff --git a/src/routes.js b/src/routes.js index 2dad9624..70708384 100644 --- a/src/routes.js +++ b/src/routes.js @@ -5,6 +5,7 @@ import React from 'react' import PropTypes from 'prop-types' import { Redirect, Route, Switch, withRouter } from 'react-router-dom' import _ from 'lodash' +import { BETA_MODE_COOKIE_TAG } from './config/constants' import renderApp from './components/App' import TopBarContainer from './containers/TopbarContainer' import Sidebar from './containers/Sidebar' @@ -15,6 +16,7 @@ import { saveToken } from './actions/auth' import { loadChallengeDetails } from './actions/challenges' import { connect } from 'react-redux' import { checkAllowedRoles } from './util/tc' +import { setCookie, removeCookie, isBetaMode } from './util/cookie' const { ACCOUNTS_APP_LOGIN_URL } = process.env @@ -72,6 +74,19 @@ class Routes extends React.Component { }) } + componentDidUpdate () { + const { search } = this.props.location + const params = new URLSearchParams(search) + if (!_.isEmpty(params.get('beta'))) { + if (params.get('beta') === 'true' && !isBetaMode()) { + setCookie(BETA_MODE_COOKIE_TAG, 'true') + } else if (params.get('beta') === 'false' && isBetaMode()) { + removeCookie(BETA_MODE_COOKIE_TAG) + } + this.props.history.push(this.props.location.pathname) + } + } + render () { if (!this.props.isLoggedIn) { return null @@ -143,7 +158,8 @@ Routes.propTypes = { saveToken: PropTypes.func, location: PropTypes.object, isLoggedIn: PropTypes.bool, - token: PropTypes.string + token: PropTypes.string, + history: PropTypes.object } export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Routes)) diff --git a/src/util/cookie.js b/src/util/cookie.js new file mode 100644 index 00000000..b1242acb --- /dev/null +++ b/src/util/cookie.js @@ -0,0 +1,34 @@ +/** + * Provides Cookie related utility methods + */ + +import { BETA_MODE_COOKIE_TAG } from '../config/constants' + +/** + * A function that get's a cookie + */ +export function getCookie (name) { + const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)') + return v ? v[2] : undefined +} + +/** + * A function that set's a cookie + */ +export function setCookie (name, value) { + document.cookie = `${name}=${value}; path=/` +} + +/** + * A function that removes Cookie by setting expiry date to past + */ +export function removeCookie (name) { + document.cookie = `${name}=; path=/; expires=Thu, 18 Dec 2013 12:00:00 UTC;` +} + +/** + * A function that checks whether beta mode is enabled or not + */ +export function isBetaMode () { + return getCookie(BETA_MODE_COOKIE_TAG) +}