Skip to content

Commit 875299c

Browse files
committed
Improve UX on approving milestones, it does not refresh page on successful approve/reject.
1 parent 95c6fbc commit 875299c

File tree

4 files changed

+61
-11
lines changed

4 files changed

+61
-11
lines changed

src/config/constants.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ export const LOAD_PROJECT_PHASES = 'LOAD_PROJECT_PHASES'
318318
export const LOAD_PROJECT_PHASES_PENDING = 'LOAD_PROJECT_PHASES_PENDING'
319319
export const LOAD_PROJECT_PHASES_FAILURE = 'LOAD_PROJECT_PHASES_FAILURE'
320320
export const LOAD_PROJECT_PHASES_SUCCESS = 'LOAD_PROJECT_PHASES_SUCCESS'
321+
export const CUSTOMER_APPROVE_MILESTONE_SUCCESS = 'CUSTOMER_APPROVE_MILESTONE_SUCCESS'
322+
export const CUSTOMER_APPROVE_MILESTONE_FAILURE = 'CUSTOMER_APPROVE_MILESTONE_FAILURE'
321323

322324
export const LOAD_PRODUCT_TIMELINE_WITH_MILESTONES = 'LOAD_PRODUCT_TIMELINE_WITH_MILESTONES'
323325
export const LOAD_PRODUCT_TIMELINE_WITH_MILESTONES_PENDING = 'LOAD_PRODUCT_TIMELINE_WITH_MILESTONES_PENDING'

