Skip to content

Commit

Permalink
Merge pull request #1423 from topcoder-platform/Oct_2022_Release
Browse files Browse the repository at this point in the history
Oct 2022 release
  • Loading branch information
jmgasper authored Oct 11, 2022
2 parents e695f7d + 0be5404 commit 68a32ee
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ workflows:
context : org-global
filters: &filters-dev
branches:
only: ['develop']
only: ['develop', 'Oct_2022_Release']

# Production builds are exectuted only on tagged commits to the
# master branch.
Expand Down
3 changes: 2 additions & 1 deletion config/constants/development.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module.exports = {
ACCOUNTS_APP_CONNECTOR_URL: `https://accounts-auth0.${DOMAIN}`,
ACCOUNTS_APP_LOGIN_URL: `https://accounts-auth0.${DOMAIN}`,
COMMUNITY_APP_URL: `https://www.${DOMAIN}`,
MEMBER_API_URL: `${DEV_API_HOSTNAME}/v4/members`,
MEMBER_API_URL: `${DEV_API_HOSTNAME}/v5/members`,
MEMBER_API_V3_URL: `${DEV_API_HOSTNAME}/v3/members`,
CHALLENGE_API_URL: `${DEV_API_HOSTNAME}/v5/challenges`,
CHALLENGE_TIMELINE_TEMPLATES_URL: `${DEV_API_HOSTNAME}/v5/timeline-templates`,
Expand Down Expand Up @@ -34,6 +34,7 @@ module.exports = {
DS_TRACK_ID: 'c0f5d461-8219-4c14-878a-c3a3f356466d',
QA_TRACK_ID: '36e6a8d0-7e1e-4608-a673-64279d99c115',
CHALLENGE_TYPE_ID: '927abff4-7af9-4145-8ba1-577c16e64e2e',
MARATHON_TYPE_ID: '929bc408-9cf2-4b3e-ba71-adfbf693046c',
SEGMENT_API_KEY: 'QBtLgV8vCiuRX1lDikbMjcoe9aCHkF6n',
CREATE_FORUM_TYPE_IDS: ['927abff4-7af9-4145-8ba1-577c16e64e2e', 'dc876fa4-ef2d-4eee-b701-b555fcc6544c', 'ecd58c69-238f-43a4-a4bb-d172719b9f31'],
FILE_PICKER_API_KEY: process.env.FILE_PICKER_API_KEY,
Expand Down
3 changes: 2 additions & 1 deletion config/constants/production.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module.exports = {
ACCOUNTS_APP_CONNECTOR_URL: process.env.ACCOUNTS_APP_CONNECTOR_URL || `https://accounts-auth0.${DOMAIN}`,
ACCOUNTS_APP_LOGIN_URL: `https://accounts-auth0.${DOMAIN}`,
COMMUNITY_APP_URL: `https://www.${DOMAIN}`,
MEMBER_API_URL: `${PROD_API_HOSTNAME}/v4/members`,
MEMBER_API_URL: `${PROD_API_HOSTNAME}/v5/members`,
MEMBER_API_V3_URL: `${PROD_API_HOSTNAME}/v3/members`,
CHALLENGE_API_URL: `${PROD_API_HOSTNAME}/v5/challenges`,
CHALLENGE_TIMELINE_TEMPLATES_URL: `${PROD_API_HOSTNAME}/v5/timeline-templates`,
Expand Down Expand Up @@ -34,6 +34,7 @@ module.exports = {
DS_TRACK_ID: 'c0f5d461-8219-4c14-878a-c3a3f356466d',
QA_TRACK_ID: '36e6a8d0-7e1e-4608-a673-64279d99c115',
CHALLENGE_TYPE_ID: '927abff4-7af9-4145-8ba1-577c16e64e2e',
MARATHON_TYPE_ID: '929bc408-9cf2-4b3e-ba71-adfbf693046c',
SEGMENT_API_KEY: 'QSQAW5BWmZfLoKFNRgNKaqHvLDLJoGqF',
CREATE_FORUM_TYPE_IDS: ['927abff4-7af9-4145-8ba1-577c16e64e2e', 'dc876fa4-ef2d-4eee-b701-b555fcc6544c', 'ecd58c69-238f-43a4-a4bb-d172719b9f31'],
FILE_PICKER_API_KEY: process.env.FILE_PICKER_API_KEY,
Expand Down
17 changes: 16 additions & 1 deletion src/components/ChallengeEditor/ChallengeView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ import AssignedMemberField from '../AssignedMember-Field'
import { getResourceRoleByName } from '../../../util/tc'
import { isBetaMode } from '../../../util/cookie'
import { loadGroupDetails } from '../../../actions/challenges'
import { REVIEW_TYPES, CONNECT_APP_URL, PHASE_PRODUCT_CHALLENGE_ID_FIELD } from '../../../config/constants'
import {
REVIEW_TYPES,
CONNECT_APP_URL,
PHASE_PRODUCT_CHALLENGE_ID_FIELD,
DS_TRACK_ID
} from '../../../config/constants'
import PhaseInput from '../../PhaseInput'

const ChallengeView = ({
Expand Down Expand Up @@ -91,6 +96,9 @@ const ChallengeView = ({
const showTimeline = false // disables the timeline for time being https://github.com/topcoder-platform/challenge-engine-ui/issues/706
const isTask = _.get(challenge, 'task.isTask', false)
const phases = _.get(challenge, 'phases', [])
const isDataScience = challenge.trackId === DS_TRACK_ID
const useDashboardData = _.find(challenge.metadata, { name: 'show_data_dashboard' })
const useDashboard = useDashboardData ? useDashboardData.value : true

return (
<div className={styles.wrapper}>
Expand Down Expand Up @@ -133,6 +141,13 @@ const ChallengeView = ({
<span><span className={styles.fieldTitle}>Challenge Name:</span> {challenge.name}</span>
</div>
</div>
{isDataScience && (
<div className={cn(styles.row, styles.topRow)}>
<div className={styles.col}>
<span><span className={styles.fieldTitle}>Show data dashboard:</span> {useDashboard ? 'Yes' : 'No'}</span>
</div>
</div>
)}
{isTask &&
<AssignedMemberField challenge={challenge} assignedMemberDetails={assignedMemberDetails} readOnly />}
<CopilotField challenge={{
Expand Down
1 change: 1 addition & 0 deletions src/components/ChallengeEditor/Type-Field/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import cn from 'classnames'
import styles from './Type-Field.module.scss'

const TypeField = ({ types, onUpdateSelect, challenge, disabled }) => {
types = _.sortBy(types, ['name'])
return (
<>
<div className={styles.row}>
Expand Down
79 changes: 69 additions & 10 deletions src/components/ChallengeEditor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ import {
MESSAGE,
COMMUNITY_APP_URL,
DES_TRACK_ID,
DEV_TRACK_ID,
CHALLENGE_TYPE_ID,
MARATHON_TYPE_ID,
REVIEW_TYPES,
MILESTONE_STATUS,
PHASE_PRODUCT_CHALLENGE_ID_FIELD,
QA_TRACK_ID
QA_TRACK_ID,
DS_TRACK_ID
} from '../../config/constants'
import { PrimaryButton, OutlineButton } from '../Buttons'
import TrackField from './Track-Field'
Expand Down Expand Up @@ -594,6 +597,8 @@ class ChallengeEditor extends Component {
submissionLimit.count = ''
}
existingMetadata.value = JSON.stringify(submissionLimit)
} else if (existingMetadata.name === 'show_data_dashboard') {
existingMetadata.value = Boolean(value)
} else {
existingMetadata.value = `${value}`
}
Expand Down Expand Up @@ -945,17 +950,14 @@ class ChallengeEditor extends Component {
async createNewChallenge () {
if (!this.props.isNew) return
const { metadata, createChallenge, projectDetail } = this.props
const { showDesignChallengeWarningModel, challenge: { name, trackId, typeId, milestoneId } } = this.state
const { challenge: { name, trackId, typeId, milestoneId, challengeType, metadata: challengeMetadata } } = this.state
const { timelineTemplates } = metadata
const isDesignChallenge = trackId === DES_TRACK_ID
const isDataScience = trackId === DS_TRACK_ID
const isChallengeType = typeId === CHALLENGE_TYPE_ID

if (!showDesignChallengeWarningModel && isDesignChallenge && isChallengeType) {
this.setState({
showDesignChallengeWarningModel: true
})
return
}
const isDevChallenge = trackId === DEV_TRACK_ID
const isMM = typeId === MARATHON_TYPE_ID
const showDashBoard = (isDataScience && isChallengeType) || (isDevChallenge && isMM)

// indicate that creating process has started
this.setState({ isSaving: true })
Expand All @@ -967,6 +969,10 @@ class ChallengeEditor extends Component {
const defaultTemplate = avlTemplates && avlTemplates.length > 0 ? avlTemplates[0] : STD_DEV_TIMELINE_TEMPLATE
const isTask = _.find(metadata.challengeTypes, { id: typeId, isTask: true })
const tags = trackId === QA_TRACK_ID ? ['QA'] : []
if (challengeType) {
tags.push(challengeType)
}
let timelineTemplateId = defaultTemplate.id

const newChallenge = {
status: 'New',
Expand All @@ -979,7 +985,7 @@ class ChallengeEditor extends Component {
reviewType: isTask || isDesignChallenge ? REVIEW_TYPES.INTERNAL : REVIEW_TYPES.COMMUNITY
},
descriptionFormat: 'markdown',
timelineTemplateId: defaultTemplate.id,
timelineTemplateId,
terms: [{ id: DEFAULT_TERM_UUID, roleId: SUBMITTER_ROLE_UUID }],
groups: [],
milestoneId,
Expand All @@ -1006,6 +1012,16 @@ class ChallengeEditor extends Component {
newChallenge.discussions = discussions
}
}
if (showDashBoard) {
if (!newChallenge.metadata) {
newChallenge.metadata = []
}
let useDashboard = _.find(challengeMetadata, { name: 'show_data_dashboard' })
if (useDashboard === undefined) {
useDashboard = { name: 'show_data_dashboard', value: true }
}
newChallenge.metadata.push(useDashboard)
}
try {
const action = await createChallenge(newChallenge, projectDetail.id)
if (isTask) {
Expand Down Expand Up @@ -1544,13 +1560,38 @@ class ChallengeEditor extends Component {
const currentChallengeId = this.getCurrentChallengeId()
const showTimeline = false // disables the timeline for time being https://github.com/topcoder-platform/challenge-engine-ui/issues/706
const copilotResources = metadata.members || challengeResources
const isDevChallenge = challenge.trackId === DEV_TRACK_ID
const isMM = challenge.typeId === MARATHON_TYPE_ID
const isChallengeType = challenge.typeId === CHALLENGE_TYPE_ID
const showDashBoard = (challenge.trackId === DS_TRACK_ID && isChallengeType) || (isDevChallenge && isMM)
const useDashboardData = _.find(challenge.metadata, { name: 'show_data_dashboard' })
const useDashboard = useDashboardData ? useDashboardData.value : true

const challengeForm = isNew
? (
<form name='challenge-new-form' noValidate autoComplete='off' onSubmit={this.createChallengeHandler}>
<div className={styles.newFormContainer}>
<TrackField tracks={metadata.challengeTracks} challenge={challenge} onUpdateOthers={this.onUpdateOthers} />
<TypeField types={metadata.challengeTypes} onUpdateSelect={this.onUpdateSelect} challenge={challenge} />
<ChallengeNameField challenge={challenge} onUpdateInput={this.onUpdateInput} />
{
showDashBoard && (
<div className={styles.row}>
<div className={cn(styles.field, styles.col1)}>
<label htmlFor='isDashboardEnabled'>Use data dashboard :</label>
</div>
<div className={cn(styles.field, styles.col2)}>
<input
name='isDashboardEnabled'
type='checkbox'
id='isDashboardEnabled'
checked={useDashboard}
onChange={(e) => this.onUpdateMetadata('show_data_dashboard', e.target.checked)}
/>
</div>
</div>
)
}
{projectDetail.version === 'v4' && <MilestoneField milestones={activeProjectMilestones} onUpdateSelect={this.onUpdateSelect} projectId={projectDetail.id} selectedMilestoneId={selectedMilestoneId} />}
{useTask && (<DiscussionField hasForum={hasForum} toggleForum={this.toggleForumOnCreate} />)}
</div>
Expand Down Expand Up @@ -1584,6 +1625,24 @@ class ChallengeEditor extends Component {
</div>

<ChallengeNameField challenge={challenge} onUpdateInput={this.onUpdateInput} />
{
showDashBoard && (
<div className={styles.row}>
<div className={cn(styles.field, styles.col1)}>
<label htmlFor='isDashboardEnabled'>Use data dashboard :</label>
</div>
<div className={cn(styles.field, styles.col2)}>
<input
name='isDashboardEnabled'
type='checkbox'
id='isDashboardEnabled'
checked={useDashboard}
onChange={(e) => this.onUpdateMetadata('show_data_dashboard', e.target.checked)}
/>
</div>
</div>
)
}
{isTask && (
<AssignedMemberField
challenge={challenge}
Expand Down
2 changes: 1 addition & 1 deletion src/components/ChallengesComponent/ChallengeList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ class ChallengeList extends Component {
<div className={styles.row}>
{!isBillingAccountLoading && !isBillingAccountLoadingFailed && !isBillingAccountExpired && (
<div className={'col-9'}>
<span className={styles.title}>Billing Account: </span><span className={styles.active}>{activeProject.status}</span> &nbsp; <span className={styles.title}>Start Date:</span> {billingStartDate} &nbsp; <span className={styles.title}>End Date:</span> {billingEndDate}
<span className={styles.title}>Billing Account: </span><span className={styles.active}>ACTIVE</span> &nbsp; <span className={styles.title}>Start Date:</span> {billingStartDate} &nbsp; <span className={styles.title}>End Date:</span> {billingEndDate}
</div>
)}
{!isBillingAccountLoading && !isBillingAccountLoadingFailed && isBillingAccountExpired && (
Expand Down
20 changes: 12 additions & 8 deletions src/components/SelectUserAutocomplete/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import React, { useState, useCallback } from 'react'
import PropTypes from 'prop-types'
import Select from '../Select'
import { suggestProfiles } from '../../services/user'
import { suggestProfilesV5, fetchProfileV5 } from '../../services/user'
import _ from 'lodash'
import { AUTOCOMPLETE_MIN_LENGTH, AUTOCOMPLETE_DEBOUNCE_TIME_MS } from '../../config/constants'

Expand All @@ -27,13 +27,17 @@ export default function SelectUserAutocomplete (props) {
return
}

suggestProfiles(inputValue).then((suggestions) => {
const suggestedOptions = suggestions.map((user) => ({
label: user.handle,
value: user.userId.toString()
}))
setOptions(suggestedOptions)
})
Promise.all([suggestProfilesV5(inputValue), fetchProfileV5(inputValue)]).then(
([suggestions, user]) => {
const suggestedOptions = suggestions.map((u) => ({
label: u.handle,
value: u.userId.toString()
}))
if (user && !_.find(suggestions, u => u.userId === user.userId)) {
suggestedOptions.push({ label: user.handle, value: user.userId.toString() })
}
setOptions(suggestedOptions)
})
}, AUTOCOMPLETE_DEBOUNCE_TIME_MS), []) // debounce, to reduce API calling rate

return (
Expand Down
1 change: 1 addition & 0 deletions src/config/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const {
DS_TRACK_ID,
QA_TRACK_ID,
CHALLENGE_TYPE_ID,
MARATHON_TYPE_ID,
SEGMENT_API_KEY
} = process.env
export const CREATE_FORUM_TYPE_IDS = typeof process.env.CREATE_FORUM_TYPE_IDS === 'string' ? process.env.CREATE_FORUM_TYPE_IDS.split(',') : process.env.CREATE_FORUM_TYPE_IDS
Expand Down
21 changes: 20 additions & 1 deletion src/services/user.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _ from 'lodash'
import { axiosInstance } from './axiosWithAuth'
const { MEMBER_API_V3_URL } = process.env
const { MEMBER_API_URL, MEMBER_API_V3_URL } = process.env

/**
* Api request for fetching user profile
Expand All @@ -11,6 +11,16 @@ export async function fetchProfile (handle) {
return _.get(response, 'data.result.content')
}

/**
* Api request for fetching user profile v5
* @returns {Promise<*>}
*/
export async function fetchProfileV5 (handle) {
const response = await axiosInstance.get(`${MEMBER_API_URL}?handle=${handle}`)
const data = _.get(response, 'data')
return data.length ? data[0] : undefined
}

/**
* Api request for fetching user profile
* @returns {Promise<*>}
Expand Down Expand Up @@ -49,3 +59,12 @@ export async function suggestProfiles (partialHandle) {
const response = await axiosInstance.get(`${MEMBER_API_V3_URL}/_suggest/${encodeURIComponent(partialHandle)}`)
return _.get(response, 'data.result.content')
}

/**
* Api request for finding (suggesting) users by the part of the handle
* @returns {Promise<*>}
*/
export async function suggestProfilesV5 (partialHandle) {
const response = await axiosInstance.get(`${MEMBER_API_URL}/autocomplete?term=${encodeURIComponent(partialHandle)}`)
return _.get(response, 'data')
}

0 comments on commit 68a32ee

Please sign in to comment.