@@ -4,7 +4,7 @@ import { connect } from 'react-redux'
4
4
import cn from 'classnames'
5
5
import { PrimaryButton , OutlineButton } from '../../Buttons'
6
6
import { REVIEW_OPPORTUNITY_TYPE_LABELS , REVIEW_OPPORTUNITY_TYPES , VALIDATION_VALUE_TYPE } from '../../../config/constants'
7
- import { loadScorecards , loadDefaultReviewers , loadWorkflows } from '../../../actions/challenges'
7
+ import { loadScorecards , loadDefaultReviewers , loadWorkflows , loadScorecardById } from '../../../actions/challenges'
8
8
import styles from './ChallengeReviewer-Field.module.scss'
9
9
import { convertDollarToInteger , validateValue } from '../../../util/input-check'
10
10
@@ -31,18 +31,28 @@ class ChallengeReviewerField extends Component {
31
31
}
32
32
33
33
componentDidMount ( ) {
34
- this . loadScorecards ( )
34
+ if ( this . props . readOnly ) {
35
+ // In read-only mode, only load specific scorecards for existing reviewers
36
+ this . loadSpecificScorecards ( )
37
+ } else {
38
+ // In edit mode, load all scorecards for dropdown
39
+ this . loadScorecards ( )
40
+ }
35
41
this . loadDefaultReviewers ( )
36
42
this . loadWorkflows ( )
37
43
}
38
44
39
45
componentDidUpdate ( prevProps ) {
40
- const { challenge } = this . props
46
+ const { challenge, readOnly } = this . props
41
47
const prevChallenge = prevProps . challenge
42
48
43
49
if ( challenge && prevChallenge &&
44
50
( challenge . type !== prevChallenge . type || challenge . track !== prevChallenge . track ) ) {
45
- this . loadScorecards ( )
51
+ if ( readOnly ) {
52
+ this . loadSpecificScorecards ( )
53
+ } else {
54
+ this . loadScorecards ( )
55
+ }
46
56
}
47
57
48
58
if ( challenge && prevChallenge &&
@@ -69,6 +79,27 @@ class ChallengeReviewerField extends Component {
69
79
loadScorecards ( filters )
70
80
}
71
81
82
+ loadSpecificScorecards ( ) {
83
+ const { challenge, loadScorecardById } = this . props
84
+ const reviewers = challenge . reviewers || [ ]
85
+
86
+ // Get unique scorecard IDs from reviewers
87
+ const scorecardIds = [ ...new Set (
88
+ reviewers
89
+ . filter ( reviewer => reviewer . scorecardId )
90
+ . map ( reviewer => reviewer . scorecardId )
91
+ ) ]
92
+
93
+ if ( scorecardIds . length === 0 ) {
94
+ return
95
+ }
96
+
97
+ // Load each scorecard individually
98
+ scorecardIds . forEach ( scorecardId => {
99
+ loadScorecardById ( scorecardId )
100
+ } )
101
+ }
102
+
72
103
loadDefaultReviewers ( ) {
73
104
const { challenge, loadDefaultReviewers } = this . props
74
105
@@ -240,7 +271,7 @@ class ChallengeReviewerField extends Component {
240
271
renderReviewerForm ( reviewer , index ) {
241
272
const { challenge, metadata = { } , readOnly = false } = this . props
242
273
const { scorecards = [ ] , workflows = [ ] } = metadata
243
- const validationErrors = this . validateReviewer ( reviewer )
274
+ const validationErrors = challenge . submitTriggered ? this . validateReviewer ( reviewer ) : { }
244
275
245
276
return (
246
277
< div key = { `reviewer-${ index } ` } className = { styles . reviewerForm } >
@@ -337,8 +368,10 @@ class ChallengeReviewerField extends Component {
337
368
) ) }
338
369
</ select >
339
370
) }
340
- { validationErrors . aiWorkflowId && (
341
- < div className = { styles . fieldError } > { validationErrors . aiWorkflowId } </ div >
371
+ { ! readOnly && challenge . submitTriggered && validationErrors . aiWorkflowId && (
372
+ < div className = { styles . error } >
373
+ { validationErrors . aiWorkflowId }
374
+ </ div >
342
375
) }
343
376
</ div >
344
377
) : (
@@ -347,8 +380,15 @@ class ChallengeReviewerField extends Component {
347
380
{ readOnly ? (
348
381
< span >
349
382
{ ( ( ) => {
383
+ const { metadata = { } } = this . props
384
+ const specificScorecard = metadata . scorecardById
385
+ if ( specificScorecard && specificScorecard . id === reviewer . scorecardId ) {
386
+ return `${ specificScorecard . name || 'Unknown' } - ${ specificScorecard . type || 'Unknown' } (${ specificScorecard . challengeTrack || 'Unknown' } ) v${ specificScorecard . version || 'Unknown' } `
387
+ }
388
+
389
+ // Fallback to searching in the general scorecards array
350
390
const scorecard = scorecards . find ( s => s . id === reviewer . scorecardId )
351
- return scorecard ? `${ scorecard . name } - ${ scorecard . type } (${ scorecard . challengeTrack } ) v${ scorecard . version } ` : 'Not selected'
391
+ return scorecard ? `${ scorecard . name || 'Unknown' } - ${ scorecard . type || 'Unknown' } (${ scorecard . challengeTrack || 'Unknown' } ) v${ scorecard . version || 'Unknown' } ` : 'Not selected'
352
392
} ) ( ) }
353
393
</ span >
354
394
) : (
@@ -359,13 +399,15 @@ class ChallengeReviewerField extends Component {
359
399
< option value = '' > Select Scorecard</ option >
360
400
{ scorecards . map ( scorecard => (
361
401
< option key = { scorecard . id } value = { scorecard . id } >
362
- { scorecard . name } - { scorecard . type } ({ scorecard . challengeTrack } ) v{ scorecard . version }
402
+ { scorecard . name || 'Unknown' } - { scorecard . type || 'Unknown' } ({ scorecard . challengeTrack || 'Unknown' } ) v{ scorecard . version || 'Unknown' }
363
403
</ option >
364
404
) ) }
365
405
</ select >
366
406
) }
367
- { validationErrors . scorecardId && (
368
- < div className = { styles . fieldError } > { validationErrors . scorecardId } </ div >
407
+ { ! readOnly && challenge . submitTriggered && validationErrors . scorecardId && (
408
+ < div className = { styles . error } >
409
+ { validationErrors . scorecardId }
410
+ </ div >
369
411
) }
370
412
</ div >
371
413
) }
@@ -409,8 +451,10 @@ class ChallengeReviewerField extends Component {
409
451
) ) }
410
452
</ select >
411
453
) }
412
- { validationErrors . phaseId && (
413
- < div className = { styles . fieldError } > { validationErrors . phaseId } </ div >
454
+ { ! readOnly && challenge . submitTriggered && validationErrors . phaseId && (
455
+ < div className = { styles . error } >
456
+ { validationErrors . phaseId }
457
+ </ div >
414
458
) }
415
459
</ div >
416
460
</ div >
@@ -433,8 +477,10 @@ class ChallengeReviewerField extends Component {
433
477
} }
434
478
/>
435
479
) }
436
- { validationErrors . memberReviewerCount && (
437
- < div className = { styles . fieldError } > { validationErrors . memberReviewerCount } </ div >
480
+ { ! readOnly && challenge . submitTriggered && validationErrors . memberReviewerCount && (
481
+ < div className = { styles . error } >
482
+ { validationErrors . memberReviewerCount }
483
+ </ div >
438
484
) }
439
485
</ div >
440
486
@@ -453,8 +499,10 @@ class ChallengeReviewerField extends Component {
453
499
} }
454
500
/>
455
501
) }
456
- { validationErrors . basePayment && (
457
- < div className = { styles . fieldError } > { validationErrors . basePayment } </ div >
502
+ { ! readOnly && challenge . submitTriggered && validationErrors . basePayment && (
503
+ < div className = { styles . error } >
504
+ { validationErrors . basePayment }
505
+ </ div >
458
506
) }
459
507
</ div >
460
508
@@ -617,13 +665,15 @@ ChallengeReviewerField.propTypes = {
617
665
metadata : PropTypes . shape ( {
618
666
scorecards : PropTypes . array ,
619
667
defaultReviewers : PropTypes . array ,
620
- workflows : PropTypes . array
668
+ workflows : PropTypes . array ,
669
+ scorecardById : PropTypes . object
621
670
} ) ,
622
671
isLoading : PropTypes . bool ,
623
672
readOnly : PropTypes . bool ,
624
673
loadScorecards : PropTypes . func . isRequired ,
625
674
loadDefaultReviewers : PropTypes . func . isRequired ,
626
- loadWorkflows : PropTypes . func . isRequired
675
+ loadWorkflows : PropTypes . func . isRequired ,
676
+ loadScorecardById : PropTypes . func . isRequired
627
677
}
628
678
629
679
const mapStateToProps = ( state ) => ( {
@@ -634,7 +684,8 @@ const mapStateToProps = (state) => ({
634
684
const mapDispatchToProps = {
635
685
loadScorecards,
636
686
loadDefaultReviewers,
637
- loadWorkflows
687
+ loadWorkflows,
688
+ loadScorecardById
638
689
}
639
690
640
691
export default connect ( mapStateToProps , mapDispatchToProps ) ( ChallengeReviewerField )
0 commit comments