Skip to content

Oct 2022 release #1423

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 11 commits into from
Oct 11, 2022
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')
}