From ecb4372c06407ce6a3cbe3fcbfff9e16b439804c Mon Sep 17 00:00:00 2001 From: Maksym Mykhailenko Date: Sun, 10 Feb 2019 11:46:16 +0800 Subject: [PATCH 1/2] winning submission for the challenge 30083315 - Topcoder Connect - Project activating validation, fixes issue #2805 --- src/components/ProjectInfo/ProjectInfo.jsx | 6 +- .../ProjectStatus/ProjectStatus.scss | 16 ++++ .../ProjectStatus/editableProjectStatus.js | 76 ++++++++++++++----- .../projectsCard/ProjectCardBody.jsx | 5 +- 4 files changed, 82 insertions(+), 21 deletions(-) diff --git a/src/components/ProjectInfo/ProjectInfo.jsx b/src/components/ProjectInfo/ProjectInfo.jsx index c4dd07453..b4ae631ec 100644 --- a/src/components/ProjectInfo/ProjectInfo.jsx +++ b/src/components/ProjectInfo/ProjectInfo.jsx @@ -10,7 +10,7 @@ import ProjectDirectLinks from '../../projects/list/components/Projects/ProjectD import MobileExpandable from '../MobileExpandable/MobileExpandable' import ProjectProgress from '../../projects/detail/components/ProjectProgress' import MediaQuery from 'react-responsive' -import { SCREEN_BREAKPOINT_MD, PHASE_STATUS_ACTIVE, PROJECT_ROLE_OWNER, PROJECT_ROLE_CUSTOMER } from '../../config/constants' +import { SCREEN_BREAKPOINT_MD, PROJECT_STATUS_ACTIVE, PHASE_STATUS_ACTIVE, PHASE_STATUS_REVIEWED, PROJECT_ROLE_OWNER, PROJECT_ROLE_CUSTOMER } from '../../config/constants' import ReviewProjectButton from '../../projects/detail/components/ReviewProjectButton' import { formatProjectProgressProps, formatOldProjectProgressProps } from '../../helpers/projectHelper' @@ -52,6 +52,9 @@ class ProjectInfo extends Component { ) const activePhases = phases ? phases.filter((phase) => phase.status === PHASE_STATUS_ACTIVE) : [] + const hasReviewedPhases = !!_.find(phases, (phase) => phase.status === PHASE_STATUS_REVIEWED) + const projectCanBeActive = (project.status !== PROJECT_STATUS_ACTIVE && hasReviewedPhases) || project.status === PROJECT_STATUS_ACTIVE + // prepare review button const showReviewBtn = project.status === 'draft' && @@ -108,6 +111,7 @@ class ProjectInfo extends Component { {(matches) => ( { +const hocStatusDropdown = (CompositeComponent, statusList, projectCanBeActive) => { class StatusDropdown extends Component { shouldDropdownUp() { if (this.refs.dropdown) { @@ -32,6 +35,12 @@ const hocStatusDropdown = (CompositeComponent, statusList) => { return null } + const activestatusList = statusList.map((status) => ({ + ...status, + disabled: !projectCanBeActive && status.value === PROJECT_STATUS_ACTIVE, + toolTipMessage: (!projectCanBeActive && status.value === PROJECT_STATUS_ACTIVE) ? 'To activate project there should be at least one phase in "Planned" status. Please, check "Project Plan" tab.' : null, + })) + this.shouldDropdownUp() return (
@@ -46,7 +55,7 @@ const hocStatusDropdown = (CompositeComponent, statusList) => { unifiedHeader={unifiedHeader} /> { canEdit && - + }
{ isOpen && canEdit && @@ -54,18 +63,43 @@ const hocStatusDropdown = (CompositeComponent, statusList) => {
Project Status
@@ -126,10 +160,10 @@ const editableProjectStatus = (CompositeComponent) => class extends Component { render() { const { showStatusChangeDialog, newStatus, statusChangeReason } = this.state - const { canEdit } = this.props + const { canEdit, projectCanBeActive } = this.props const StatusDropdown = canEdit - ? enhanceDropdown(hocStatusDropdown(CompositeComponent, PROJECT_STATUS)) - : hocStatusDropdown(CompositeComponent, PROJECT_STATUS) + ? enhanceDropdown(hocStatusDropdown(CompositeComponent, PROJECT_STATUS, projectCanBeActive)) + : hocStatusDropdown(CompositeComponent, PROJECT_STATUS, projectCanBeActive) return (
@@ -152,7 +186,11 @@ editableProjectStatus.propTypes = { /** * Boolean flag to control editability of the project status. It does not render the dropdown if it is not editable. */ - canEdit: PropTypes.bool + canEdit: PropTypes.bool, + /** + * Boolean flag to control if project status can be switched to active. + */ + projectCanBeActive: PropTypes.bool } export default editableProjectStatus diff --git a/src/projects/components/projectsCard/ProjectCardBody.jsx b/src/projects/components/projectsCard/ProjectCardBody.jsx index 0ae5cd78b..36e85f2a9 100644 --- a/src/projects/components/projectsCard/ProjectCardBody.jsx +++ b/src/projects/components/projectsCard/ProjectCardBody.jsx @@ -11,7 +11,7 @@ import _ from 'lodash' const EnhancedProjectStatus = editableProjectStatus(ProjectStatus) -function ProjectCardBody({ project, duration, currentMemberRole, descLinesCount = 8, +function ProjectCardBody({ project, projectCanBeActive, duration, currentMemberRole, descLinesCount = 8, onChangeStatus, isSuperUser, showLink, showLinkURL, canEditStatus = true }) { if (!project) return null @@ -39,6 +39,7 @@ function ProjectCardBody({ project, duration, currentMemberRole, descLinesCount {(project.status !== PROJECT_STATUS_ACTIVE || progress === 0) && Date: Sun, 10 Feb 2019 11:51:12 +0800 Subject: [PATCH 2/2] fix to also allow activate project if it has active phases --- src/components/ProjectInfo/ProjectInfo.jsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/ProjectInfo/ProjectInfo.jsx b/src/components/ProjectInfo/ProjectInfo.jsx index b4ae631ec..319e8ffd2 100644 --- a/src/components/ProjectInfo/ProjectInfo.jsx +++ b/src/components/ProjectInfo/ProjectInfo.jsx @@ -52,9 +52,9 @@ class ProjectInfo extends Component { ) const activePhases = phases ? phases.filter((phase) => phase.status === PHASE_STATUS_ACTIVE) : [] - const hasReviewedPhases = !!_.find(phases, (phase) => phase.status === PHASE_STATUS_REVIEWED) - const projectCanBeActive = (project.status !== PROJECT_STATUS_ACTIVE && hasReviewedPhases) || project.status === PROJECT_STATUS_ACTIVE - + const hasReviewedOrActivePhases = !!_.find(phases, (phase) => _.includes([PHASE_STATUS_REVIEWED, PHASE_STATUS_ACTIVE], phase.status)) + const projectCanBeActive = (project.status !== PROJECT_STATUS_ACTIVE && hasReviewedOrActivePhases) || project.status === PROJECT_STATUS_ACTIVE + // prepare review button const showReviewBtn = project.status === 'draft' && @@ -63,10 +63,10 @@ class ProjectInfo extends Component { const reviewButtonSection = (

- Your project "{_.unescape(project.name)}" has been drafted. - If you have your requirements documented, just verify it against our checklist and then upload it on the Scope section. - Once you've finalized your scope, select the "Submit for Review" button. - Topcoder will then review your drafted project and will assign a manager to get your delivery in-progress! + Your project "{_.unescape(project.name)}" has been drafted. + If you have your requirements documented, just verify it against our checklist and then upload it on the Scope section. + Once you've finalized your scope, select the "Submit for Review" button. + Topcoder will then review your drafted project and will assign a manager to get your delivery in-progress! Get stuck or need help? Email us at support@topcoder.com.