From d2d6a76d92a05b5a5e147695cf2d4d037b0fecdf Mon Sep 17 00:00:00 2001 From: Nguyen Viet Date: Sat, 24 Jul 2021 21:50:30 +0700 Subject: [PATCH 01/18] integrate with phase member api --- src/api/phaseMembers.js | 9 +++++++ src/projects/actions/phaseMember.js | 10 +++++++ src/projects/actions/project.js | 8 +++--- .../ManageMilestones/ManageMilestones.jsx | 1 + .../MilestoneHeaderRow/MilestoneHeaderRow.jsx | 2 +- .../components/MilestoneRow/MilestoneRow.jsx | 25 +++++++++--------- .../detail/containers/DashboardContainer.jsx | 26 +++++++++++++------ 7 files changed, 56 insertions(+), 25 deletions(-) create mode 100644 src/api/phaseMembers.js create mode 100644 src/projects/actions/phaseMember.js diff --git a/src/api/phaseMembers.js b/src/api/phaseMembers.js new file mode 100644 index 000000000..60782e834 --- /dev/null +++ b/src/api/phaseMembers.js @@ -0,0 +1,9 @@ +import { axiosInstance as axios } from './requestInterceptor' +import { PROJECTS_API_URL } from '../config/constants' + +export function updatePhaseMembers(projectId, phaseId, userIds) { + const url = `${PROJECTS_API_URL}/v5/projects/${projectId}/phases/${phaseId}/members` + const data = { userIds } + return axios.post(url, data) + .then(res => res.data) +} diff --git a/src/projects/actions/phaseMember.js b/src/projects/actions/phaseMember.js new file mode 100644 index 000000000..8cbb5ec42 --- /dev/null +++ b/src/projects/actions/phaseMember.js @@ -0,0 +1,10 @@ +import { updatePhaseMembers as updatePhaseMembersAPI } from '../../api/phaseMembers' + +export function updatePhaseMembers(projectId, phaseId, userIds) { + return (dispatch) => { + return dispatch({ + type: 'UPDATE_PROJECT_PHASE_MEMBERS', + payload: updatePhaseMembersAPI(projectId, phaseId, userIds) + }) + } +} diff --git a/src/projects/actions/project.js b/src/projects/actions/project.js index 51278d20c..0aef4b35a 100644 --- a/src/projects/actions/project.js +++ b/src/projects/actions/project.js @@ -187,6 +187,7 @@ function getProjectPhasesWithProducts(projectId) { 'spentBudget', 'startDate', 'status', + 'members', 'updatedAt', 'updatedBy', ].join(',') @@ -286,14 +287,13 @@ function createProductsTimelineAndMilestone(project) { * * @return {Promise} project */ -export function createProjectPhaseAndProduct(project, productTemplate, status = PHASE_STATUS_DRAFT, startDate, endDate, createTimeline = true, budget, details) { +export function createProjectPhaseAndProduct(project, productTemplate, status = PHASE_STATUS_DRAFT, startDate, endDate, createTimeline = true, budget) { const param = { status, name: productTemplate.name, description: productTemplate.description, productTemplateId: productTemplate.id, budget, - details, } if (startDate) { param['startDate'] = startDate.format('YYYY-MM-DD') @@ -358,12 +358,12 @@ function createPhaseAndMilestonesRequest(project, productTemplate, status = PHAS * @param {*} startDate * @param {*} endDate */ -export function createPhaseWithoutTimeline(project, productTemplate, status, startDate, endDate, budget, details) { +export function createPhaseWithoutTimeline(project, productTemplate, status, startDate, endDate, budget) { return (dispatch) => { console.log(CREATE_PROJECT_PHASE) return dispatch({ type: CREATE_PROJECT_PHASE, - payload: createProjectPhaseAndProduct(project, productTemplate, status, startDate, endDate, false, budget, details) + payload: createProjectPhaseAndProduct(project, productTemplate, status, startDate, endDate, false, budget) }) } } diff --git a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx index 241c378d4..894f4316c 100644 --- a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx +++ b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx @@ -130,6 +130,7 @@ class ManageMilestones extends React.Component { isCreatingRow={`${milestone.id}`.startsWith('new-milestone')} isUpdatable={isUpdatable} members={members} + phaseMembers={milestone.members} /> ))} diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneHeaderRow/MilestoneHeaderRow.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneHeaderRow/MilestoneHeaderRow.jsx index 6822d19b1..813f4c795 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneHeaderRow/MilestoneHeaderRow.jsx +++ b/src/projects/detail/components/SimplePlan/components/MilestoneHeaderRow/MilestoneHeaderRow.jsx @@ -46,7 +46,7 @@ function MilestoneHeaderRow ({ milestones, onChangeMilestones, isUpdatable }) { END DATE STATUS BUDGET - {/* COPILOTS */} + COPILOTS {isUpdatable && (ACTION)} ) diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneRow/MilestoneRow.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneRow/MilestoneRow.jsx index 4c7a5bd26..533f49961 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneRow/MilestoneRow.jsx +++ b/src/projects/detail/components/SimplePlan/components/MilestoneRow/MilestoneRow.jsx @@ -9,7 +9,7 @@ import _ from 'lodash' import { components } from 'react-select' import { isValidStartEndDates } from '../../../../../../helpers/utils' import FormsySelect from '../../../../../../components/Select/FormsySelect' -// import MilestoneCopilots from '../MilestoneCopilots' +import MilestoneCopilots from '../MilestoneCopilots' import MilestoneStatus from '../MilestoneStatus' import MilestoneBudget from '../MilestoneBudget' import MilestoneDeleteButton from '../MilestoneDeleteButton' @@ -36,10 +36,11 @@ function MilestoneRow({ isCreatingRow, isUpdatable, members, + phaseMembers, }) { const phaseStatusOptions = PHASE_STATUS_OPTIONS const edit = milestone.edit - const copilotIds = _.get(milestone, 'details.copilots', []) + const copilotIds = (phaseMembers || []).map(i => i.userId) let copilots = copilotIds.map(userId => projectMembers.find(member => member.userId === userId)).filter(Boolean) if (copilots.length !== copilotIds.length) { @@ -221,7 +222,7 @@ function MilestoneRow({ innerRef={ref => budgetRef = ref} /> - {/* + copilot.userId).concat(member.userId) - onChange({...milestone, details: { ...details, copilots: copilotIdsUpdated } }) + const copilotsUpdated = copilots + .concat(member) + onChange({...milestone, members: copilotsUpdated }) }} onRemove={(member) => { if (!milestone.origin) { milestone.origin = {...milestone} } - const details = milestone.details - const copilotIdsUpdated = copilots.filter(copilot => copilot.userId !== member.userId).map(copilot => copilot.userId) - onChange({...milestone, details: { ...details, copilots: copilotIdsUpdated } }) + const copilotsUpdated = copilots + .filter(copilot => copilot.userId !== member.userId) + onChange({...milestone, members: copilotsUpdated }) }} /> - */} +
*/} +
+ {this.getSelectCount()} PROJECTS SELECTED +
+
+ +
+
+ {this.renderAddCopilot()} +
+
+ +
{isUpdatable && ( + } {open && ( @@ -66,6 +67,7 @@ MilestoneCopilots.propTypes = { edit: PT.bool, copilots: PT.arrayOf(PT.shape()), projectMembers: PT.arrayOf(PT.shape()), + customButton: PT.element, onAdd: PT.func, onRemove: PT.func, } diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneHeaderRow/MilestoneHeaderRow.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneHeaderRow/MilestoneHeaderRow.jsx index ddbded24f..b49df0870 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneHeaderRow/MilestoneHeaderRow.jsx +++ b/src/projects/detail/components/SimplePlan/components/MilestoneHeaderRow/MilestoneHeaderRow.jsx @@ -31,6 +31,7 @@ function MilestoneHeaderRow ({ milestones, onChangeMilestones, isUpdatable }) { return ( + + ) : ( + onExpand(!isExpand, milestone)}>{isExpand ? : } svg { + height: 13px; + } + } .checkbox {} diff --git a/src/projects/detail/containers/DashboardContainer.jsx b/src/projects/detail/containers/DashboardContainer.jsx index 509c15368..dc5e8f402 100644 --- a/src/projects/detail/containers/DashboardContainer.jsx +++ b/src/projects/detail/containers/DashboardContainer.jsx @@ -31,6 +31,7 @@ import { collapseAllProjectPhases, createPhaseAndMilestones, createPhaseWithoutTimeline, + getChallengesByIds, } from '../../actions/project' import { addProductAttachment, updateProductAttachment, removeProductAttachment } from '../../actions/projectAttachment' @@ -90,6 +91,10 @@ class DashboardContainer extends React.Component { this.onChangeMilestones = this.onChangeMilestones.bind(this) this.onSaveMilestone = this.onSaveMilestone.bind(this) this.onRemoveMilestone = this.onRemoveMilestone.bind(this) + this.onGetChallenges = this.onGetChallenges.bind(this) + } + onGetChallenges(milestoneId, challengeIds) { + this.props.getChallengesByIds(milestoneId, challengeIds) } onNotificationRead(notification) { @@ -477,6 +482,7 @@ class DashboardContainer extends React.Component { milestones={this.state.createGameplanPhases || visiblePhases || []} onChangeMilestones={this.onChangeMilestones} onSaveMilestone={this.onSaveMilestone} + onGetChallenges={this.onGetChallenges} onRemoveMilestone={this.onRemoveMilestone} /> ) @@ -521,6 +527,7 @@ const mapDispatchToProps = { updateProduct, createPhaseAndMilestones, createPhaseWithoutTimeline, + getChallengesByIds, fireProductDirty, fireProductDirtyUndo, addProductAttachment, diff --git a/src/projects/reducers/project.js b/src/projects/reducers/project.js index a877ce308..e7cf932ec 100644 --- a/src/projects/reducers/project.js +++ b/src/projects/reducers/project.js @@ -9,6 +9,7 @@ import { UPDATE_PROJECT_ATTACHMENT_PENDING, UPDATE_PROJECT_ATTACHMENT_SUCCESS, UPDATE_PROJECT_ATTACHMENT_FAILURE, REMOVE_PROJECT_ATTACHMENT_PENDING, REMOVE_PROJECT_ATTACHMENT_SUCCESS, REMOVE_PROJECT_ATTACHMENT_FAILURE, REMOVE_PENDING_ATTACHMENT, UPDATE_PENDING_ATTACHMENT, + LOAD_CHALLEGNES_PENDING, LOAD_CHALLEGNES_SUCCESS, ADD_PRODUCT_ATTACHMENT_PENDING, ADD_PRODUCT_ATTACHMENT_SUCCESS, ADD_PRODUCT_ATTACHMENT_FAILURE, UPDATE_PRODUCT_ATTACHMENT_PENDING, UPDATE_PRODUCT_ATTACHMENT_SUCCESS, UPDATE_PRODUCT_ATTACHMENT_FAILURE, REMOVE_PRODUCT_ATTACHMENT_PENDING, REMOVE_PRODUCT_ATTACHMENT_SUCCESS, REMOVE_PRODUCT_ATTACHMENT_FAILURE, @@ -163,6 +164,29 @@ export const projectState = function (state=initialState, action) { ...state, isBillingAccountExpired: false, } + case LOAD_CHALLEGNES_PENDING: { + + const phaseIndex = _.findIndex(state.phases, { id: action.meta.milestoneId }) + + const phase = { + ...state.phases[phaseIndex], + isLoadingChallenges: true + } + return update(state, { + phases: { $splice: [[phaseIndex, 1, phase]] }, + }) + } + case LOAD_CHALLEGNES_SUCCESS: { + const phaseIndex = _.findIndex(state.phases, { id: action.meta.milestoneId }) + const phase = { + ...state.phases[phaseIndex], + challenges: action.payload, + isLoadingChallenges: false + } + return update(state, { + phases: { $splice: [[phaseIndex, 1, phase]] }, + }) + } case CREATE_PROJECT_PHASE_TIMELINE_MILESTONES_SUCCESS: case CREATE_PROJECT_PHASE_SUCCESS: { const { phase, product } = action.payload From 9ba9f6c953a9a0b5d48a9ea43ad1febfabc8a13a Mon Sep 17 00:00:00 2001 From: yoution Date: Wed, 4 Aug 2021 23:33:28 +0800 Subject: [PATCH 11/18] fix: fix issues --- config/constants/dev.js | 1 + config/constants/master.js | 1 + src/assets/icons/icon-calendar2.svg | 1 + src/assets/icons/icon-copilot.svg | 7 +- src/assets/icons/icon-trash2.svg | 7 +- src/config/constants.js | 2 + .../ManageMilestones/ManageMilestones.jsx | 90 +++++++++++++++---- .../ManageMilestones/ManageMilestones.scss | 16 +++- .../ConfirmMoveMilestoneDate.jsx | 50 +++++++++++ .../ConfirmMoveMilestoneDate.scss | 59 ++++++++++++ .../ConfirmMoveMilestoneDate/index.js | 2 + .../MilestoneChallengeFooter.jsx | 35 +++++--- .../MilestoneChallengeFooter.scss | 6 ++ .../MilestoneChallengeHeader.jsx | 10 ++- .../MilestoneChallengeHeader.scss | 1 - .../MilestoneChallengeRow.jsx | 49 +++++++--- .../MilestoneChallengeRow.scss | 14 +-- .../MilestoneMoveDateButton.jsx | 87 ++++++++++++++++++ .../MilestoneMoveDateButton.scss | 21 +++++ .../MilestoneMoveDateButton/index.jsx | 2 + src/projects/reducers/project.js | 14 ++- 21 files changed, 408 insertions(+), 67 deletions(-) create mode 100644 src/assets/icons/icon-calendar2.svg create mode 100644 src/projects/detail/components/SimplePlan/components/ConfirmMoveMilestoneDate/ConfirmMoveMilestoneDate.jsx create mode 100644 src/projects/detail/components/SimplePlan/components/ConfirmMoveMilestoneDate/ConfirmMoveMilestoneDate.scss create mode 100644 src/projects/detail/components/SimplePlan/components/ConfirmMoveMilestoneDate/index.js create mode 100644 src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/MilestoneMoveDateButton.jsx create mode 100644 src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/MilestoneMoveDateButton.scss create mode 100644 src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/index.jsx diff --git a/config/constants/dev.js b/config/constants/dev.js index e2f2ba1d6..1972ccea5 100644 --- a/config/constants/dev.js +++ b/config/constants/dev.js @@ -57,6 +57,7 @@ module.exports = { DASHBOARD_FAQ_CONTENT_ID : process.env.DASHBOARD_FAQ_CONTENT_ID, CONTENTFUL_DELIVERY_KEY : process.env.CONTENTFUL_DELIVERY_KEY, CONTENTFUL_SPACE_ID : process.env.CONTENTFUL_SPACE_ID, + CHALLENGE_ID_MAPPING: process.env.CHALLENGE_ID_MAPPING, TAAS_APP_URL: 'https://platform.topcoder-dev.com/taas', DEFAULT_NDA_UUID: 'e5811a7b-43d1-407a-a064-69e5015b4900' diff --git a/config/constants/master.js b/config/constants/master.js index ec979e937..79c1594ea 100644 --- a/config/constants/master.js +++ b/config/constants/master.js @@ -57,6 +57,7 @@ module.exports = { DASHBOARD_FAQ_CONTENT_ID : process.env.DASHBOARD_FAQ_CONTENT_ID, CONTENTFUL_DELIVERY_KEY : process.env.CONTENTFUL_DELIVERY_KEY, CONTENTFUL_SPACE_ID : process.env.CONTENTFUL_SPACE_ID, + CHALLENGE_ID_MAPPING: process.env.CHALLENGE_ID_MAPPING, TAAS_APP_URL: 'https://platform.topcoder.com/taas', DEFAULT_NDA_UUID: 'c41e90e5-4d0e-4811-bd09-38ff72674490' diff --git a/src/assets/icons/icon-calendar2.svg b/src/assets/icons/icon-calendar2.svg new file mode 100644 index 000000000..b2ebdd5ba --- /dev/null +++ b/src/assets/icons/icon-calendar2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/icon-copilot.svg b/src/assets/icons/icon-copilot.svg index 7cfcab478..3ed5897d0 100644 --- a/src/assets/icons/icon-copilot.svg +++ b/src/assets/icons/icon-copilot.svg @@ -1,6 +1 @@ - - - - - - + \ No newline at end of file diff --git a/src/assets/icons/icon-trash2.svg b/src/assets/icons/icon-trash2.svg index e95e0abae..b6088e145 100644 --- a/src/assets/icons/icon-trash2.svg +++ b/src/assets/icons/icon-trash2.svg @@ -1,6 +1 @@ - - - - - - + \ No newline at end of file diff --git a/src/config/constants.js b/src/config/constants.js index cf277a8ff..68a267a3e 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -758,6 +758,8 @@ export const PROJECT_ATTACHMENTS_FOLDER = process.env.PROJECT_ATTACHMENTS_FOLDER 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'] export const SEGMENT_KEY = process.env.CONNECT_SEGMENT_KEY + +export const CHALLENGE_ID_MAPPING = process.env.CHALLENGE_ID_MAPPING || 'challengeId' /* * URLs */ diff --git a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx index 31e1ca641..4e0bcc0b1 100644 --- a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx +++ b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx @@ -3,6 +3,7 @@ */ import React from 'react' import PT from 'prop-types' +import moment from 'moment' import FormsyForm from 'appirio-tech-react-components/components/Formsy' import MilestoneRow from '../components/MilestoneRow' import MilestoneChallengeHeader from '../components/MilestoneChallengeHeader' @@ -11,10 +12,12 @@ import MilestoneChallengeFooter from '../components/MilestoneChallengeFooter' import MilestoneHeaderRow from '../components/MilestoneHeaderRow' import MilestoneDeleteButton from '../components/MilestoneDeleteButton' import MilestoneCopilots from '../components/MilestoneCopilots' +import MilestoneMoveDateButton from '../components/MilestoneMoveDateButton' + import * as milestoneHelper from '../components/helpers/milestone' import IconUnselect from '../../../../../assets/icons/icon-disselect.svg' import IconCopilot from '../../../../../assets/icons/icon-copilot.svg' -import IconCalendar from '../../../../../assets/icons/calendar.svg' +import { CHALLENGE_ID_MAPPING } from '../../../../../config/constants' // import IconGridView from '../../../../../assets/icons/ui-16px-2_grid-45-gray.svg' // import IconGnattView from '../../../../../assets/icons/icon-gnatt-gray.svg' @@ -38,8 +41,26 @@ class ManageMilestones extends React.Component { this.onUnselectAll = this.onUnselectAll.bind(this) this.onDeleteAll = this.onDeleteAll.bind(this) this.onAddCopilotAll = this.onAddCopilotAll.bind(this) + this.onMoveMilestoneDates = this.onMoveMilestoneDates.bind(this) + this.onLoadChallengesByPage = this.onLoadChallengesByPage.bind(this) } + onMoveMilestoneDates(days) { + const { + milestones, + onSaveMilestone + } = this.props + + if (days > 0) { + const seletedMilestones = _.filter(milestones, m => m.selected) + _.forEach(seletedMilestones, m => { + m.startDate = moment(m.startDate).add(days, 'days') + m.endDate = moment(m.endDate).add(days, 'days') + this.onChange(m) + onSaveMilestone(m.id) + }) + } + } onAddCopilotAll(member, isAdd) { const { milestones, onSaveMilestone } = this.props const seletedMilestones = _.filter(milestones, m => m.selected) @@ -81,11 +102,21 @@ class ManageMilestones extends React.Component { })) onChangeMilestones(milestonesUnselected) } + + onLoadChallengesByPage(index, milestone) { + const { onGetChallenges } = this.props + let challengeIds = _.map(milestone.products, `details.${CHALLENGE_ID_MAPPING}`).slice(6 * index, 7 * (index+1)) + challengeIds = _.filter(challengeIds) + if (!challengeIds.length) { + return + } + onGetChallenges(milestone.id, challengeIds) + } onExpandChallenges(isExpand, milestone) { let expandList = this.state.expandList const { onGetChallenges } = this.props - let challengeIds = _.map(milestone.products, 'details.challengeId').slice(0, 6) + let challengeIds = _.map(milestone.products, `details.${CHALLENGE_ID_MAPPING}`).slice(0, 6) challengeIds = _.filter(challengeIds) if (!challengeIds.length) { return @@ -141,7 +172,7 @@ class ManageMilestones extends React.Component { isExpandChallengeList(milestone) { const isExpand = _.find(this.state.expandList, (i) => i === milestone.id) - if (isExpand && milestone.challenges) { + if (isExpand) { return true } else { return false @@ -149,16 +180,38 @@ class ManageMilestones extends React.Component { } renderChallengeTable(milestone) { + const { + isUpdatable + } = this.props if (!this.isExpandChallengeList(milestone)) { return } + + let challengeIds = _.map(milestone.products, `details.${CHALLENGE_ID_MAPPING}`).slice(0, 6) + challengeIds = _.filter(challengeIds) + // no challenges + if (!challengeIds.length) { + return [ + , + + ] + } + + // loading challenges + if (milestone.isLoadingChallenges) { + return [ + , + + ] + } + const rows = _.map(milestone.challenges, (c) => { - return + return }) return [ - , + , ...rows, - + ] } getSelectCount() { @@ -170,19 +223,23 @@ class ManageMilestones extends React.Component { renderAddCopilot() { const { projectMembers, + milestones, } = this.props + const seletedMilestones = _.filter(milestones, m => m.selected) + const copilots = _.intersectionBy(..._.map(seletedMilestones, 'members'), 'userId') return ( } - copilots={[]} + customButton={} + copilots={copilots} projectMembers={projectMembers} onAdd={(member) => this.onAddCopilotAll(member, true)} onRemove={(member) => this.onAddCopilotAll(member, false)} /> ) } + render() { const { milestones, @@ -191,6 +248,7 @@ class ManageMilestones extends React.Component { isUpdatable, } = this.props + const canEdit = isUpdatable && this.getSelectCount() > 0 return (
@@ -201,18 +259,16 @@ class ManageMilestones extends React.Component {
*/} -
+ {canEdit ?
{this.getSelectCount()} PROJECTS SELECTED -
-
+
: null } + { canEdit ?
-
-
+
: null } + { canEdit ?
{this.renderAddCopilot()} -
-
- -
+
: null } + { canEdit ? : null} {isUpdatable && ( + +
+
+ ) + } +} + +ConfirmMoveMilestoneDate.propTypes = { + onClose: PT.func, +} + +export default ConfirmMoveMilestoneDate diff --git a/src/projects/detail/components/SimplePlan/components/ConfirmMoveMilestoneDate/ConfirmMoveMilestoneDate.scss b/src/projects/detail/components/SimplePlan/components/ConfirmMoveMilestoneDate/ConfirmMoveMilestoneDate.scss new file mode 100644 index 000000000..2b1b94aeb --- /dev/null +++ b/src/projects/detail/components/SimplePlan/components/ConfirmMoveMilestoneDate/ConfirmMoveMilestoneDate.scss @@ -0,0 +1,59 @@ +@import '~styles/variables'; + +.confirm-delete-milestone { + width: 204px; + padding: 15px 8px 12px 12px; + color: $tc-black; + background-color: $tc-white; + border: 1px solid $tc-gray-50; + border-radius: 3 * $corner-radius; + box-shadow: 0 3px 6px rbga(#000, .16); + + .icon { + width: 16px; + height: 16px; + margin-right: 8px; + color: red; + stroke: currentColor; + + * { + stroke: inherit; + } + } + .input-row { + display: flex; + align-items: center; + margin-bottom: 10px; + >input { + height: 26px; + width: 80px; + margin: 0 10px 0 0; + } + } + + + .title { + @include roboto-bold; + + display: flex; + margin-bottom: 8px; + font-size: $tc-body-xs; + line-height: 15px; + } + + .text { + @include roboto; + + margin-bottom: 12px; + font-size: $tc-body-sm; + line-height: 16px; + } + + .footer { + button + button { + margin-left: 10px; + } + } +} + + diff --git a/src/projects/detail/components/SimplePlan/components/ConfirmMoveMilestoneDate/index.js b/src/projects/detail/components/SimplePlan/components/ConfirmMoveMilestoneDate/index.js new file mode 100644 index 000000000..5f07433c0 --- /dev/null +++ b/src/projects/detail/components/SimplePlan/components/ConfirmMoveMilestoneDate/index.js @@ -0,0 +1,2 @@ +import ConfirmMoveMilestoneDate from './ConfirmMoveMilestoneDate' +export default ConfirmMoveMilestoneDate diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx index 120bb8eb4..16ba9bb47 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx +++ b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx @@ -3,6 +3,7 @@ */ import React from 'react' import _ from 'lodash' +import cn from 'classnames' import PT from 'prop-types' import { WORK_MANAGER_APP @@ -13,9 +14,22 @@ import './MilestoneChallengeFooter.scss' class MilestoneChallengeFooter extends React.Component { constructor(props) { super(props) - + this.state = { + curPage: 0 + } + this.loadChallengeBypage = this.loadChallengeBypage.bind(this) } + loadChallengeBypage(page) { + const { + milestone, + onLoadChallengesByPage + } = this.props + if (this.state.curPage === page) { + return + } + onLoadChallengesByPage(page, milestone) + } renderPagination() { const { milestone @@ -32,8 +46,8 @@ class MilestoneChallengeFooter extends React.Component { return (
{ - _.map(_.range(length), i => { - return
{i+1}
+ _.map(_.range(length), (i, index) => { + return
{this.loadChallengeBypage(index)}}>{i+1}
}) }
@@ -43,6 +57,7 @@ class MilestoneChallengeFooter extends React.Component { render() { const { + isUpdatable, milestone } = this.props const url = `${WORK_MANAGER_APP}/${milestone.projectId}/challenges` @@ -50,7 +65,7 @@ class MilestoneChallengeFooter extends React.Component { return ( - +
@@ -69,17 +84,9 @@ class MilestoneChallengeFooter extends React.Component { } MilestoneChallengeFooter.propTypes = { + onLoadChallengesByPage: PT.func, milestone: PT.shape(), - rowId: PT.string, - onChange: PT.func, - onSave: PT.func, - onRemove: PT.func, - onDiscard: PT.func, - projectMembers: PT.arrayOf(PT.shape()), - allMilestones: PT.arrayOf(PT.shape()), - isCreatingRow: PT.bool, - isUpdatable: PT.bool, - members: PT.object, + isUpdatable: PT.bool } export default MilestoneChallengeFooter diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.scss b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.scss index 00ac4baa5..5c2809a8c 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.scss +++ b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.scss @@ -22,6 +22,7 @@ } .pagination { display: flex; + margin-right: 20px; div { color: #127D60; border: 1px solid #127D60; @@ -31,6 +32,11 @@ border-radius: 50%; text-align: center; line-height: 18px; + cursor: pointer; + &.selected { + color: #000; + border-color: #000; + } } } } diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeHeader/MilestoneChallengeHeader.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeHeader/MilestoneChallengeHeader.jsx index fa8e3cce6..17a42de2c 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeHeader/MilestoneChallengeHeader.jsx +++ b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeHeader/MilestoneChallengeHeader.jsx @@ -2,14 +2,14 @@ * milestoneChallenge header */ import React from 'react' +import PT from 'prop-types' import './MilestoneChallengeHeader.scss' -function MilestoneChallengeHeader() { +function MilestoneChallengeHeader({isUpdatable}) { return ( - - +
TITLE
STATUS
@@ -22,4 +22,8 @@ function MilestoneChallengeHeader() { ) } +MilestoneChallengeHeader.propTypes = { + isUpdatable: PT.bool +} + export default MilestoneChallengeHeader diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeHeader/MilestoneChallengeHeader.scss b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeHeader/MilestoneChallengeHeader.scss index 80e2f5c14..b094a6941 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeHeader/MilestoneChallengeHeader.scss +++ b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeHeader/MilestoneChallengeHeader.scss @@ -13,7 +13,6 @@ align-items: center; .title { flex: 1; - max-width: 43%; margin-left: 30px; margin-right: 10px; } diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.jsx index 4f5e0d191..17671da7b 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.jsx +++ b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.jsx @@ -13,17 +13,41 @@ import './MilestoneChallengeRow.scss' const STALLED_MSG = 'Stalled' const DRAFT_MSG = 'Draft' -function MilestoneChallengeRow({challenge: { - id, - name, - status, - track, - type, - startDate, - phases: allPhases, - endDate -}}) { +function MilestoneChallengeRow({challenge, isEmpty, isLoading, isUpdatable}) { + if (isEmpty) { + return ( + + +
+ no challenges found +
+ + + ) + } + + if (isLoading) { + return ( + + +
+ loading challenges... +
+ + + ) + } + const { + id, + name, + status, + track, + type, + startDate, + phases: allPhases, + endDate + } = challenge let statusPhase = allPhases .filter(p => p.name !== 'Registration' && p.isOpen) @@ -41,7 +65,7 @@ function MilestoneChallengeRow({challenge: { return ( - +
{phaseMessage}
@@ -56,6 +80,9 @@ function MilestoneChallengeRow({challenge: { MilestoneChallengeRow.propTypes = { challenge: PT.shape(), + isUpdatable: PT.bool, + isEmpty: PT.bool, + isLoading: PT.bool } export default MilestoneChallengeRow diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.scss b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.scss index 5b7b37662..77123f943 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.scss +++ b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.scss @@ -6,16 +6,18 @@ color: #6b6b6b; } +.challenge-empty-row { + text-align: center; +} + .challenge-table-row { display: flex; align-items: center; .title { flex: 1; - white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-left: 30px; - max-width: 43%; margin-right: 10px; color: #0A81FF } @@ -48,10 +50,10 @@ padding: 4px 0; text-align: center; color: #fff; - &.Design { background-color: $tc-light-blue-100; } - &.Development { background-color: $tc-green-100; } - &.DataScience { background-color: $tc-orange-100; } - &.QualityAssurance { background-color: $tc-green-100; } + &.Design { background-color: #0076A5; } + &.Development { background-color: #328732; } + &.DataScience { background-color: #BA4C00; } + &.QualityAssurance { background-color: #8231A9 } } } diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/MilestoneMoveDateButton.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/MilestoneMoveDateButton.jsx new file mode 100644 index 000000000..cc3d89c48 --- /dev/null +++ b/src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/MilestoneMoveDateButton.jsx @@ -0,0 +1,87 @@ +import React from 'react' +import PT from 'prop-types' +import { Popper, Manager } from 'react-popper' +import ConfirmMoveMilestoneDate from '../ConfirmMoveMilestoneDate' +import IconCalendar from '../../../../../../assets/icons/icon-calendar2.svg' + +import './MilestoneMoveDateButton.scss' + +class MilestoneMoveDateButton extends React.Component { + constructor(props) { + super(props) + + this.state = { + open: false + } + + this.onClickOutside = this.onClickOutside.bind(this) + } + + componentDidUpdate() { + const { open } = this.state + + if (open) { + document.addEventListener('click', this.onClickOutside) + } else { + document.removeEventListener('click', this.onClickOutside) + } + } + + onClickOutside(event) { + if (this.confirmRef.contains(event.target)) { + return + } + + this.setState({ open: false }) + } + + render() { + const { onMove } = this.props + const { open } = this.state + + return ( + + { + event.stopPropagation() + + this.setState({ + open: !open + }) + }} + ref={ref => this.btnRef = ref} + > + + + {open && + + + {({ ref, style, placement, arrowProps }) => ( +
+
this.confirmRef = ref2}> + { + if (yes) { + onMove(value) + } + this.setState({ open: false }) + }} + /> +
+
+
+ )} + + + } + + ) + } +} + +MilestoneMoveDateButton.propTypes = { + onMove: PT.func, +} + +export default MilestoneMoveDateButton diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/MilestoneMoveDateButton.scss b/src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/MilestoneMoveDateButton.scss new file mode 100644 index 000000000..4674861de --- /dev/null +++ b/src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/MilestoneMoveDateButton.scss @@ -0,0 +1,21 @@ +.icon-button{ + width: 14px; + height: 14px; + padding: 0; + border: 0; + cursor: pointer; + + svg { + width: 20px; + } +} + +.pane { + margin-top: 10px; + z-index: 1; +} + +.arrow { + width: 0; + height: 0; +} diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/index.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/index.jsx new file mode 100644 index 000000000..9ee70caf0 --- /dev/null +++ b/src/projects/detail/components/SimplePlan/components/MilestoneMoveDateButton/index.jsx @@ -0,0 +1,2 @@ +import MilestoneMoveDateButton from './MilestoneMoveDateButton' +export default MilestoneMoveDateButton diff --git a/src/projects/reducers/project.js b/src/projects/reducers/project.js index e7cf932ec..17ab6f622 100644 --- a/src/projects/reducers/project.js +++ b/src/projects/reducers/project.js @@ -9,7 +9,7 @@ import { UPDATE_PROJECT_ATTACHMENT_PENDING, UPDATE_PROJECT_ATTACHMENT_SUCCESS, UPDATE_PROJECT_ATTACHMENT_FAILURE, REMOVE_PROJECT_ATTACHMENT_PENDING, REMOVE_PROJECT_ATTACHMENT_SUCCESS, REMOVE_PROJECT_ATTACHMENT_FAILURE, REMOVE_PENDING_ATTACHMENT, UPDATE_PENDING_ATTACHMENT, - LOAD_CHALLEGNES_PENDING, LOAD_CHALLEGNES_SUCCESS, + LOAD_CHALLEGNES_PENDING, LOAD_CHALLEGNES_SUCCESS, LOAD_CHALLEGNES_FAILURE, ADD_PRODUCT_ATTACHMENT_PENDING, ADD_PRODUCT_ATTACHMENT_SUCCESS, ADD_PRODUCT_ATTACHMENT_FAILURE, UPDATE_PRODUCT_ATTACHMENT_PENDING, UPDATE_PRODUCT_ATTACHMENT_SUCCESS, UPDATE_PRODUCT_ATTACHMENT_FAILURE, REMOVE_PRODUCT_ATTACHMENT_PENDING, REMOVE_PRODUCT_ATTACHMENT_SUCCESS, REMOVE_PRODUCT_ATTACHMENT_FAILURE, @@ -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 + LOAD_PROJECT_MEMBERS_SUCCESS, LOAD_PROJECT_MEMBER_INVITES_SUCCESS, LOAD_PROJECT_MEMBER_SUCCESS, CREATE_PROJECT_PHASE_PENDING, CREATE_PROJECT_PHASE_SUCCESS, } from '../../config/constants' import _ from 'lodash' import update from 'react-addons-update' @@ -187,6 +187,16 @@ export const projectState = function (state=initialState, action) { phases: { $splice: [[phaseIndex, 1, phase]] }, }) } + case LOAD_CHALLEGNES_FAILURE: { + const phaseIndex = _.findIndex(state.phases, { id: action.meta.milestoneId }) + const phase = { + ...state.phases[phaseIndex], + isLoadingChallenges: false, + } + return update(state, { + phases: { $splice: [[phaseIndex, 1, phase]] }, + }) + } case CREATE_PROJECT_PHASE_TIMELINE_MILESTONES_SUCCESS: case CREATE_PROJECT_PHASE_SUCCESS: { const { phase, product } = action.payload From b9661ef6bede710364f1f955af080181c507ed5e Mon Sep 17 00:00:00 2001 From: Ahmad Alkhawaja Date: Wed, 4 Aug 2021 22:28:14 +0300 Subject: [PATCH 12/18] moved details.challengeId to configurable string --- .../MilestoneChallengeFooter/MilestoneChallengeFooter.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx index 16ba9bb47..73a26107e 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx +++ b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx @@ -6,7 +6,8 @@ import _ from 'lodash' import cn from 'classnames' import PT from 'prop-types' import { - WORK_MANAGER_APP + WORK_MANAGER_APP, + CHALLENGE_ID_MAPPING } from '../../../../../../../src/config/constants' import './MilestoneChallengeFooter.scss' @@ -34,7 +35,7 @@ class MilestoneChallengeFooter extends React.Component { const { milestone } = this.props - let challengeIds = _.map(milestone.products, 'details.challengeId') + let challengeIds = _.map(milestone.products, `details.${CHALLENGE_ID_MAPPING}`) challengeIds = _.filter(challengeIds) const length = Math.ceil(challengeIds.length/6) From abf4795c379d3fe2b88afbb1247235e4ecf77b0b Mon Sep 17 00:00:00 2001 From: Ahmad Alkhawaja Date: Wed, 4 Aug 2021 22:39:15 +0300 Subject: [PATCH 13/18] attempt to fix pagination --- .../MilestoneChallengeFooter/MilestoneChallengeFooter.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx index 73a26107e..3658bda83 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx +++ b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx @@ -29,6 +29,7 @@ class MilestoneChallengeFooter extends React.Component { if (this.state.curPage === page) { return } + this.state.curPage = page; onLoadChallengesByPage(page, milestone) } renderPagination() { From a432b2c54a0bf16116d5168b13928e63d12084ea Mon Sep 17 00:00:00 2001 From: Ahmad Alkhawaja Date: Wed, 4 Aug 2021 22:53:33 +0300 Subject: [PATCH 14/18] fixed lint --- .../MilestoneChallengeFooter/MilestoneChallengeFooter.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx index 3658bda83..bf81dd81f 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx +++ b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx @@ -29,7 +29,7 @@ class MilestoneChallengeFooter extends React.Component { if (this.state.curPage === page) { return } - this.state.curPage = page; + this.state.curPage = page onLoadChallengesByPage(page, milestone) } renderPagination() { From 56ae5f1270796ee5407feac1510acdb1c9a29d75 Mon Sep 17 00:00:00 2001 From: yoution Date: Thu, 5 Aug 2021 17:31:21 +0800 Subject: [PATCH 15/18] fix: issue about pagination and gap line --- .../ManageMilestones/ManageMilestones.jsx | 16 +++++++++------- .../ManageMilestones/ManageMilestones.scss | 8 +++++++- .../MilestoneChallengeFooter.jsx | 14 ++++++++++---- .../MilestoneChallengeRow.scss | 1 + 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx index 3df98c290..aa53f2651 100644 --- a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx +++ b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx @@ -192,26 +192,27 @@ class ManageMilestones extends React.Component { // no challenges if (!challengeIds.length) { return [ - , - + , + ] } // loading challenges if (milestone.isLoadingChallenges) { return [ - , - + , + , + ] } const rows = _.map(milestone.challenges, (c) => { - return + return }) return [ - , + , ...rows, - + ] } getSelectCount() { @@ -262,6 +263,7 @@ class ManageMilestones extends React.Component { {canEdit ?
{this.getSelectCount()} PROJECTS SELECTED
: null } + {canEdit ?
: null} { canEdit ?
: null } diff --git a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.scss b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.scss index ec653d049..97e31227e 100644 --- a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.scss +++ b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.scss @@ -17,7 +17,6 @@ font-size: 12px; padding: 0 5px; cursor: pointer; - svg { margin-right: 4px; height: 13px; @@ -25,6 +24,13 @@ } margin-right: 20px; } + .line { + width: 1px; + height: 20px; + display: inline-block; + border: 1px solid #C4C4C4; + margin-right: 10px; + } .delete-button { cursor: pointer; margin: 0 10px; diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx index bf81dd81f..08f263da1 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx +++ b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeFooter/MilestoneChallengeFooter.jsx @@ -29,7 +29,7 @@ class MilestoneChallengeFooter extends React.Component { if (this.state.curPage === page) { return } - this.state.curPage = page + this.setState({curPage: page}) onLoadChallengesByPage(page, milestone) } renderPagination() { @@ -60,10 +60,15 @@ class MilestoneChallengeFooter extends React.Component { render() { const { isUpdatable, - milestone + milestone, + isLoading, } = this.props - const url = `${WORK_MANAGER_APP}/${milestone.projectId}/challenges` + if (isLoading) { + return null + } + + const url = `${WORK_MANAGER_APP}/${milestone.projectId}/challenges` return ( @@ -88,7 +93,8 @@ class MilestoneChallengeFooter extends React.Component { MilestoneChallengeFooter.propTypes = { onLoadChallengesByPage: PT.func, milestone: PT.shape(), - isUpdatable: PT.bool + isUpdatable: PT.bool, + isLoading: PT.bool } export default MilestoneChallengeFooter diff --git a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.scss b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.scss index 77123f943..5e7462dfa 100644 --- a/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.scss +++ b/src/projects/detail/components/SimplePlan/components/MilestoneChallengeRow/MilestoneChallengeRow.scss @@ -34,6 +34,7 @@ &.Registration { background-color: $tc-orange-100; } &.Appeals { background-color: $tc-orange-100; } &.AppealsResponse { background-color: $tc-orange-100; } + &.Post-Mortem { background-color: $tc-orange-100; } &.Draft { background-color: $tc-gray-20; } &.Stalled { background-color: $tc-gray-20; } &.Completed { background-color: $tc-green-100; } From 88dbdb5f410ed08e20fb6d2f043e3c889490ce19 Mon Sep 17 00:00:00 2001 From: yoution Date: Thu, 5 Aug 2021 18:46:10 +0800 Subject: [PATCH 16/18] fix: issue about no challenges --- .../SimplePlan/ManageMilestones/ManageMilestones.jsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx index aa53f2651..8185026c8 100644 --- a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx +++ b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx @@ -118,12 +118,11 @@ class ManageMilestones extends React.Component { let challengeIds = _.map(milestone.products, `details.${CHALLENGE_ID_MAPPING}`).slice(0, 6) challengeIds = _.filter(challengeIds) - if (!challengeIds.length) { - return - } if (isExpand) { - onGetChallenges(milestone.id, challengeIds) + if (challengeIds.length) { + onGetChallenges(milestone.id, challengeIds) + } expandList.push(milestone.id) this.setState({expandList}) } else { From 26bb1ff451da40a2205699c8641a800e30e6f7fd Mon Sep 17 00:00:00 2001 From: Ahmad Alkhawaja Date: Thu, 5 Aug 2021 18:28:15 +0300 Subject: [PATCH 17/18] Revert challenge id config map, put it as constant in constants --- config/constants/dev.js | 1 - config/constants/master.js | 1 - src/config/constants.js | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/config/constants/dev.js b/config/constants/dev.js index 1972ccea5..e2f2ba1d6 100644 --- a/config/constants/dev.js +++ b/config/constants/dev.js @@ -57,7 +57,6 @@ module.exports = { DASHBOARD_FAQ_CONTENT_ID : process.env.DASHBOARD_FAQ_CONTENT_ID, CONTENTFUL_DELIVERY_KEY : process.env.CONTENTFUL_DELIVERY_KEY, CONTENTFUL_SPACE_ID : process.env.CONTENTFUL_SPACE_ID, - CHALLENGE_ID_MAPPING: process.env.CHALLENGE_ID_MAPPING, TAAS_APP_URL: 'https://platform.topcoder-dev.com/taas', DEFAULT_NDA_UUID: 'e5811a7b-43d1-407a-a064-69e5015b4900' diff --git a/config/constants/master.js b/config/constants/master.js index 79c1594ea..ec979e937 100644 --- a/config/constants/master.js +++ b/config/constants/master.js @@ -57,7 +57,6 @@ module.exports = { DASHBOARD_FAQ_CONTENT_ID : process.env.DASHBOARD_FAQ_CONTENT_ID, CONTENTFUL_DELIVERY_KEY : process.env.CONTENTFUL_DELIVERY_KEY, CONTENTFUL_SPACE_ID : process.env.CONTENTFUL_SPACE_ID, - CHALLENGE_ID_MAPPING: process.env.CHALLENGE_ID_MAPPING, TAAS_APP_URL: 'https://platform.topcoder.com/taas', DEFAULT_NDA_UUID: 'c41e90e5-4d0e-4811-bd09-38ff72674490' diff --git a/src/config/constants.js b/src/config/constants.js index 68a267a3e..1203c00ab 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -759,7 +759,7 @@ export const FILE_PICKER_ACCEPT = process.env.FILE_PICKER_ACCEPT || ['.bmp', '.g export const SEGMENT_KEY = process.env.CONNECT_SEGMENT_KEY -export const CHALLENGE_ID_MAPPING = process.env.CHALLENGE_ID_MAPPING || 'challengeId' +export const CHALLENGE_ID_MAPPING = 'challengeGuid' /* * URLs */ From 6f75f09caac2bd72205e0fdc8736081208f9ff54 Mon Sep 17 00:00:00 2001 From: yoution Date: Sat, 7 Aug 2021 07:47:56 +0800 Subject: [PATCH 18/18] fix: issue about milestone challenge count --- .../SimplePlan/ManageMilestones/ManageMilestones.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx index 8185026c8..e63f2aaad 100644 --- a/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx +++ b/src/projects/detail/components/SimplePlan/ManageMilestones/ManageMilestones.jsx @@ -116,8 +116,7 @@ class ManageMilestones extends React.Component { let expandList = this.state.expandList const { onGetChallenges } = this.props - let challengeIds = _.map(milestone.products, `details.${CHALLENGE_ID_MAPPING}`).slice(0, 6) - challengeIds = _.filter(challengeIds) + const challengeIds = _.filter(_.map(milestone.products, `details.${CHALLENGE_ID_MAPPING}`)).slice(0, 6) if (isExpand) { if (challengeIds.length) {