Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions src/projects/actions/productsTimelines.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
BULK_UPDATE_PRODUCT_MILESTONES,
} from '../../config/constants'
import { processUpdateMilestone } from '../../helpers/milestoneHelper'
import moment from 'moment'

/**
* Get the next milestone in the list, which is not hidden
Expand Down Expand Up @@ -448,3 +449,79 @@ export function completeFinalFixesMilestone(productId, timelineId, milestoneId,
})
}
}

/**
* Mark the milestone as 'completed' and append a 'deliverable-final-fixes' milestone after it
* @param {Number} productId product id
* @param {Number} timelineId timeline id
* @param {Number} milestoneId milestone id
* @param {String} finalFixRequest final fixes request text
*/
export function submitDeliverableFinalFixesRequest(productId, timelineId, milestoneId, finalFixRequest) {
return (dispatch, getState) => {
const state = getState()
const timeline = state.productsTimelines[productId].timeline
const milestoneIdx = _.findIndex(timeline.milestones, { id: milestoneId })
const milestone = timeline.milestones[milestoneIdx]

let updatedTimelineMilestones = [
...timeline.milestones,
]

updatedTimelineMilestones = processUpdateMilestone(
milestone, {
status: MILESTONE_STATUS.COMPLETED,
}, updatedTimelineMilestones
).updatedTimelineMilestones

const finalFixesMilestone = {
type: 'deliverable-final-fixes',
startDate: milestone.endDate,
endDate: moment(milestone.endDate).add(3, 'day').toISOString(),
status: MILESTONE_STATUS.ACTIVE,
details: {
content: {
finalFixesRequest: finalFixRequest,
}
},
name: 'Final Fixes',
duration: 3,
order: timeline.milestones.length + 1,
hidden: false,
completedText: 'completed text',
activeText: 'active text',
description: 'description',
plannedText: 'planned text',
blockedText: 'blocked text',
}

updatedTimelineMilestones.splice(milestoneIdx + 1, 0, finalFixesMilestone)

dispatch({
type: SUBMIT_FINAL_FIXES_REQUEST_PENDING,
meta: { productId, milestoneId }
})

const milestones = updatedTimelineMilestones.map(milestone => _.omit(milestone, ['timelineId', 'error', 'isUpdating', 'statusHistory']))

return dispatch({
type: BULK_UPDATE_PRODUCT_MILESTONES,
payload: updateMilestones(timelineId, milestones),
meta: {
productId,
}
}).then(() => {
dispatch({
type: SUBMIT_FINAL_FIXES_REQUEST_SUCCESS,
meta: { productId, milestoneId }
})
}).catch((error) => {
dispatch({
type: SUBMIT_FINAL_FIXES_REQUEST_FAILURE,
payload: error,
meta: { productId, milestoneId }
})
throw error
})
}
}
35 changes: 34 additions & 1 deletion src/projects/detail/components/timeline/Milestone/Milestone.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import MilestoneTypeFinalDesigns from '../milestones/MilestoneTypeFinalDesigns'
import MilestoneTypeDelivery from '../milestones/MilestoneTypeDelivery'
import MilestoneTypeFinalFixes from '../milestones/MilestoneTypeFinalFixes'
import MilestoneTypeAddLinks from '../milestones/MilestoneTypeAddLinks'
import MilestoneTypeReporting from '../milestones/MilestoneTypeReporting'
import MilestoneTypeDeliverableReview from '../milestones/MilestoneTypeDeliverableReview'
import DotIndicator from '../DotIndicator'
import MobilePage from '../../../../../components/MobilePage/MobilePage'
import MediaQuery from 'react-responsive'
Expand Down Expand Up @@ -48,6 +50,7 @@ class Milestone extends React.Component {
this.completeFinalFixesMilestone = this.completeFinalFixesMilestone.bind(this)
this.extendMilestone = this.extendMilestone.bind(this)
this.submitFinalFixesRequest = this.submitFinalFixesRequest.bind(this)
this.submitDeliverableFinalFixesRequest = this.submitDeliverableFinalFixesRequest.bind(this)
this.milestoneEditorChanged = this.milestoneEditorChanged.bind(this)

this.state = {
Expand Down Expand Up @@ -157,7 +160,7 @@ class Milestone extends React.Component {
}
}

updateMilestoneContent(contentProps, metaDataProps) {
updateMilestoneContent(contentProps, metaDataProps, status) {
const { updateMilestone, milestone } = this.props

const updatedMilestone = {
Expand All @@ -174,6 +177,10 @@ class Milestone extends React.Component {
}
}

if (status) {
updatedMilestone.status = status
}

updateMilestone(milestone.id, updatedMilestone)
}

Expand Down Expand Up @@ -216,6 +223,12 @@ class Milestone extends React.Component {
submitFinalFixesRequest(milestone.id, finalFixRequests)
}

submitDeliverableFinalFixesRequest(finalFixesRequest) {
const { submitDeliverableFinalFixesRequest, milestone } = this.props

submitDeliverableFinalFixesRequest(milestone.id, finalFixesRequest)
}

render() {
const {
milestone,
Expand Down Expand Up @@ -330,6 +343,7 @@ class Milestone extends React.Component {
disableSubmitButton={this.state.disableSubmit}
/>
)

return (
<div styleName="timeline-post">
{(<div styleName={'background ' + ((this.state.isHoverHeader && !this.state.isEditing && !isCompleted) ? 'hover ' : '')} />)}
Expand Down Expand Up @@ -491,6 +505,24 @@ class Milestone extends React.Component {
/>
)
}

{!isEditing && !isUpdating && milestone.type === 'reporting' && (
<MilestoneTypeReporting
milestone={milestone}
updateMilestoneContent={this.updateMilestoneContent}
currentUser={currentUser}
/>
)}

{!isEditing && !isUpdating && (milestone.type === 'deliverable-review' || milestone.type === 'final-deliverable-review' || milestone.type === 'deliverable-final-fixes') && (
<MilestoneTypeDeliverableReview
milestone={milestone}
currentUser={currentUser}
updateMilestoneContent={this.updateMilestoneContent}
submitDeliverableFinalFixesRequest={this.submitDeliverableFinalFixesRequest}
completeMilestone={this.completeMilestone}
/>
)}
</div>
</div>
)
Expand All @@ -504,6 +536,7 @@ Milestone.propTypes = {
milestone: PT.object.isRequired,
submitFinalFixesRequest: PT.func.isRequired,
updateMilestone: PT.func.isRequired,
submitDeliverableFinalFixesRequest: PT.func.isRequired,
}

export default Milestone
13 changes: 13 additions & 0 deletions src/projects/detail/components/timeline/Timeline/Timeline.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Timeline extends React.Component {
this.completeFinalFixesMilestone = this.completeFinalFixesMilestone.bind(this)
this.extendMilestone = this.extendMilestone.bind(this)
this.submitFinalFixesRequest = this.submitFinalFixesRequest.bind(this)
this.submitDeliverableFinalFixesRequest = this.submitDeliverableFinalFixesRequest.bind(this)
}

componentWillReceiveProps() {
Expand Down Expand Up @@ -91,6 +92,16 @@ class Timeline extends React.Component {
submitFinalFixesRequest(product.id, timeline.id, milestoneId, finalFixRequests)
}

submitDeliverableFinalFixesRequest(milestoneId, finalFixesRequest) {
const {
product,
submitDeliverableFinalFixesRequest,
timeline,
} = this.props

submitDeliverableFinalFixesRequest(product.id, timeline.id, milestoneId, finalFixesRequest)
}

render() {
const {
currentUser,
Expand Down Expand Up @@ -123,6 +134,7 @@ class Timeline extends React.Component {
extendMilestone={this.extendMilestone}
submitFinalFixesRequest={this.submitFinalFixesRequest}
completeFinalFixesMilestone={this.completeFinalFixesMilestone}
submitDeliverableFinalFixesRequest={this.submitDeliverableFinalFixesRequest}
//$TODO convert the below logic more optimized way
previousMilestone={_.find(orderedMilestones, m => m.order === milestone.order-1) &&
_.find(orderedMilestones, m => m.order === milestone.order-1).type}
Expand All @@ -146,6 +158,7 @@ Timeline.propType = {
updateProductMilestone: PT.func.isRequired,
completeProductMilestone: PT.func.isRequired,
extendProductMilestone: PT.func.isRequired,
submitDeliverableFinalFixesRequest: PT.func.isRequired,
}

export default Timeline
Loading