diff --git a/connect-automation/page-objects/project-creation-flow/projects/projects.po.ts b/connect-automation/page-objects/project-creation-flow/projects/projects.po.ts index 795241608..0d7c5303a 100644 --- a/connect-automation/page-objects/project-creation-flow/projects/projects.po.ts +++ b/connect-automation/page-objects/project-creation-flow/projects/projects.po.ts @@ -84,7 +84,8 @@ export class ProjectsPageObject { await CommonHelper.fillInputField(searchInput, inputText); await this.searchButton.click(); - await BrowserHelper.sleep(2000); + await BrowserHelper.sleep(4000); + } /** diff --git a/connect-automation/page-objects/project-milestone/project-milestone.helper.ts b/connect-automation/page-objects/project-milestone/project-milestone.helper.ts index 9448d9d24..0f60066d9 100644 --- a/connect-automation/page-objects/project-milestone/project-milestone.helper.ts +++ b/connect-automation/page-objects/project-milestone/project-milestone.helper.ts @@ -347,9 +347,11 @@ export class ProjectMilestonePageHelper { await this.projectMilestonePageObject.yesButton.click(); logger.info('Clicked Yes button'); - const milestoneDeletionMessage = await CommonHelper.getAlertMessageAndClosePopup(); - expect(milestoneDeletionMessage).toEqual(projectMilestones.milestoneDeletionMessage); - logger.info(`Verified Delete Milestone Message ${milestoneDeletionMessage}`); + + const milestoneBulkDeletionMessage = await CommonHelper.getAlertMessageAndClosePopup(); + expect(milestoneBulkDeletionMessage).toEqual(projectMilestones.milestoneBulkDeletionMessage); + logger.info(`Verified Delete Milestone Message ${milestoneBulkDeletionMessage}`); + } /** @@ -438,9 +440,11 @@ export class ProjectMilestonePageHelper { await this.projectMilestonePageObject.yesButton.click(); logger.info('Clicked Yes button'); - const milestoneDeletionMessage = await CommonHelper.getAlertMessageAndClosePopup(); - expect(milestoneDeletionMessage).toEqual(projectMilestones.milestoneDeletionMessage); - logger.info(`Verified Delete Milestone Message ${milestoneDeletionMessage}`); + + const milestoneBulkDeletionMessage = await CommonHelper.getAlertMessageAndClosePopup(); + expect(milestoneBulkDeletionMessage).toEqual(projectMilestones.milestoneBulkDeletionMessage); + logger.info(`Verified Delete Milestone Message ${milestoneBulkDeletionMessage}`); + await BrowserHelper.waitUntilClickableOf( this.projectMilestonePageObject.getAddButton(), diff --git a/connect-automation/page-objects/project-milestone/project-milestone.model.ts b/connect-automation/page-objects/project-milestone/project-milestone.model.ts index 515f41cbc..fc3460805 100644 --- a/connect-automation/page-objects/project-milestone/project-milestone.model.ts +++ b/connect-automation/page-objects/project-milestone/project-milestone.model.ts @@ -7,6 +7,8 @@ export interface IProjectMilestone { deleteConfirmation: string; deletePopupMessage: string; milestoneDeletionMessage: string; + + milestoneBulkDeletionMessage: string; copilot: string; copilotName: string; moveMilestoneDatesTitle: string; diff --git a/connect-automation/page-objects/project-settings/project-settings.helper.ts b/connect-automation/page-objects/project-settings/project-settings.helper.ts index 141990168..511a692e5 100644 --- a/connect-automation/page-objects/project-settings/project-settings.helper.ts +++ b/connect-automation/page-objects/project-settings/project-settings.helper.ts @@ -425,7 +425,7 @@ export class ProjectSettingsPageHelper { public static async specifyUploadFilePathAndClickUploadButton() { // Specify the File Upload Path const fileToUploadElement = this.projectSettingsPageObject.selectFileToUploadButton; - const fileToUpload = '../../sample.pdf'; + const fileToUpload = '../../../sample.pdf'; let absolutePath = path.resolve(__dirname, fileToUpload); absolutePath = absolutePath.replace('/temp/', '/'); await fileToUploadElement.sendKeys(absolutePath); diff --git a/connect-automation/test-data/test-data.json b/connect-automation/test-data/test-data.json index 9f0be18a7..9d45d33cf 100644 --- a/connect-automation/test-data/test-data.json +++ b/connect-automation/test-data/test-data.json @@ -83,6 +83,8 @@ "deleteConfirmation": "Deletion Confirmation", "deletePopupMessage": "Are you sure you want to delete the selected Milestone (s)?", "milestoneDeletionMessage": "PROJECT MILESTONE DELETED.", + + "milestoneBulkDeletionMessage": "PROJECT MILESTONES DELETED.", "copilot": "Copilot", "copilotName": "TCConnCopilot", "moveMilestoneDatesTitle": "Move Milestone Dates", @@ -94,6 +96,8 @@ "inReview": "In Review", "actionOnMilestoneApprove": "approve", "milestoneApprovedMessageStr": "APPROVED MILESTONES SUCCESSFULLY.", - "allMilestoneApprovedNotificationStr": "All the milestone(s) has been approved by the customer" + + "allMilestoneApprovedNotificationStr": "The following milestone(s) has been approved" + } } \ No newline at end of file diff --git a/connect-automation/test-suites/milestone-flow/create-new-milestone.spec.ts b/connect-automation/test-suites/milestone-flow/create-new-milestone.spec.ts index 4e79a6dfd..eff9a8ccd 100644 --- a/connect-automation/test-suites/milestone-flow/create-new-milestone.spec.ts +++ b/connect-automation/test-suites/milestone-flow/create-new-milestone.spec.ts @@ -35,6 +35,8 @@ describe('Connect App - Create New Milestone Tests:', () => { it('[TC_003] Should verify user can bulk update the milestone.', async () => { await ProjectMilestonePageHelper.deleteAllMilestones(testData.projectMilestone); + + await CommonHelper.waitForAddNewMilestones(); const milestoneNames = await ProjectMilestonePageHelper.addMilestones(testData.projectMilestone, 2, testData.projectMilestone.active); await ProjectMilestonePageHelper.verifyUserCanBulkUpdateTheMilestone(testData.projectMilestone); }); diff --git a/connect-automation/test-suites/project-settings-flow/project-settings.spec.ts b/connect-automation/test-suites/project-settings-flow/project-settings.spec.ts index ed30ac073..809dc6cbb 100644 --- a/connect-automation/test-suites/project-settings-flow/project-settings.spec.ts +++ b/connect-automation/test-suites/project-settings-flow/project-settings.spec.ts @@ -1,3 +1,4 @@ +import { BrowserHelper } from 'topcoder-testing-lib'; import { CommonHelper } from '../../page-objects/common-page/common.helper'; import { ProjectSettingsPageHelper } from '../../page-objects/project-settings/project-settings.helper' import * as testData from '../../test-data/test-data.json'; @@ -42,18 +43,21 @@ describe('Connect App - Project Settings Tests:', () => { it('[TC_003] Should verify user can Add/Edit/Delete/Download Files', async () => { await CommonHelper.goToRecentlyCreatedProject(); + await BrowserHelper.sleep(5000); await CommonHelper.waitForAddNewMilestones(); await ProjectSettingsPageHelper.verifyUserCanAddEditDeleteDownloadFiles(testData.projectSettings); }); it('[TC_004] Should verify user can Add/Edit/Delete/Download Links', async () => { await CommonHelper.goToRecentlyCreatedProject(); + await BrowserHelper.sleep(5000); await CommonHelper.waitForAddNewMilestones(); await ProjectSettingsPageHelper.verifyUserCanAddEditDeleteDownloadLinks(testData.projectSettings); }); it('[TC_005] Should verify user can Add Message with Files Attachment', async () => { await CommonHelper.goToRecentlyCreatedProject(); + await BrowserHelper.sleep(5000); await CommonHelper.waitForAddNewMilestones(); await ProjectSettingsPageHelper.verifyUserCanAddMessageWithFileAttachment(testData.projectSettings); }); diff --git a/src/api/projects.js b/src/api/projects.js index 17cc966da..950a39e7c 100644 --- a/src/api/projects.js +++ b/src/api/projects.js @@ -223,3 +223,8 @@ export function deleteProjectPhase(projectId, phaseId) { return axios.delete(`${PROJECTS_API_URL}/v5/projects/${projectId}/phases/${phaseId}`) .then(() => ({ projectId, phaseId })) } + +export function deleteBulkProjectPhase(projectId, phaseIds) { + return axios.delete(`${PROJECTS_API_URL}/v5/projects/${projectId}/phases`, { data: { phaseIds } }) + .then(() => ({ phaseIds })) +} diff --git a/src/config/constants.js b/src/config/constants.js index 0b27005a0..420aeda9f 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -300,6 +300,11 @@ export const DELETE_PROJECT_PHASE_PENDING = 'DELETE_PROJECT_PHASE_PENDING' export const DELETE_PROJECT_PHASE_FAILURE = 'DELETE_PROJECT_PHASE_FAILURE' export const DELETE_PROJECT_PHASE_SUCCESS = 'DELETE_PROJECT_PHASE_SUCCESS' +export const DELETE_BULK_PROJECT_PHASE = 'DELETE_BULK_PROJECT_PHASE' +export const DELETE_BULK_PROJECT_PHASE_PENDING = 'DELETE_BULK_PROJECT_PHASE_PENDING' +export const DELETE_BULK_PROJECT_PHASE_FAILURE = 'DELETE_BULK_PROJECT_PHASE_FAILURE' +export const DELETE_BULK_PROJECT_PHASE_SUCCESS = 'DELETE_BULK_PROJECT_PHASE_SUCCESS' + export const UPDATE_PRODUCT = 'UPDATE_PRODUCT' export const UPDATE_PRODUCT_PENDING = 'UPDATE_PRODUCT_PENDING' export const UPDATE_PRODUCT_SUCCESS = 'UPDATE_PRODUCT_SUCCESS' diff --git a/src/config/permissions.js b/src/config/permissions.js index 82e33250d..0b26002e5 100644 --- a/src/config/permissions.js +++ b/src/config/permissions.js @@ -249,7 +249,7 @@ export const PERMISSIONS = { description: 'Remove copilots form the project.', }, projectRoles: [ - ..._.difference(PROJECT_ALL, [PROJECT_ROLE_COPILOT, PROJECT_ROLE_CUSTOMER]) + ..._.difference(PROJECT_ALL, [PROJECT_ROLE_CUSTOMER]) ], topcoderRoles: [ ...TOPCODER_ADMINS, diff --git a/src/projects/actions/project.js b/src/projects/actions/project.js index 6bcb8aff7..aedb88427 100644 --- a/src/projects/actions/project.js +++ b/src/projects/actions/project.js @@ -7,6 +7,7 @@ import { getProjectById, updateProject as updateProjectAPI, deleteProject as deleteProjectAPI, deleteProjectPhase as deleteProjectPhaseAPI, + deleteBulkProjectPhase as deleteBulkProjectPhaseAPI, getProjectPhases, updateProduct as updateProductAPI, updatePhase as updatePhaseAPI, @@ -79,7 +80,8 @@ import { CUSTOMER_APPROVE_MILESTONE_APPROVE_SUCCESS, CUSTOMER_APPROVE_MILESTONE_REJECT_FAILURE, CUSTOMER_APPROVE_MILESTONE_APPROVE_FAILURE, - CUSTOMER_APPROVE_MILESTONE_REJECT_SUCCESS + CUSTOMER_APPROVE_MILESTONE_REJECT_SUCCESS, + DELETE_BULK_PROJECT_PHASE } from '../../config/constants' import { updateProductMilestone, @@ -334,6 +336,11 @@ export function createProjectPhaseAndProduct(project, productTemplate, status = description: productTemplate.description, productTemplateId: productTemplate.id, } + + if(productTemplate.members) { + param.members = productTemplate.members + } + if (startDate) { param['startDate'] = startDate.format('YYYY-MM-DD') } @@ -441,6 +448,15 @@ export function deleteProjectPhase(projectId, phaseId) { } } +export function deleteBulkProjectPhase(projectId, phaseIds) { + return (dispatch) => { + return dispatch({ + type: DELETE_BULK_PROJECT_PHASE, + payload: deleteBulkProjectPhaseAPI(projectId, phaseIds) + }) + } +} + export function updateProject(projectId, updatedProps, updateExisting = false) { return (dispatch) => { return dispatch({ diff --git a/src/projects/detail/components/SimplePlan/CreateSimplePlan/CreateSimplePlan.jsx b/src/projects/detail/components/SimplePlan/CreateSimplePlan/CreateSimplePlan.jsx index 10a37ccfe..34d0c65e3 100644 --- a/src/projects/detail/components/SimplePlan/CreateSimplePlan/CreateSimplePlan.jsx +++ b/src/projects/detail/components/SimplePlan/CreateSimplePlan/CreateSimplePlan.jsx @@ -10,6 +10,7 @@ import * as milestoneHelper from '../components/helpers/milestone' import styles from './CreateSimplePlan.scss' import MilestonesApprovalNotification from '../components/MilestonesApprovalNotification' +import { PHASE_STATUS_IN_REVIEW } from '../../../../../config/constants' const createTabs = ({ onClick } ) => ([ { @@ -39,6 +40,7 @@ class CreateSimplePlan extends React.Component { onChangeMilestones, onSaveMilestone, onRemoveMilestone, + onRemoveAllMilestones, onGetChallenges, onApproveMilestones, isProjectLive, @@ -46,6 +48,10 @@ class CreateSimplePlan extends React.Component { } = this.props const onClickMilestonesTab = () => {} + const isInReview = + isCustomer ? (milestones.filter( x => x.status === PHASE_STATUS_IN_REVIEW).length > 0 && isProjectLive) + : isProjectLive + if (milestones.length === 0) { return isCustomer ? null : (
: null} - |
- |
+ + { + hideCheckbox ? null : |
+ |
+ }
MILESTONE | DESCRIPTION | START DATE | @@ -54,6 +56,7 @@ function MilestoneHeaderRow ({ milestones, onChangeMilestones, isUpdatable }) { MilestoneHeaderRow.propTypes = { onChangeMilestones: PT.func, + hideCheckbox: PT.bool, } export default MilestoneHeaderRow diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneRow/MilestoneRow.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneRow/MilestoneRow.jsx index 47ebf9e32..93024fb94 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneRow/MilestoneRow.jsx +++ b/src/projects/detail/components/SimplePlan/components/MilestoneRow/MilestoneRow.jsx @@ -45,7 +45,9 @@ function MilestoneRow({ phaseMembers, disableDeleteAction, isCustomer, - isApproving + isApproving, + hideCheckbox, + isInReview }) { const isNeedApproval = milestone.status === PHASE_STATUS_IN_REVIEW const showApproval = isCustomer && isNeedApproval @@ -58,11 +60,12 @@ function MilestoneRow({ let milestoneRef let startDateRef let endDateRef + const tdEl = hideCheckbox ? null :return edit ? ( | |||
---|---|---|---|---|---|---|---|---|---|---|
: null} - {isEditingMilestone ? | : | + {(isEditingMilestone || hideCheckbox) ? | : |
onExpand(!isExpand, milestone)}>{isExpand ? | : }
- {isEditingMilestone ? | : |
+ {(isEditingMilestone || hideCheckbox) ? tdEl : |
|
|
{
@@ -402,6 +405,8 @@ MilestoneRow.propTypes = {
disableDeleteAction: PT.bool,
isCustomer: PT.bool,
members: PT.object,
+ hideCheckbox: PT.bool,
+ isInReview: PT.bool,
}
export default MilestoneRow
diff --git a/src/projects/detail/containers/DashboardContainer.jsx b/src/projects/detail/containers/DashboardContainer.jsx
index e8b42b1f6..d9cbd75ce 100644
--- a/src/projects/detail/containers/DashboardContainer.jsx
+++ b/src/projects/detail/containers/DashboardContainer.jsx
@@ -26,6 +26,7 @@ import {
fireProductDirty,
fireProductDirtyUndo,
deleteProjectPhase,
+ deleteBulkProjectPhase,
expandProjectPhase,
collapseProjectPhase,
collapseAllProjectPhases,
@@ -53,7 +54,6 @@ import { updateProject, fireProjectDirty, fireProjectDirtyUndo, updatePhase, exe
import { addProjectAttachment, updateProjectAttachment, removeProjectAttachment } from '../../actions/projectAttachment'
import ProjectEstimation from '../../create/components/ProjectEstimation'
import CreateSimplePlan from '../components/SimplePlan/CreateSimplePlan'
-import { updatePhaseMembers } from '../../actions/phaseMember'
import {
PHASE_STATUS_ACTIVE,
@@ -94,6 +94,7 @@ class DashboardContainer extends React.Component {
this.onChangeMilestones = this.onChangeMilestones.bind(this)
this.onSaveMilestone = this.onSaveMilestone.bind(this)
this.onRemoveMilestone = this.onRemoveMilestone.bind(this)
+ this.onRemoveAllMilestones = this.onRemoveAllMilestones.bind(this)
this.onGetChallenges = this.onGetChallenges.bind(this)
this.onApproveMilestones = this.onApproveMilestones.bind(this)
}
@@ -188,23 +189,20 @@ class DashboardContainer extends React.Component {
const { createGameplanPhases } = this.state
const index = createGameplanPhases.findIndex(phase => phase.id === id)
const phase = createGameplanPhases[index]
+
- /*
- * @return {Promise} The updated phase members
+ /**
+ * Helper function to get changes in members
*/
- const updatePhaseMembers = (projectId, phaseId) => {
+ const getUpdatedPhaseMembers = () => {
const phaseMembers = _.get(phase, 'members', [])
const oldPhaseMembers = _.get(phase, 'origin.members', [])
- if (phaseMembers.length !== oldPhaseMembers.length ||
- _.differenceBy(phaseMembers, oldPhaseMembers, member => member.userId).length !== 0) {
- return this.props.updatePhaseMembers(
- projectId,
- phaseId,
- phaseMembers.map(member => member.userId)
- ).then(() => phaseMembers) // ignore the result from backend
+ const updatedPhaseMembers =
+ _.differenceBy(phaseMembers, oldPhaseMembers, member => member.userId)
+ if(phaseMembers.length !== oldPhaseMembers.length || updatedPhaseMembers.length !== 0) {
+ return phaseMembers
}
-
- return Promise.resolve(phaseMembers)
+ return null
}
if (`${phase.id}`.startsWith('new-milestone')) {
@@ -217,8 +215,11 @@ class DashboardContainer extends React.Component {
productTemplate.description = phase.description.trim()
}
- const projectId = project.id
- let phaseId
+ const phaseMembers = getUpdatedPhaseMembers()
+ if(phaseMembers !== null) {
+ productTemplate.members = phaseMembers.map(member => member.userId)
+ }
+
createPhaseWithoutTimeline(
project,
productTemplate,
@@ -226,26 +227,13 @@ class DashboardContainer extends React.Component {
moment.utc(phase.startDate),
moment.utc(phase.endDate)
).then(({ action }) => {
- phaseId = action.payload.phase.id
// reload phase
const updatedCreateGameplanPhases = [...this.state.createGameplanPhases]
updatedCreateGameplanPhases.splice(index, 1, {
...action.payload.phase,
selected: phase.selected,
})
- this.setState({ createGameplanPhases: updatedCreateGameplanPhases }, () => {
- updatePhaseMembers(projectId, phaseId)
- .then((members) => {
- // reload members
- const updatedPhases = [...this.state.createGameplanPhases]
- updatedPhases.splice(index, 1, {
- ...updatedPhases[index],
- members
- })
- this.setState({ createGameplanPhases: updatedPhases })
- })
- })
-
+ this.setState({ createGameplanPhases: updatedCreateGameplanPhases })
})
} else {
const updateParam = {
@@ -259,14 +247,16 @@ class DashboardContainer extends React.Component {
updateParam.description = phase.description.trim()
}
- Promise.all([
- updatePhase(
- phase.projectId,
- phase.id,
- updateParam
- ),
- updatePhaseMembers(phase.projectId, phase.id)
- ]).then(([{ action }, members]) => {
+ const phaseMembers = getUpdatedPhaseMembers()
+ if(phaseMembers !== null) {
+ updateParam.members = phaseMembers.map(member => member.userId)
+ }
+
+ updatePhase(
+ phase.projectId,
+ phase.id,
+ updateParam
+ ).then(({ action }) => {
const updatedCreateGameplanPhases = [...this.state.createGameplanPhases]
const idx = updatedCreateGameplanPhases.findIndex(phase => phase.id === action.payload.id)
@@ -275,7 +265,8 @@ class DashboardContainer extends React.Component {
...action.payload,
edit: this.state.createGameplanPhases[idx].edit,
selected: this.state.createGameplanPhases[idx].selected,
- members
+ products: this.state.createGameplanPhases[idx].products,
+ challenges: this.state.createGameplanPhases[idx].challenges,
})
this.setState({ createGameplanPhases: updatedCreateGameplanPhases })
})
@@ -321,6 +312,21 @@ class DashboardContainer extends React.Component {
})
}
+ onRemoveAllMilestones(projectId, phaseIds) {
+ this.props.deleteBulkProjectPhase(
+ projectId,
+ phaseIds
+ ).then(() => {
+ if (!this.state.createGameplanPhases) {
+ return
+ }
+
+ // remove phases
+ const newGameplanPhases = this.state.createGameplanPhases.filter(phase => !phaseIds.includes(phase.id))
+ this.setState({createGameplanPhases: newGameplanPhases})
+ })
+ }
+
render() {
const {
@@ -523,6 +529,7 @@ class DashboardContainer extends React.Component {
onSaveMilestone={this.onSaveMilestone}
onGetChallenges={this.onGetChallenges}
onRemoveMilestone={this.onRemoveMilestone}
+ onRemoveAllMilestones={this.onRemoveAllMilestones}
onApproveMilestones={this.onApproveMilestones}
/>
)
@@ -575,6 +582,7 @@ const mapDispatchToProps = {
updateProductAttachment,
removeProductAttachment,
deleteProjectPhase,
+ deleteBulkProjectPhase,
expandProjectPhase,
collapseProjectPhase,
collapseAllProjectPhases,
@@ -585,7 +593,6 @@ const mapDispatchToProps = {
updateProjectAttachment,
removeProjectAttachment,
updatePhase,
- updatePhaseMembers,
executePhaseApproval,
approveMilestone
}
diff --git a/src/projects/reducers/project.js b/src/projects/reducers/project.js
index d6b11b9f0..b04a79c62 100644
--- a/src/projects/reducers/project.js
+++ b/src/projects/reducers/project.js
@@ -26,7 +26,7 @@ import {
ACCEPT_OR_REFUSE_INVITE_SUCCESS, ACCEPT_OR_REFUSE_INVITE_FAILURE, ACCEPT_OR_REFUSE_INVITE_PENDING,
UPLOAD_PROJECT_ATTACHMENT_FILES, DISCARD_PROJECT_ATTACHMENT, CHANGE_ATTACHMENT_PERMISSION,
CREATE_SCOPE_CHANGE_REQUEST_SUCCESS, APPROVE_SCOPE_CHANGE_SUCCESS, REJECT_SCOPE_CHANGE_SUCCESS, CANCEL_SCOPE_CHANGE_SUCCESS, ACTIVATE_SCOPE_CHANGE_SUCCESS,
- LOAD_PROJECT_MEMBERS_SUCCESS, LOAD_PROJECT_MEMBER_INVITES_SUCCESS, LOAD_PROJECT_MEMBER_SUCCESS, CREATE_PROJECT_PHASE_PENDING, CREATE_PROJECT_PHASE_SUCCESS, CUSTOMER_APPROVE_MILESTONE_PENDING, CUSTOMER_APPROVE_MILESTONE_FINISHED,
+ LOAD_PROJECT_MEMBERS_SUCCESS, LOAD_PROJECT_MEMBER_INVITES_SUCCESS, LOAD_PROJECT_MEMBER_SUCCESS, CREATE_PROJECT_PHASE_PENDING, CREATE_PROJECT_PHASE_SUCCESS, CUSTOMER_APPROVE_MILESTONE_PENDING, CUSTOMER_APPROVE_MILESTONE_FINISHED, DELETE_BULK_PROJECT_PHASE_PENDING, DELETE_BULK_PROJECT_PHASE_SUCCESS,
} from '../../config/constants'
import _ from 'lodash'
import update from 'react-addons-update'
@@ -519,6 +519,7 @@ export const projectState = function (state=initialState, action) {
case UPDATE_PROJECT_PENDING:
case UPDATE_PHASE_PENDING:
case DELETE_PROJECT_PHASE_PENDING:
+ case DELETE_BULK_PROJECT_PHASE_PENDING:
return Object.assign({}, state, {
isLoading: false,
processing: true,
@@ -562,6 +563,18 @@ export const projectState = function (state=initialState, action) {
})
}
+ case DELETE_BULK_PROJECT_PHASE_SUCCESS: {
+ const { phaseIds } = action.payload
+
+ const newPhases = state.phases.filter(phase => !phaseIds.includes(phase.id))
+
+ return Object.assign({}, state, {
+ phases: newPhases,
+ phasesNonDirty: newPhases,
+ processing: false,
+ })
+ }
+
case UPDATE_PRODUCT_SUCCESS:
return {
...state,
diff --git a/src/reducers/alerts.js b/src/reducers/alerts.js
index da1b345e3..6de87290c 100644
--- a/src/reducers/alerts.js
+++ b/src/reducers/alerts.js
@@ -77,7 +77,8 @@ import {
CUSTOMER_APPROVE_MILESTONE_APPROVE_SUCCESS,
CUSTOMER_APPROVE_MILESTONE_REJECT_SUCCESS,
CUSTOMER_APPROVE_MILESTONE_APPROVE_FAILURE,
- CUSTOMER_APPROVE_MILESTONE_REJECT_FAILURE
+ CUSTOMER_APPROVE_MILESTONE_REJECT_FAILURE,
+ DELETE_BULK_PROJECT_PHASE_SUCCESS
} from '../config/constants'
/* eslint-enable no-unused-vars */
@@ -112,6 +113,16 @@ export default function(state = {}, action) {
return state
}
+ case DELETE_BULK_PROJECT_PHASE_SUCCESS: {
+ if (state.project.version === 'v4') {
+ Alert.success('Project milestones deleted.')
+ } else {
+ Alert.success('Project phases deleted.')
+ }
+
+ return state
+ }
+
case DELETE_PROJECT_SUCCESS:
Alert.success('Project deleted.')
return state
|