diff --git a/.circleci/config.yml b/.circleci/config.yml index 02fc2b25..39899074 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -160,7 +160,7 @@ workflows: context: org-global filters: &filters-dev branches: - only: ["develop"] + only: ["develop", "pm-2917"] # Production builds are exectuted only on tagged commits to the # master branch. diff --git a/package.json b/package.json index 46f40f28..fc87fffb 100644 --- a/package.json +++ b/package.json @@ -114,7 +114,7 @@ "sass-loader": "^13.3.2", "standard": "^12.0.1", "style-loader": "^3.3.4", - "tc-auth-lib": "topcoder-platform/tc-auth-lib#1.0.4", + "tc-auth-lib": "topcoder-platform/tc-auth-lib#v2.0", "terser": "^5.31.0", "terser-webpack-plugin": "^5.3.10", "topcoder-healthcheck-dropin": "^1.0.3", diff --git a/src/components/ChallengeEditor/ChallengeReviewer-Field/index.js b/src/components/ChallengeEditor/ChallengeReviewer-Field/index.js index 523d3588..218e6bf0 100644 --- a/src/components/ChallengeEditor/ChallengeReviewer-Field/index.js +++ b/src/components/ChallengeEditor/ChallengeReviewer-Field/index.js @@ -772,24 +772,38 @@ class ChallengeReviewerField extends Component { const isPostMortemPhase = norm === 'postmortem' const isCurrentlySelected = reviewer.phaseId && ((phase.id === reviewer.phaseId) || (phase.phaseId === reviewer.phaseId)) && !isSubmissionPhase + // Collect phases already assigned to other reviewers (excluding current reviewer) + const assignedPhaseIds = new Set( + (challenge.reviewers || []) + .filter((r, i) => i !== index) + .map(r => r.phaseId) + .filter(id => id !== undefined && id !== null) + ) + + // If current reviewer is a member review, allow selecting phases even if already assigned to others. + // Only exclude assigned phases for ai reviewers. + if (!!reviewer.isMemberReview && assignedPhaseIds.has(phase.phaseId || phase.id) && !isCurrentlySelected) { + return false + } + // For AI reviewers, allow review, submission, and other required phases // For member reviewers, allow review and other required phases if (this.isAIReviewer(reviewer)) { return ( isReviewPhase || - isSubmissionPhase || - isScreeningPhase || - isApprovalPhase || - isPostMortemPhase || - isCurrentlySelected + isSubmissionPhase || + isScreeningPhase || + isApprovalPhase || + isPostMortemPhase || + isCurrentlySelected ) } else { return ( isReviewPhase || - isScreeningPhase || - isApprovalPhase || - isPostMortemPhase || - isCurrentlySelected + isScreeningPhase || + isApprovalPhase || + isPostMortemPhase || + isCurrentlySelected ) } }) diff --git a/src/components/ChallengeEditor/index.js b/src/components/ChallengeEditor/index.js index 2c6be99b..da51eb04 100644 --- a/src/components/ChallengeEditor/index.js +++ b/src/components/ChallengeEditor/index.js @@ -1314,9 +1314,21 @@ class ChallengeEditor extends Component { const { updateChallengeDetails, assignedMemberDetails: oldAssignedMember, projectDetail, challengeDetails } = this.props if (this.state.isSaving) return this.setState({ isSaving: true }, async () => { - const challenge = this.collectChallengeData(status) + let challenge = this.collectChallengeData(status) let newChallenge = _.cloneDeep(this.state.challenge) newChallenge.status = status + + if (challenge.reviewers && Array.isArray(challenge.reviewers)) { + challenge.reviewers = challenge.reviewers.map(reviewer => { + if (reviewer.isMemberReview === false) { + const copy = { ...reviewer } + delete copy.type + return copy + } + return reviewer + }) + } + try { const challengeId = this.getCurrentChallengeId() // state can have updated assigned member (in cases where user changes assignments without refreshing the page) diff --git a/src/routes.js b/src/routes.js index 61a2e197..e3a500d1 100644 --- a/src/routes.js +++ b/src/routes.js @@ -86,11 +86,8 @@ class Routes extends React.Component { getFreshToken().then((token) => { this.props.saveToken(token) }).catch((error) => { - if (process.env.NODE_ENV === 'development') { - console.error(error) - } else { - console.error('An unexpected error occurred while getting auth token') - } + const errorMessage = error && error.message ? error.message : error + console.error('An unexpected error occurred while getting auth token', errorMessage) const redirectBackToUrl = encodeURIComponent(window.location.origin + this.props.location.pathname + this.props.location.search) window.location = `${ACCOUNTS_APP_LOGIN_URL}?retUrl=${redirectBackToUrl}` })