Skip to content

Commit 9d53191

Browse files
authored
Merge pull request #4455 from appirio-tech/dev
[PROD] Milestone Management
2 parents ac24c7f + 9cca4dc commit 9d53191

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1263
-350
lines changed

src/api/phaseMembers.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { axiosInstance as axios } from './requestInterceptor'
2+
import { PROJECTS_API_URL } from '../config/constants'
3+
4+
export function updatePhaseMembers(projectId, phaseId, userIds) {
5+
const url = `${PROJECTS_API_URL}/v5/projects/${projectId}/phases/${phaseId}/members`
6+
const data = { userIds }
7+
return axios.post(url, data)
8+
.then(res => res.data)
9+
}

src/api/projects.js

+13
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ export function getProjectSuggestions() {
3434
// TODO
3535
}
3636

37+
/**
38+
* Get a challenge detail based on it's id
39+
* @param {integer} challenId challenge id
40+
* @return {object} challenge detail returned by api
41+
*/
42+
export function getChallengeById(challengeId) {
43+
return axios.get(`${PROJECTS_API_URL}/v5/challenges/${challengeId}/`)
44+
.then(resp => {
45+
const res = resp.data
46+
return res
47+
})
48+
}
49+
3750

3851
/**
3952
* Get a project based on it's id

src/assets/icons/calendar.svg

+36
Loading

src/assets/icons/icon-calendar.svg

+1
Loading

src/assets/icons/icon-calendar2.svg

+3
Loading

src/assets/icons/icon-copilot.svg

+3
Loading

src/assets/icons/icon-delete.svg

+1
Loading

src/assets/icons/icon-disselect.svg

+7
Loading

src/assets/icons/icon-save2.svg

+1
Loading

src/assets/icons/icon-trash2.svg

+1
Loading

src/assets/icons/icon-ui-pencil.svg

+1-1
Loading
+1-1
Loading

src/config/constants.js

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ export const LOAD_USER_CREDENTIAL_PENDING = 'LOAD_USER_CREDENTIAL_PENDING'
1212
export const LOAD_USER_CREDENTIAL_SUCCESS = 'LOAD_USER_CREDENTIAL_SUCCESS'
1313
export const LOAD_USER_CREDENTIAL_FAILURE = 'LOAD_USER_CREDENTIAL_FAILURE'
1414

15+
// Load_CHALLEGNES
16+
export const LOAD_CHALLEGNES = 'LOAD_CHALLEGNES'
17+
export const LOAD_CHALLEGNES_PENDING = 'LOAD_CHALLEGNES_PENDING'
18+
export const LOAD_CHALLEGNES_SUCCESS = 'LOAD_CHALLEGNES_SUCCESS'
19+
export const LOAD_CHALLEGNES_FAILURE = 'Load_CHALLEGNES_FAILURE'
1520

1621
// Load organization configs
1722
export const LOAD_ORG_CONFIG_SUCCESS = 'LOAD_ORG_CONFIG_SUCCESS'
@@ -753,6 +758,8 @@ export const PROJECT_ATTACHMENTS_FOLDER = process.env.PROJECT_ATTACHMENTS_FOLDER
753758
export const FILE_PICKER_ACCEPT = process.env.FILE_PICKER_ACCEPT || ['.bmp', '.gif', '.jpg', '.tex', '.xls', '.xlsx', '.doc', '.docx', '.zip', '.txt', '.pdf', '.png', '.ppt', '.pptx', '.rtf', '.csv']
754759

755760
export const SEGMENT_KEY = process.env.CONNECT_SEGMENT_KEY
761+
762+
export const CHALLENGE_ID_MAPPING = 'challengeGuid'
756763
/*
757764
* URLs
758765
*/
@@ -766,6 +773,7 @@ export const ACCOUNTS_APP_REGISTER_URL = process.env.ACCOUNTS_APP_REGISTER_URL |
766773
export const TC_API_URL = `https://api.${DOMAIN}`
767774
export const DIRECT_PROJECT_URL = `https://www.${DOMAIN}/direct/projectOverview?formData.projectId=`
768775
export const WORK_MANAGER_APP = `https://challenges.${DOMAIN}/projects`
776+
export const CHALLENGE_DETAIL_APP = `https://www.${DOMAIN}/challenges`
769777
export const SALESFORCE_PROJECT_LEAD_LINK = process.env.SALESFORCE_PROJECT_LEAD_LINK
770778
export const SALESFORCE_BILLING_ACCOUNT_LINK = process.env.SALESFORCE_BILLING_ACCOUNT_LINK
771779
export const TC_NOTIFICATION_URL = process.env.TC_NOTIFICATION_URL || `${TC_API_URL}/v5/notifications`

src/projects/actions/phaseMember.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { updatePhaseMembers as updatePhaseMembersAPI } from '../../api/phaseMembers'
2+
3+
export function updatePhaseMembers(projectId, phaseId, userIds) {
4+
return (dispatch) => {
5+
return dispatch({
6+
type: 'UPDATE_PROJECT_PHASE_MEMBERS',
7+
payload: updatePhaseMembersAPI(projectId, phaseId, userIds)
8+
})
9+
}
10+
}

src/projects/actions/project.js

