33 */
44import React from 'react'
55import PT from 'prop-types'
6+ import moment from 'moment'
67import FormsyForm from 'appirio-tech-react-components/components/Formsy'
78import MilestoneRow from '../components/MilestoneRow'
89import MilestoneChallengeHeader from '../components/MilestoneChallengeHeader'
@@ -11,10 +12,12 @@ import MilestoneChallengeFooter from '../components/MilestoneChallengeFooter'
1112import MilestoneHeaderRow from '../components/MilestoneHeaderRow'
1213import MilestoneDeleteButton from '../components/MilestoneDeleteButton'
1314import MilestoneCopilots from '../components/MilestoneCopilots'
15+ import MilestoneMoveDateButton from '../components/MilestoneMoveDateButton'
16+
1417import * as milestoneHelper from '../components/helpers/milestone'
1518import IconUnselect from '../../../../../assets/icons/icon-disselect.svg'
1619import IconCopilot from '../../../../../assets/icons/icon-copilot.svg'
17- import IconCalendar from '../../../../../assets/icons/calendar.svg '
20+ import { CHALLENGE_ID_MAPPING } from '../../../../../config/constants '
1821// import IconGridView from '../../../../../assets/icons/ui-16px-2_grid-45-gray.svg'
1922// import IconGnattView from '../../../../../assets/icons/icon-gnatt-gray.svg'
2023
@@ -38,8 +41,26 @@ class ManageMilestones extends React.Component {
3841 this . onUnselectAll = this . onUnselectAll . bind ( this )
3942 this . onDeleteAll = this . onDeleteAll . bind ( this )
4043 this . onAddCopilotAll = this . onAddCopilotAll . bind ( this )
44+ this . onMoveMilestoneDates = this . onMoveMilestoneDates . bind ( this )
45+ this . onLoadChallengesByPage = this . onLoadChallengesByPage . bind ( this )
4146 }
47+ onMoveMilestoneDates ( days ) {
48+ const {
49+ milestones,
50+ onSaveMilestone
51+ } = this . props
4252
53+
54+ if ( days > 0 ) {
55+ const seletedMilestones = _ . filter ( milestones , m => m . selected )
56+ _ . forEach ( seletedMilestones , m => {
57+ m . startDate = moment ( m . startDate ) . add ( days , 'days' )
58+ m . endDate = moment ( m . endDate ) . add ( days , 'days' )
59+ this . onChange ( m )
60+ onSaveMilestone ( m . id )
61+ } )
62+ }
63+ }
4364 onAddCopilotAll ( member , isAdd ) {
4465 const { milestones, onSaveMilestone } = this . props
4566 const seletedMilestones = _ . filter ( milestones , m => m . selected )
@@ -81,11 +102,21 @@ class ManageMilestones extends React.Component {
81102 } ) )
82103 onChangeMilestones ( milestonesUnselected )
83104 }
105+
106+ onLoadChallengesByPage ( index , milestone ) {
107+ const { onGetChallenges } = this . props
108+ let challengeIds = _ . map ( milestone . products , `details.${ CHALLENGE_ID_MAPPING } ` ) . slice ( 6 * index , 7 * ( index + 1 ) )
109+ challengeIds = _ . filter ( challengeIds )
110+ if ( ! challengeIds . length ) {
111+ return
112+ }
113+ onGetChallenges ( milestone . id , challengeIds )
114+ }
84115 onExpandChallenges ( isExpand , milestone ) {
85116 let expandList = this . state . expandList
86117 const { onGetChallenges } = this . props
87118
88- let challengeIds = _ . map ( milestone . products , ' details.challengeId' ) . slice ( 0 , 6 )
119+ let challengeIds = _ . map ( milestone . products , ` details.${ CHALLENGE_ID_MAPPING } ` ) . slice ( 0 , 6 )
89120 challengeIds = _ . filter ( challengeIds )
90121 if ( ! challengeIds . length ) {
91122 return
@@ -141,24 +172,46 @@ class ManageMilestones extends React.Component {
141172
142173 isExpandChallengeList ( milestone ) {
143174 const isExpand = _ . find ( this . state . expandList , ( i ) => i === milestone . id )
144- if ( isExpand && milestone . challenges ) {
175+ if ( isExpand ) {
145176 return true
146177 } else {
147178 return false
148179 }
149180 }
150181
151182 renderChallengeTable ( milestone ) {
183+ const {
184+ isUpdatable
185+ } = this . props
152186 if ( ! this . isExpandChallengeList ( milestone ) ) {
153187 return < tr />
154188 }
189+
190+ let challengeIds = _ . map ( milestone . products , `details.${ CHALLENGE_ID_MAPPING } ` ) . slice ( 0 , 6 )
191+ challengeIds = _ . filter ( challengeIds )
192+ // no challenges
193+ if ( ! challengeIds . length ) {
194+ return [
195+ < MilestoneChallengeHeader isUpdatable = { isUpdatable } /> ,
196+ < MilestoneChallengeRow isEmpty isUpdatable = { isUpdatable } />
197+ ]
198+ }
199+
200+ // loading challenges
201+ if ( milestone . isLoadingChallenges ) {
202+ return [
203+ < MilestoneChallengeHeader isUpdatable = { isUpdatable } /> ,
204+ < MilestoneChallengeRow isLoading isUpdatable = { isUpdatable } />
205+ ]
206+ }
207+
155208 const rows = _ . map ( milestone . challenges , ( c ) => {
156- return < MilestoneChallengeRow challenge = { c } />
209+ return < MilestoneChallengeRow challenge = { c } isUpdatable = { isUpdatable } />
157210 } )
158211 return [
159- < MilestoneChallengeHeader /> ,
212+ < MilestoneChallengeHeader isUpdatable = { isUpdatable } /> ,
160213 ...rows ,
161- < MilestoneChallengeFooter milestone = { milestone } />
214+ < MilestoneChallengeFooter milestone = { milestone } onLoadChallengesByPage = { this . onLoadChallengesByPage } isUpdatable = { isUpdatable } />
162215 ]
163216 }
164217 getSelectCount ( ) {
@@ -170,19 +223,23 @@ class ManageMilestones extends React.Component {
170223 renderAddCopilot ( ) {
171224 const {
172225 projectMembers,
226+ milestones,
173227 } = this . props
174228
229+ const seletedMilestones = _ . filter ( milestones , m => m . selected )
230+ const copilots = _ . intersectionBy ( ..._ . map ( seletedMilestones , 'members' ) , 'userId' )
175231 return (
176232 < MilestoneCopilots
177233 edit
178- customButton = { < IconCopilot /> }
179- copilots = { [ ] }
234+ customButton = { < IconCopilot styleName = "copilot-icon" /> }
235+ copilots = { copilots }
180236 projectMembers = { projectMembers }
181237 onAdd = { ( member ) => this . onAddCopilotAll ( member , true ) }
182238 onRemove = { ( member ) => this . onAddCopilotAll ( member , false ) }
183239 />
184240 )
185241 }
242+
186243 render ( ) {
187244 const {
188245 milestones,
@@ -191,6 +248,7 @@ class ManageMilestones extends React.Component {
191248 isUpdatable,
192249 } = this . props
193250
251+ const canEdit = isUpdatable && this . getSelectCount ( ) > 0
194252 return (
195253 < div >
196254 < div styleName = "toolbar" >
@@ -201,18 +259,16 @@ class ManageMilestones extends React.Component {
201259 <IconGnattView />
202260 </button>
203261 <div styleName="separator" /> */ }
204- < div styleName = "unselect-bottom" onClick = { this . onUnselectAll } >
262+ { canEdit ? < div styleName = "unselect-bottom" onClick = { this . onUnselectAll } >
205263 < IconUnselect /> { this . getSelectCount ( ) } PROJECTS SELECTED
206- </ div >
207- < div styleName = "delete-button" >
264+ </ div > : null }
265+ { canEdit ? < div styleName = "delete-button" >
208266 < MilestoneDeleteButton onDelete = { this . onDeleteAll } />
209- </ div >
210- < div styleName = "icon" >
267+ </ div > : null }
268+ { canEdit ? < div styleName = "icon" >
211269 { this . renderAddCopilot ( ) }
212- </ div >
213- < div styleName = "icon" >
214- < IconCalendar />
215- </ div >
270+ </ div > : null }
271+ { canEdit ? < MilestoneMoveDateButton onMove = { this . onMoveMilestoneDates } /> : null }
216272 { isUpdatable && (
217273 < button className = "tc-btn tc-btn-primary tc-btn-sm" styleName = "primary-button" onClick = { this . onAdd } >
218274 ADD
@@ -229,6 +285,7 @@ class ManageMilestones extends React.Component {
229285 < Formsy . Form >
230286 < table styleName = "milestones-table" >
231287 < colgroup >
288+ < col style = { { width : '20px' } } />
232289 < col style = { { width : '20px' } } /> { /* CHECKBOX */ }
233290 < col style = { { width : '8%' } } /> { /* MILESTONE */ }
234291 < col /> { /* DESCRIPTION */ }
0 commit comments