src/projects/actions/project.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ import {
7171
CREATE_PROJECT_PHASE_TIMELINE_MILESTONES,
7272
LOAD_PROJECT_MEMBER,
7373
ES_REINDEX_DELAY,
74-
CREATE_PROJECT_PHASE
74+
CREATE_PROJECT_PHASE,
75+
CUSTOMER_APPROVE_MILESTONE_SUCCESS,
76+
CUSTOMER_APPROVE_MILESTONE_FAILURE
7577
} from '../../config/constants'
7678
import {
7779
updateProductMilestone,
@@ -515,12 +517,30 @@ export function executePhaseApproval(projectId, phaseId, updatedProps, phaseInde
515517
const state = getState()
516518
phaseIndex = phaseIndex ? phaseIndex : _.findIndex(state.projectState.phases, { id: phaseId })
517519

518-
createPhaseApprovalAPI(projectId, phaseId, updatedProps, phaseIndex).then(() => {
519-
dispatch(loadProjectPhasesWithProducts(projectId))
520+
return createPhaseApprovalAPI(projectId, phaseId, updatedProps, phaseIndex).then(() => {
521+
}).catch(() => {
522+
return Promise.reject(new Error('Fail to approve milestone'))
520523
})
521524
}
522525
}
523526

527+
/**
528+
* Dispatch alert message after individual or bulk milestone approval
529+
*
530+
* @param {Boolean} success is milestone updated successfully
531+
*
532+
* @return {Promise} phase
533+
*/
534+
export function approveMilestone(success = true) {
535+
return (dispatch) => {
536+
if (success) {
537+
dispatch({ type: CUSTOMER_APPROVE_MILESTONE_SUCCESS })
538+
} else {
539+
dispatch({ type: CUSTOMER_APPROVE_MILESTONE_FAILURE })
540+
}
541+
}
542+
}
543+
524544
/**
525545
* Update phase info
526546
*

src/projects/detail/containers/DashboardContainer.jsx

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
createPhaseAndMilestones,
3333
createPhaseWithoutTimeline,
3434
getChallengesByIds,
35+
approveMilestone,
3536
} from '../../actions/project'
3637
import { addProductAttachment, updateProductAttachment, removeProductAttachment } from '../../actions/projectAttachment'
3738

@@ -67,7 +68,8 @@ import {
6768
SCREEN_BREAKPOINT_MD,
6869
CODER_BOT_USERID,
6970
PROJECT_TYPE_TALENT_AS_A_SERVICE,
70-
PHASE_PRODUCT_TEMPLATE_ID
71+
PHASE_PRODUCT_TEMPLATE_ID,
72+
PHASE_STATUS_REVIEWED
7173
} from '../../../config/constants'
7274

7375
const SYSTEM_USER = {
@@ -83,7 +85,8 @@ class DashboardContainer extends React.Component {
8385

8486
this.state = {
8587
open: false,
86-
createGameplanPhases: null
88+
createGameplanPhases: null,
89+
visiblePhases: null
8790
}
8891
this.onNotificationRead = this.onNotificationRead.bind(this)
8992
this.toggleDrawer = this.toggleDrawer.bind(this)
@@ -151,18 +154,32 @@ class DashboardContainer extends React.Component {
151154
}
152155

153156
onApproveMilestones({type, comment, milestones}) {
154-
const { executePhaseApproval } = this.props
157+
const { executePhaseApproval, approveMilestone } = this.props
155158
const reqs = []
156159
milestones.forEach( ms => {
157160
reqs.push(
158161
executePhaseApproval(ms.projectId, ms.id, {decision: type, comment})
159162
)
160163
console.log('type-comment', type, comment, ms)
161164
})
162-
Promise.all(reqs).then((...args) => {console.log('onApproveMilestones t', args)})
163-
.catch(e => console.log('onApproveMilestones f', e))
165+
const updatedPhases = this.state.createGameplanPhases || this.state.visiblePhases || []
166+
Promise.all(reqs).then(() => {
167+
milestones.forEach(ms => {
168+
const index = updatedPhases.findIndex(phase => phase.id === ms.id)
169+
updatedPhases.splice(index, 1, {
170+
...updatedPhases[index],
171+
status: PHASE_STATUS_REVIEWED
172+
})
173+
})
174+
175+
approveMilestone()
176+
})
177+
.catch((e) => {
178+
console.log('onApproveMilestones f', e)
179+
approveMilestone(false)
180+
})
164181
.finally(() => {
165-
this.onChangeMilestones(null)
182+
this.onChangeMilestones(updatedPhases)
166183
})
167184
}
168185

@@ -350,6 +367,7 @@ class DashboardContainer extends React.Component {
350367
const visiblePhases = phases && phases.filter((phase) => (
351368
hasPermission(PERMISSIONS.VIEW_DRAFT_PHASES) || phase.status !== PHASE_STATUS_DRAFT
352369
))
370+
this.state.visiblePhases = visiblePhases
353371
const visiblePhasesIds = _.map(visiblePhases, 'id')
354372
const visiblePhasesNonDirty = phasesNonDirty && phasesNonDirty.filter((phaseNonDirty) => (
355373
_.includes(visiblePhasesIds, phaseNonDirty.id)
@@ -565,7 +583,8 @@ const mapDispatchToProps = {
565583
removeProjectAttachment,
566584
updatePhase,
567585
updatePhaseMembers,
568-
executePhaseApproval
586+
executePhaseApproval,
587+
approveMilestone
569588
}
570589

571590
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(DashboardContainer))

src/reducers/alerts.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ import {
7171
REJECT_SCOPE_CHANGE_FAILURE,
7272
CANCEL_SCOPE_CHANGE_FAILURE,
7373
ACTIVATE_SCOPE_CHANGE_FAILURE,
74-
CREATE_PROJECT_PHASE_SUCCESS
74+
CREATE_PROJECT_PHASE_SUCCESS,
75+
CUSTOMER_APPROVE_MILESTONE_SUCCESS,
76+
CUSTOMER_APPROVE_MILESTONE_FAILURE
7577
} from '../config/constants'
7678
/* eslint-enable no-unused-vars */
7779

@@ -263,6 +265,13 @@ export default function(state = {}, action) {
263265
Alert.error(message)
264266
return state
265267
}
268+
case CUSTOMER_APPROVE_MILESTONE_SUCCESS:
269+
Alert.success('Approved Milestones successfully.')
270+
return state
271+
272+
case CUSTOMER_APPROVE_MILESTONE_FAILURE:
273+
Alert.error('Unable to Approve Milestone.')
274+
return state
266275

267276
case CREATE_PROJECT_FAILURE:
268277
case DELETE_PROJECT_FAILURE:

0 commit comments

Comments
 (0)