@@ -17,7 +17,8 @@ import {
1717 DEFAULT_NDA_UUID ,
1818 SUBMITTER_ROLE_UUID ,
1919 CREATE_FORUM_TYPE_IDS ,
20- MESSAGE
20+ MESSAGE ,
21+ COMMUNITY_APP_URL
2122} from '../../config/constants'
2223import { PrimaryButton , OutlineButton } from '../Buttons'
2324import TrackField from './Track-Field'
@@ -934,35 +935,67 @@ class ChallengeEditor extends Component {
934935 async updateAllChallengeInfo ( status , cb = ( ) => { } ) {
935936 const { updateChallengeDetails, assignedMemberDetails : oldAssignedMember } = this . props
936937 if ( this . state . isSaving ) return
937- this . setState ( { isSaving : true } )
938- const challenge = this . collectChallengeData ( status )
939- let newChallenge = _ . cloneDeep ( this . state . challenge )
940- newChallenge . status = status
941- try {
942- const challengeId = this . getCurrentChallengeId ( )
943- const action = await updateChallengeDetails ( challengeId , challenge )
944- const { copilot : previousCopilot , reviewer : previousReviewer } = this . state . draftChallenge . data
945- const { challenge : { copilot, reviewer } , assignedMemberDetails : assignedMember } = this . state
946- if ( copilot ) await this . updateResource ( challengeId , 'Copilot' , copilot , previousCopilot )
947- if ( reviewer ) await this . updateResource ( challengeId , 'Reviewer' , reviewer , previousReviewer )
948- const oldMemberHandle = _ . get ( oldAssignedMember , 'handle' )
949- // assigned member has been updated
950- if ( assignedMember && assignedMember . handle !== oldMemberHandle ) {
951- await this . updateResource ( challengeId , 'Submitter' , assignedMember . handle , oldMemberHandle )
938+ this . setState ( { isSaving : true } , async ( ) => {
939+ const challenge = this . collectChallengeData ( status )
940+ let newChallenge = _ . cloneDeep ( this . state . challenge )
941+ newChallenge . status = status
942+ try {
943+ const challengeId = this . getCurrentChallengeId ( )
944+ // state can have updated assigned member (in cases where user changes assignments without refreshing the page)
945+ const { challenge : { copilot, reviewer } , assignedMemberDetails : assignedMember } = this . state
946+ const oldMemberHandle = _ . get ( oldAssignedMember , 'handle' )
947+ const assignedMemberHandle = _ . get ( assignedMember , 'handle' )
948+ // assigned member has been updated
949+ if ( assignedMemberHandle !== oldMemberHandle ) {
950+ await this . updateResource ( challengeId , 'Submitter' , assignedMemberHandle , oldMemberHandle )
951+ }
952+ const action = await updateChallengeDetails ( challengeId , challenge )
953+ const { copilot : previousCopilot , reviewer : previousReviewer } = this . state . draftChallenge . data
954+ if ( copilot !== previousCopilot ) await this . updateResource ( challengeId , 'Copilot' , copilot , previousCopilot )
955+ if ( reviewer !== previousReviewer ) await this . updateResource ( challengeId , 'Reviewer' , reviewer , previousReviewer )
956+
957+ const draftChallenge = { data : action . challengeDetails }
958+ draftChallenge . data . copilot = copilot
959+ draftChallenge . data . reviewer = reviewer
960+ this . setState ( { isLaunch : true ,
961+ isConfirm : newChallenge . id ,
962+ draftChallenge,
963+ challenge : newChallenge ,
964+ isSaving : false } , cb )
965+ } catch ( e ) {
966+ const error = this . formatResponseError ( e ) || `Unable to update the challenge to status ${ status } `
967+ this . setState ( { isSaving : false , error } , cb )
952968 }
969+ } )
970+ }
953971
954- const draftChallenge = { data : action . challengeDetails }
955- draftChallenge . data . copilot = copilot
956- draftChallenge . data . reviewer = reviewer
957- this . setState ( { isLaunch : true ,
958- isConfirm : newChallenge . id ,
959- draftChallenge,
960- challenge : newChallenge ,
961- isSaving : false } , cb )
962- } catch ( e ) {
963- const error = _ . get ( e , 'response.data.message' , `Unable to update the challenge to status ${ status } ` )
964- this . setState ( { isSaving : false , error } , cb )
972+ /**
973+ * Format the error we might get from some API endpoint.
974+ *
975+ * @param {Error } error error
976+ *
977+ * @returns {import('react').ReactNode }
978+ */
979+ formatResponseError ( error ) {
980+ const errorMessage = _ . get ( error , 'response.data.message' )
981+ const errorMetadata = _ . get ( error , 'response.data.metadata' )
982+
983+ if ( errorMetadata . missingTerms && errorMetadata . missingTerms . length > 0 ) {
984+ return < >
985+ { errorMessage }
986+ < ul className = { styles . linkList } > { ' ' }
987+ { errorMetadata . missingTerms . map ( ( terms , index ) => {
988+ const termsNumber = errorMetadata . missingTerms . length > 1 ? ` ${ index + 1 } ` : ''
989+ return (
990+ < li key = { index } > < a href = { `${ COMMUNITY_APP_URL } /challenges/terms/detail/${ terms . termId } ` } target = '_blank' > link to terms{ termsNumber } </ a > </ li >
991+ )
992+ } ) }
993+ </ ul >
994+ </ >
965995 }
996+
997+ // if no special error data, just use message
998+ return errorMessage
966999 }
9671000
9681001 async onActiveChallenge ( ) {
@@ -1055,7 +1088,6 @@ class ChallengeEditor extends Component {
10551088 return < div > Error loading challenge</ div >
10561089 }
10571090 const isTask = _ . get ( challenge , 'task.isTask' , false )
1058- console . log ( this . props . assignedMemberDetails )
10591091 const { assignedMemberDetails, error } = this . state
10601092 let isActive = false
10611093 let isDraft = false
@@ -1206,7 +1238,7 @@ class ChallengeEditor extends Component {
12061238 <OutlineButton text={isSaving ? 'Saving...' : 'Save'} type={'success'} onClick={this.onSaveChallenge} />
12071239 </div> */ }
12081240 < div className = { styles . button } >
1209- < PrimaryButton text = { 'Save Draft' } type = { 'info' } onClick = { this . createDraftHandler } />
1241+ < PrimaryButton text = { isSaving ? 'Saving...' : 'Save Draft' } type = { 'info' } onClick = { this . createDraftHandler } />
12101242 </ div >
12111243 { isDraft && (
12121244 < div className = { styles . button } >
@@ -1222,9 +1254,9 @@ class ChallengeEditor extends Component {
12221254 ) }
12231255 </ div > }
12241256 { ! isLoading && isActive && < div className = { styles . buttonContainer } >
1225- { /* <div className={styles.button}>
1257+ < div className = { styles . button } >
12261258 < OutlineButton text = { isSaving ? 'Saving...' : 'Save' } type = { 'success' } onClick = { this . onSaveChallenge } />
1227- </div> */ }
1259+ </ div >
12281260 { isTask && (
12291261 < div className = { styles . button } >
12301262 < PrimaryButton text = { 'Close Task' } type = { 'danger' } onClick = { this . openCloseTaskConfirmation } />
0 commit comments