+34-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import _ from 'lodash'
22
import moment from 'moment'
33
import { flatten, unflatten } from 'flat'
44
import { getProjectById,
5+
getChallengeById,
56
createProject as createProjectAPI,
67
updateProject as updateProjectAPI,
78
deleteProject as deleteProjectAPI,
@@ -36,6 +37,7 @@ import {
3637
DELETE_PROJECT,
3738
PROJECT_DIRTY,
3839
PROJECT_DIRTY_UNDO,
40+
LOAD_CHALLEGNES,
3941
LOAD_PROJECT_PHASES,
4042
UPDATE_PRODUCT,
4143
PROJECT_STATUS_DRAFT,
@@ -161,6 +163,7 @@ export function loadProjectInvite(projectId) {
161163
}*/
162164
}
163165

166+
164167
/**
165168
* Get project phases together with products
166169
*
@@ -187,12 +190,40 @@ function getProjectPhasesWithProducts(projectId) {
187190
'spentBudget',
188191
'startDate',
189192
'status',
193+
'members',
190194
'updatedAt',
191195
'updatedBy',
192196
].join(',')
193197
})
194198
}
195199

200+
/**
201+
* Get challenges by challenge ids
202+
*
203+
* @param {Number} milestoneId milestone id
204+
* @param {Array} challengeIds challenge ids
205+
*
206+
* @returns {Promise<[]>} resolves to the list of challenge
207+
*/
208+
export function getChallengesByIds(milestoneId, challengeIds) {
209+
210+
const requests = _.map(challengeIds, id => getChallengeById(id))
211+
const challengesAPIs = Promise.all(requests)
212+
213+
return (dispatch) => {
214+
return dispatch({
215+
type: LOAD_CHALLEGNES,
216+
payload: challengesAPIs,
217+
meta: {
218+
milestoneId
219+
}
220+
})
221+
}
222+
223+
}
224+
225+
226+
196227
/**
197228
* Load project phases with populated products
198229
*
@@ -286,14 +317,12 @@ function createProductsTimelineAndMilestone(project) {
286317
*
287318
* @return {Promise} project
288319
*/
289-
export function createProjectPhaseAndProduct(project, productTemplate, status = PHASE_STATUS_DRAFT, startDate, endDate, createTimeline = true, budget, details) {
320+
export function createProjectPhaseAndProduct(project, productTemplate, status = PHASE_STATUS_DRAFT, startDate, endDate, createTimeline = true) {
290321
const param = {
291322
status,
292323
name: productTemplate.name,
293324
description: productTemplate.description,
294325
productTemplateId: productTemplate.id,
295-
budget,
296-
details,
297326
}
298327
if (startDate) {
299328
param['startDate'] = startDate.format('YYYY-MM-DD')
@@ -358,12 +387,12 @@ function createPhaseAndMilestonesRequest(project, productTemplate, status = PHAS
358387
* @param {*} startDate
359388
* @param {*} endDate
360389
*/
361-
export function createPhaseWithoutTimeline(project, productTemplate, status, startDate, endDate, budget, details) {
390+
export function createPhaseWithoutTimeline(project, productTemplate, status, startDate, endDate) {
362391
return (dispatch) => {
363392
console.log(CREATE_PROJECT_PHASE)
364393
return dispatch({
365394
type: CREATE_PROJECT_PHASE,
366-
payload: createProjectPhaseAndProduct(project, productTemplate, status, startDate, endDate, false, budget, details)
395+
payload: createProjectPhaseAndProduct(project, productTemplate, status, startDate, endDate, false)
367396
})
368397
}
369398
}

src/projects/detail/components/SimplePlan/CreateSimplePlan/CreateSimplePlan.jsx

+3-17
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
*/
44
import React from 'react'
55
import PT from 'prop-types'
6-
import _ from 'lodash'
76
import GenericMenu from '../../../../../components/GenericMenu'
87
// import ProjectDetailsWidget from '../ProjectDetailsWidget'
98
import ManageMilestones from '../ManageMilestones'
@@ -21,19 +20,6 @@ const createTabs = ({ onClick } ) => ([
2120

2221
class CreateSimplePlan extends React.Component {
2322
componentDidMount() {
24-
const { project, milestones, loadMembers } = this.props
25-
26-
let copilotIds = []
27-
milestones.forEach((milestone) => {
28-
copilotIds = copilotIds.concat(_.get(milestone, 'details.copilots', []))
29-
})
30-
31-
const projectMemberIds = project.members.map(member => member.userId)
32-
const missingMemberIds = _.difference(copilotIds, projectMemberIds)
33-
if (missingMemberIds.length) {
34-
loadMembers(missingMemberIds)
35-
}
36-
3723
const contentInnerElement = document.querySelector('.twoColsLayout-contentInner')
3824
contentInnerElement.classList.add(styles['twoColsLayout-contentInner'])
3925
}
@@ -51,8 +37,8 @@ class CreateSimplePlan extends React.Component {
5137
onChangeMilestones,
5238
onSaveMilestone,
5339
onRemoveMilestone,
40+
onGetChallenges,
5441
isProjectLive,
55-
members,
5642
isCustomer,
5743
} = this.props
5844
const onClickMilestonesTab = () => {}
@@ -83,12 +69,12 @@ class CreateSimplePlan extends React.Component {
8369
</div>
8470
<ManageMilestones
8571
milestones={milestones}
72+
onGetChallenges={onGetChallenges}
8673
onChangeMilestones={onChangeMilestones}
8774
onSaveMilestone={onSaveMilestone}
8875
onRemoveMilestone={onRemoveMilestone}
8976
projectMembers={project.members}
9077
isUpdatable={isProjectLive && !isCustomer}
91-
members={members}
9278
/>
9379
</div>
9480
</div>
@@ -103,7 +89,7 @@ CreateSimplePlan.propTypes = {
10389
onChangeMilestones: PT.func,
10490
onSaveMilestone: PT.func,
10591
onRemoveMilestone: PT.func,
106-
members: PT.object,
92+
onGetChallenges: PT.func,
10793
isCustomer: PT.bool,
10894
}
10995

0 commit comments

Comments
 (0)