From caa3f2f7e745334ad32502052d0069757d12117e Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Tue, 14 May 2019 20:58:03 +0530 Subject: [PATCH 01/14] WIP issue 2177 --- src/projects/detail/ProjectDetail.jsx | 6 ++---- .../detail/containers/DashboardContainer.jsx | 2 ++ .../detail/containers/ProjectInfoContainer.js | 19 ++++++++++++++++++- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/projects/detail/ProjectDetail.jsx b/src/projects/detail/ProjectDetail.jsx index 1191dc1f6..a4183060b 100644 --- a/src/projects/detail/ProjectDetail.jsx +++ b/src/projects/detail/ProjectDetail.jsx @@ -64,9 +64,7 @@ const ProjectDetailView = (props) => { if (!currentMemberRole && props.currentUserRoles && props.currentUserRoles.length > 0) { currentMemberRole = props.currentUserRoles[0] } - const regex = /#(feed-([0-9]+)|comment-([0-9]+))/ - const match = props.location.hash.match(regex) - const ids = match ? { feedId: match[2], commentId: match[3] } : {} + const locationHash = window.location.hash ? window.location.hash.substring(1) : null const { component: Component } = props const componentProps = { @@ -79,7 +77,7 @@ const ProjectDetailView = (props) => { isProcessing: props.isProcessing, allProductTemplates: props.allProductTemplates, productsTimelines: props.productsTimelines, - ...ids + locationHash } return } diff --git a/src/projects/detail/containers/DashboardContainer.jsx b/src/projects/detail/containers/DashboardContainer.jsx index a0ffb55df..49c125091 100644 --- a/src/projects/detail/containers/DashboardContainer.jsx +++ b/src/projects/detail/containers/DashboardContainer.jsx @@ -112,6 +112,7 @@ class DashboardContainer extends React.Component { phasesTopics, expandProjectPhase, collapseProjectPhase, + locationHash, } = this.props // system notifications @@ -135,6 +136,7 @@ class DashboardContainer extends React.Component { productsTimelines={productsTimelines} phasesTopics={phasesTopics} isProjectProcessing={isProcessing} + locationHash={locationHash} /> ) diff --git a/src/projects/detail/containers/ProjectInfoContainer.js b/src/projects/detail/containers/ProjectInfoContainer.js index 9c6140720..73732cb8d 100644 --- a/src/projects/detail/containers/ProjectInfoContainer.js +++ b/src/projects/detail/containers/ProjectInfoContainer.js @@ -81,8 +81,25 @@ class ProjectInfoContainer extends React.Component { }) } - componentWillReceiveProps({project}) { + componentWillReceiveProps(props) { + const { project, locationHash, feeds, canAccessPrivatePosts, loadDashboardFeeds, loadProjectMessages } = props this.setDuration(project) + if (locationHash && locationHash !== this.props.locationHash) { + const hashParts = _.split(locationHash, '-') + if (hashParts[0] === 'comment') { + let commentFound = false + _.forEach(feeds, feed => _.forEach(feed.posts, post => { + if (post.id === hashParts[1]) { + commentFound = true + return false + } + })) + if (!commentFound) { + loadDashboardFeeds(project.id) + canAccessPrivatePosts && loadProjectMessages(project.id) + } + } + } } onChangeStatus(projectId, status, reason) { From 7f5e6e36b9c77e202934616c34a44da26ad66e06 Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Wed, 15 May 2019 21:01:14 +0530 Subject: [PATCH 02/14] fix for issue 2177 --- src/projects/detail/ProjectDetail.jsx | 2 - .../detail/containers/DashboardContainer.jsx | 2 - .../detail/containers/FeedContainer.js | 2 +- .../detail/containers/ProjectInfoContainer.js | 74 +++++++++++++------ 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/projects/detail/ProjectDetail.jsx b/src/projects/detail/ProjectDetail.jsx index a4183060b..56b4710c8 100644 --- a/src/projects/detail/ProjectDetail.jsx +++ b/src/projects/detail/ProjectDetail.jsx @@ -64,7 +64,6 @@ const ProjectDetailView = (props) => { if (!currentMemberRole && props.currentUserRoles && props.currentUserRoles.length > 0) { currentMemberRole = props.currentUserRoles[0] } - const locationHash = window.location.hash ? window.location.hash.substring(1) : null const { component: Component } = props const componentProps = { @@ -77,7 +76,6 @@ const ProjectDetailView = (props) => { isProcessing: props.isProcessing, allProductTemplates: props.allProductTemplates, productsTimelines: props.productsTimelines, - locationHash } return } diff --git a/src/projects/detail/containers/DashboardContainer.jsx b/src/projects/detail/containers/DashboardContainer.jsx index 49c125091..a0ffb55df 100644 --- a/src/projects/detail/containers/DashboardContainer.jsx +++ b/src/projects/detail/containers/DashboardContainer.jsx @@ -112,7 +112,6 @@ class DashboardContainer extends React.Component { phasesTopics, expandProjectPhase, collapseProjectPhase, - locationHash, } = this.props // system notifications @@ -136,7 +135,6 @@ class DashboardContainer extends React.Component { productsTimelines={productsTimelines} phasesTopics={phasesTopics} isProjectProcessing={isProcessing} - locationHash={locationHash} /> ) diff --git a/src/projects/detail/containers/FeedContainer.js b/src/projects/detail/containers/FeedContainer.js index 624477588..0f35f074f 100644 --- a/src/projects/detail/containers/FeedContainer.js +++ b/src/projects/detail/containers/FeedContainer.js @@ -226,7 +226,7 @@ class FeedView extends React.Component { } const scrollTo = window.location.hash ? window.location.hash.substring(1) : null if (scrollTo) { - scrollToHash(scrollTo) + setTimeout(() => scrollToHash(scrollTo), 0) } }) } diff --git a/src/projects/detail/containers/ProjectInfoContainer.js b/src/projects/detail/containers/ProjectInfoContainer.js index 73732cb8d..960aee397 100644 --- a/src/projects/detail/containers/ProjectInfoContainer.js +++ b/src/projects/detail/containers/ProjectInfoContainer.js @@ -1,12 +1,13 @@ import React from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' +import { withRouter } from 'react-router-dom' import update from 'react-addons-update' import _ from 'lodash' import LinksMenu from '../../../components/LinksMenu/LinksMenu' import FileLinksMenu from '../../../components/LinksMenu/FileLinksMenu' import TeamManagementContainer from './TeamManagementContainer' -import { updateProject, deleteProject } from '../../actions/project' +import { updateProject, deleteProject, loadProjectPhasesWithProducts } from '../../actions/project' import { loadDashboardFeeds, loadProjectMessages } from '../../actions/projectTopics' import { loadPhaseFeed } from '../../actions/phasesTopics' import { setDuration } from '../../../helpers/projectHelper' @@ -60,16 +61,14 @@ class ProjectInfoContainer extends React.Component { } componentWillMount() { - const { project, isFeedsLoading, feeds, loadDashboardFeeds, - loadProjectMessages, phases, phasesTopics, loadPhaseFeed, canAccessPrivatePosts } = this.props + const { project, isFeedsLoading, feeds, phases, phasesTopics, loadPhaseFeed } = this.props this.setDuration(project) // load feeds from dashboard if they are not currently loading or loaded yet // also it will load feeds, if we already loaded them, but it was 0 feeds before if (!isFeedsLoading && feeds.length < 1) { - loadDashboardFeeds(project.id) - canAccessPrivatePosts && loadProjectMessages(project.id) + this.loadAllFeeds() } // load phases feeds if they are not loaded yet @@ -82,26 +81,59 @@ class ProjectInfoContainer extends React.Component { } componentWillReceiveProps(props) { - const { project, locationHash, feeds, canAccessPrivatePosts, loadDashboardFeeds, loadProjectMessages } = props + const { project, phases, feeds, loadProjectPhasesWithProducts, loadPhaseFeed, location } = props + this.setDuration(project) - if (locationHash && locationHash !== this.props.locationHash) { - const hashParts = _.split(locationHash, '-') - if (hashParts[0] === 'comment') { - let commentFound = false - _.forEach(feeds, feed => _.forEach(feed.posts, post => { - if (post.id === hashParts[1]) { - commentFound = true - return false - } - })) - if (!commentFound) { - loadDashboardFeeds(project.id) - canAccessPrivatePosts && loadProjectMessages(project.id) + + if (!_.isEmpty(location.hash) && location.hash !== this.props.location.hash) { + const hashParts = _.split(location.hash.substring(1), '-') + const hashPrimaryId = parseInt(hashParts[1], 10) + + switch (hashParts[0]) { + case 'comment': + if (!this.foundCommentInFeeds(feeds, hashPrimaryId)) { + this.loadAllFeeds() } + break + + case 'feed': + if (!_.some(feeds, { id: hashPrimaryId})) { + this.loadAllFeeds() + } + break + + case 'phase': + if (!_.some(phases, { id: hashPrimaryId})) { + loadProjectPhasesWithProducts(project.id) + .then(({ value: newPhases }) => { + _.some(newPhases, { id: hashPrimaryId}) && loadPhaseFeed(project.id, hashPrimaryId) + }) + } + break } } } + loadAllFeeds() { + const { canAccessPrivatePosts, loadDashboardFeeds, loadProjectMessages, project } = this.props + + loadDashboardFeeds(project.id) + canAccessPrivatePosts && loadProjectMessages(project.id) + } + + foundCommentInFeeds(feeds, commentId) { + let commentFound = false + + _.forEach(feeds, feed => _.forEach(feed.posts, post => { + if (post.id === commentId) { + commentFound = true + return false + } + })) + + return commentFound + } + onChangeStatus(projectId, status, reason) { const delta = {status} if (reason && status === PROJECT_STATUS_CANCELLED) { @@ -366,6 +398,6 @@ const mapStateToProps = ({ templates, projectState, members, loadUser }) => { const mapDispatchToProps = { updateProject, deleteProject, addProjectAttachment, updateProjectAttachment, loadProjectMessages, discardAttachments, uploadProjectAttachments, loadDashboardFeeds, loadPhaseFeed, changeAttachmentPermission, - removeProjectAttachment } + removeProjectAttachment, loadProjectPhasesWithProducts } -export default connect(mapStateToProps, mapDispatchToProps)(ProjectInfoContainer) +export default connect(mapStateToProps, mapDispatchToProps)(withRouter(ProjectInfoContainer)) From dc9da26f5e6c2ca9aca990a967e09fdaca6beca6 Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Tue, 21 May 2019 18:46:36 +0530 Subject: [PATCH 03/14] fixes project plan tab --- .../detail/components/PhaseFeed/PhaseFeed.jsx | 54 +++++++++++++----- .../detail/components/ProjectStage.jsx | 36 +++++++----- .../detail/components/ProjectStages.jsx | 7 ++- .../detail/containers/FeedContainer.js | 2 +- .../detail/containers/PhaseFeedHOC.jsx | 4 +- .../detail/containers/ProjectInfoContainer.js | 55 +++++++++++++------ .../containers/ProjectPlanContainer.jsx | 36 +++++------- 7 files changed, 123 insertions(+), 71 deletions(-) diff --git a/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx b/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx index 1fbeb0bc7..629a91089 100644 --- a/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx +++ b/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx @@ -5,26 +5,54 @@ */ import React from 'react' import _ from 'lodash' +import { withRouter } from 'react-router-dom' import ScrollableFeed from '../../../../components/Feed/ScrollableFeed' import spinnerWhileLoading from '../../../../components/LoadingSpinner' +import { scrollToHash } from '../../../../components/ScrollToAnchors' import './PhaseFeed.scss' -const PhaseFeedView = (props) => ( -
- -
-) +class PhaseFeedView extends React.Component { + constructor(props) { + super(props) + } + + componentWillMount() { + !_.isEmpty(this.props.location.hash) && this.handleUrlHash(this.props) + } + + componentWillReceiveProps(props) { + if (!_.isEmpty(location.hash) && props.location.hash !== this.props.location.hash) { + this.handleUrlHash(props) + } + } + + handleUrlHash(props) { + const hashParts = _.split(location.hash.substring(1), '-') + const phaseId = hashParts[0] === 'phase' ? parseInt(hashParts[1], 10) : null + if (phaseId === props.phaseId) { + setTimeout(() => scrollToHash(props.location.hash), 100) + } + } + + render() { + return ( +
+ +
+ ) + } +} const enhance = spinnerWhileLoading(props => !props.isLoading) -const EnhancedPhaseFeedView = enhance(PhaseFeedView) +const EnhancedPhaseFeedView = enhance(withRouter(PhaseFeedView)) export default EnhancedPhaseFeedView diff --git a/src/projects/detail/components/ProjectStage.jsx b/src/projects/detail/components/ProjectStage.jsx index fea286765..0d7214aa8 100644 --- a/src/projects/detail/components/ProjectStage.jsx +++ b/src/projects/detail/components/ProjectStage.jsx @@ -5,6 +5,7 @@ import React from 'react' import PT from 'prop-types' import _ from 'lodash' import uncontrollable from 'uncontrollable' +import { withRouter } from 'react-router-dom' import { formatNumberWithCommas } from '../../../helpers/format' import { getPhaseActualData } from '../../../helpers/projectHelper' @@ -22,7 +23,6 @@ import ProductTimelineContainer from '../containers/ProductTimelineContainer' import NotificationsReader from '../../../components/NotificationsReader' import { phaseFeedHOC } from '../containers/PhaseFeedHOC' import spinnerWhileLoading from '../../../components/LoadingSpinner' -import { scrollToHash } from '../../../components/ScrollToAnchors' const enhance = spinnerWhileLoading(props => !props.processing) const EnhancedEditProjectForm = enhance(EditProjectForm) @@ -130,23 +130,26 @@ class ProjectStage extends React.Component{ expandProjectPhase(phase.id, tab) } - componentDidUpdate() { - const { phaseState } = this.props - if (_.get(phaseState, 'isExpanded')) { - const scrollTo = window.location.hash ? window.location.hash.substring(1) : null - if (scrollTo) { - scrollToHash(scrollTo) - } + componentWillReceiveProps(props) { + if (!_.isEmpty(location.hash) && props.location.hash !== this.props.location.hash) { + this.handleUrlHash(props) } } - componentWillReceiveProps(nextProps) { - const { feedId, commentId, phase, phaseState, expandProjectPhase } = this.props - const { feed } = nextProps - if (!_.get(phaseState, 'isExpanded') && feed && (feed.id === parseInt(feedId) || feed.postIds.includes(parseInt(commentId)))){ - expandProjectPhase(phase.id, 'posts') - } + componentWillMount() { + !_.isEmpty(this.props.location.hash) && this.handleUrlHash(this.props) + } + + handleUrlHash(props) { + const { expandProjectPhase, phase, location } = props + const hashParts = _.split(location.hash.substring(1), '-') + const phaseId = hashParts[0] === 'phase' ? parseInt(hashParts[1], 10) : null + + if (phaseId && phase.id === phaseId) { + const tab = hashParts[2] + expandProjectPhase(phaseId, tab) + } } render() { @@ -169,6 +172,7 @@ class ProjectStage extends React.Component{ collapseProjectPhase, expandProjectPhase, commentAnchorPrefix, + isLoading, // comes from phaseFeedHOC currentUser, @@ -253,6 +257,8 @@ class ProjectStage extends React.Component{ projectMembers={projectMembers} onSaveMessage={onSaveMessage} commentAnchorPrefix={commentAnchorPrefix} + phaseId={phase.id} + isLoading={isLoading} /> )} @@ -311,7 +317,7 @@ ProjectStage.propTypes = { commentAnchorPrefix: PT.string, } -const ProjectStageUncontrollable = uncontrollable(ProjectStage, { +const ProjectStageUncontrollable = uncontrollable(withRouter(ProjectStage), { activeTab: 'onTabClick', }) diff --git a/src/projects/detail/components/ProjectStages.jsx b/src/projects/detail/components/ProjectStages.jsx index 744a368f9..fc4ea7c04 100644 --- a/src/projects/detail/components/ProjectStages.jsx +++ b/src/projects/detail/components/ProjectStages.jsx @@ -10,6 +10,7 @@ import { withRouter } from 'react-router-dom' import { formatNumberWithCommas } from '../../../helpers/format' import { getPhaseActualData } from '../../../helpers/projectHelper' +import spinnerWhileLoading from '../../../components/LoadingSpinner' import Section from '../components/Section' import ProjectStage from '../components/ProjectStage' import PhaseCardListHeader from '../components/PhaseCardListHeader' @@ -151,6 +152,10 @@ ProjectStages.propTypes = { updateProductAttachment: PT.func.isRequired, removeProductAttachment: PT.func.isRequired, deleteProjectPhase: PT.func.isRequired, + isLoadingPhases: PT.func.isRequired, } -export default withRouter(ProjectStages) +const enhance = spinnerWhileLoading(props => !props.isLoadingPhases) +const EnhancedProjectStages = enhance(ProjectStages) + +export default withRouter(EnhancedProjectStages) diff --git a/src/projects/detail/containers/FeedContainer.js b/src/projects/detail/containers/FeedContainer.js index 0f35f074f..4631e45ed 100644 --- a/src/projects/detail/containers/FeedContainer.js +++ b/src/projects/detail/containers/FeedContainer.js @@ -226,7 +226,7 @@ class FeedView extends React.Component { } const scrollTo = window.location.hash ? window.location.hash.substring(1) : null if (scrollTo) { - setTimeout(() => scrollToHash(scrollTo), 0) + setTimeout(() => scrollToHash(scrollTo), 100) } }) } diff --git a/src/projects/detail/containers/PhaseFeedHOC.jsx b/src/projects/detail/containers/PhaseFeedHOC.jsx index 74e1127d0..d7f957d65 100644 --- a/src/projects/detail/containers/PhaseFeedHOC.jsx +++ b/src/projects/detail/containers/PhaseFeedHOC.jsx @@ -43,9 +43,9 @@ const phaseFeedHOC = (Component) => { } componentWillMount() { - const { isLoading, loadPhaseFeed, phase, project } = this.props + const { isLoading, topic, loadPhaseFeed, phase, project } = this.props - if (!isLoading) { + if (!isLoading && !topic) { loadPhaseFeed(project.id, phase.id) } } diff --git a/src/projects/detail/containers/ProjectInfoContainer.js b/src/projects/detail/containers/ProjectInfoContainer.js index 960aee397..357504743 100644 --- a/src/projects/detail/containers/ProjectInfoContainer.js +++ b/src/projects/detail/containers/ProjectInfoContainer.js @@ -61,7 +61,7 @@ class ProjectInfoContainer extends React.Component { } componentWillMount() { - const { project, isFeedsLoading, feeds, phases, phasesTopics, loadPhaseFeed } = this.props + const { project, isFeedsLoading, feeds, phases, phasesTopics, loadPhaseFeed, location } = this.props this.setDuration(project) @@ -78,39 +78,60 @@ class ProjectInfoContainer extends React.Component { loadPhaseFeed(project.id, phase.id) } }) + + // handle url hash + if (!_.isEmpty(location.hash)) { + this.handleUrlHash(this.props) + } } componentWillReceiveProps(props) { - const { project, phases, feeds, loadProjectPhasesWithProducts, loadPhaseFeed, location } = props + const { project, location } = props this.setDuration(project) if (!_.isEmpty(location.hash) && location.hash !== this.props.location.hash) { - const hashParts = _.split(location.hash.substring(1), '-') - const hashPrimaryId = parseInt(hashParts[1], 10) + this.handleUrlHash(props) + } + } - switch (hashParts[0]) { - case 'comment': - if (!this.foundCommentInFeeds(feeds, hashPrimaryId)) { - this.loadAllFeeds() - } - break + // this is just to see if the comment/feed/post/phase the url hash is attempting to scroll to is loaded or not + // if its not loaded then we load the appropriate item + handleUrlHash(props) { + const { project, isFeedsLoading, phases, phasesTopics, feeds, loadProjectPhasesWithProducts, loadPhaseFeed, location } = props + const hashParts = _.split(location.hash.substring(1), '-') + const hashPrimaryId = parseInt(hashParts[1], 10) + + switch (hashParts[0]) { + case 'comment': { + if (!isFeedsLoading && !this.foundCommentInFeeds(feeds, hashPrimaryId)) { + this.loadAllFeeds() + } + break + } - case 'feed': - if (!_.some(feeds, { id: hashPrimaryId})) { - this.loadAllFeeds() - } - break + case 'feed': { + if (!isFeedsLoading && !_.some(feeds, { id: hashPrimaryId})) { + this.loadAllFeeds() + } + break + } + + case 'phase': { + const postId = parseInt(hashParts[3], 10) - case 'phase': + if (phases && phasesTopics) { if (!_.some(phases, { id: hashPrimaryId})) { loadProjectPhasesWithProducts(project.id) .then(({ value: newPhases }) => { _.some(newPhases, { id: hashPrimaryId}) && loadPhaseFeed(project.id, hashPrimaryId) }) + } else if(postId && !(phasesTopics[hashPrimaryId].topic && phasesTopics[hashPrimaryId].topic.postIds.includes(postId))) { + loadPhaseFeed(project.id, hashPrimaryId) } - break } + break + } } } diff --git a/src/projects/detail/containers/ProjectPlanContainer.jsx b/src/projects/detail/containers/ProjectPlanContainer.jsx index 460530cbd..1ea96fe6d 100644 --- a/src/projects/detail/containers/ProjectPlanContainer.jsx +++ b/src/projects/detail/containers/ProjectPlanContainer.jsx @@ -7,6 +7,7 @@ import React from 'react' import PT from 'prop-types' import { connect } from 'react-redux' +import { withRouter } from 'react-router-dom' import _ from 'lodash' import { @@ -63,30 +64,20 @@ class ProjectPlanContainer extends React.Component { } componentDidMount() { - const { expandProjectPhase } = this.props - const scrollTo = window.location.hash ? window.location.hash.substring(1) : null - if (scrollTo) { - const hashParts = _.split(scrollTo, '-') - const phaseId = hashParts[0] === 'phase' ? parseInt(hashParts[1], 10) : null - if (phaseId) { - let tab = hashParts[2] - tab = tab === scrollTo ? 'timeline' : tab - // we just open tab, while smooth scrolling has to be caused by URL hash - expandProjectPhase(phaseId, tab) - } - } else { - // if the user is a customer and its not a direct link to a particular phase - // then by default expand all phases which are active - if (this.props.isCustomerUser) { - _.forEach(this.props.phases, phase => { - if (phase.status === PHASE_STATUS_ACTIVE) { - expandProjectPhase(phase.id) - } - }) - } + const { expandProjectPhase, location } = this.props + + // if the user is a customer and its not a direct link to a particular phase + // then by default expand all phases which are active + if (_.isEmpty(location.hash) && this.props.isCustomerUser) { + _.forEach(this.props.phases, phase => { + if (phase.status === PHASE_STATUS_ACTIVE) { + expandProjectPhase(phase.id) + } + }) } } + componentWillUnmount() { const { collapseAllProjectPhases } = this.props @@ -208,6 +199,7 @@ const mapStateToProps = ({ projectState, projectTopics, phasesTopics, templates isFeedsLoading: projectTopics.isLoading, phasesTopics, phasesStates: projectState.phasesStates, + isLoadingPhases: projectState.isLoadingPhases, } } @@ -224,4 +216,4 @@ const mapDispatchToProps = { collapseAllProjectPhases, } -export default connect(mapStateToProps, mapDispatchToProps)(ProjectPlanContainer) +export default connect(mapStateToProps, mapDispatchToProps)(withRouter(ProjectPlanContainer)) From 46ec7308322f9506728a3512f150401d5296519b Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Tue, 21 May 2019 19:27:18 +0530 Subject: [PATCH 04/14] removed check in phaseFeedHOC --- src/projects/detail/containers/PhaseFeedHOC.jsx | 4 ++-- src/projects/detail/containers/ProjectPlanContainer.jsx | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/projects/detail/containers/PhaseFeedHOC.jsx b/src/projects/detail/containers/PhaseFeedHOC.jsx index d7f957d65..74e1127d0 100644 --- a/src/projects/detail/containers/PhaseFeedHOC.jsx +++ b/src/projects/detail/containers/PhaseFeedHOC.jsx @@ -43,9 +43,9 @@ const phaseFeedHOC = (Component) => { } componentWillMount() { - const { isLoading, topic, loadPhaseFeed, phase, project } = this.props + const { isLoading, loadPhaseFeed, phase, project } = this.props - if (!isLoading && !topic) { + if (!isLoading) { loadPhaseFeed(project.id, phase.id) } } diff --git a/src/projects/detail/containers/ProjectPlanContainer.jsx b/src/projects/detail/containers/ProjectPlanContainer.jsx index 1ea96fe6d..2d069ce26 100644 --- a/src/projects/detail/containers/ProjectPlanContainer.jsx +++ b/src/projects/detail/containers/ProjectPlanContainer.jsx @@ -77,7 +77,6 @@ class ProjectPlanContainer extends React.Component { } } - componentWillUnmount() { const { collapseAllProjectPhases } = this.props From d322a4e4a528eb8a5afc2612e12b55e2b5bab7a8 Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Wed, 22 May 2019 21:19:52 +0530 Subject: [PATCH 05/14] improved code and fixed couple of issues in project plan tab --- .../detail/components/PhaseFeed/PhaseFeed.jsx | 12 +++++++----- src/projects/detail/components/ProjectStage.jsx | 14 ++++++++------ src/projects/detail/containers/FeedContainer.js | 7 ++----- src/projects/detail/containers/PhaseFeedHOC.jsx | 4 ++-- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx b/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx index 629a91089..b244d5772 100644 --- a/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx +++ b/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx @@ -18,21 +18,23 @@ class PhaseFeedView extends React.Component { super(props) } - componentWillMount() { + componentDidMount() { !_.isEmpty(this.props.location.hash) && this.handleUrlHash(this.props) } - componentWillReceiveProps(props) { - if (!_.isEmpty(location.hash) && props.location.hash !== this.props.location.hash) { - this.handleUrlHash(props) + componentDidUpdate(prevProps) { + const { location } = this.props + if (!_.isEmpty(location.hash) && location.hash !== prevProps.location.hash) { + this.handleUrlHash(this.props) } } + // when the phase feed is actually loaded/rendered scroll to the appropriate post depending on url hash handleUrlHash(props) { const hashParts = _.split(location.hash.substring(1), '-') const phaseId = hashParts[0] === 'phase' ? parseInt(hashParts[1], 10) : null if (phaseId === props.phaseId) { - setTimeout(() => scrollToHash(props.location.hash), 100) + scrollToHash(props.location.hash) } } diff --git a/src/projects/detail/components/ProjectStage.jsx b/src/projects/detail/components/ProjectStage.jsx index 0d7214aa8..78a62c576 100644 --- a/src/projects/detail/components/ProjectStage.jsx +++ b/src/projects/detail/components/ProjectStage.jsx @@ -130,16 +130,18 @@ class ProjectStage extends React.Component{ expandProjectPhase(phase.id, tab) } - componentWillReceiveProps(props) { - if (!_.isEmpty(location.hash) && props.location.hash !== this.props.location.hash) { - this.handleUrlHash(props) - } + componentDidMount() { + !_.isEmpty(this.props.location.hash) && this.handleUrlHash(this.props) } - componentWillMount() { - !_.isEmpty(this.props.location.hash) && this.handleUrlHash(this.props) + componentDidUpdate(prevProps) { + const { location } = this.props + if (!_.isEmpty(location.hash) && location.hash !== prevProps.location.hash) { + this.handleUrlHash(this.props) + } } + // expand a phase if necessary depending on the url hash handleUrlHash(props) { const { expandProjectPhase, phase, location } = props diff --git a/src/projects/detail/containers/FeedContainer.js b/src/projects/detail/containers/FeedContainer.js index 4631e45ed..156dfbd53 100644 --- a/src/projects/detail/containers/FeedContainer.js +++ b/src/projects/detail/containers/FeedContainer.js @@ -79,9 +79,6 @@ class FeedView extends React.Component { componentDidMount() { window.addEventListener('beforeunload', this.onLeave) - } - - componentWillMount() { this.init(this.props) } @@ -201,7 +198,7 @@ class FeedView extends React.Component { return item } - init(props, prevProps) { + init(props, prevProps) {console.log('infinite') const { feeds } = props let resetNewPost = false if (prevProps) { @@ -226,7 +223,7 @@ class FeedView extends React.Component { } const scrollTo = window.location.hash ? window.location.hash.substring(1) : null if (scrollTo) { - setTimeout(() => scrollToHash(scrollTo), 100) + scrollToHash(scrollTo) } }) } diff --git a/src/projects/detail/containers/PhaseFeedHOC.jsx b/src/projects/detail/containers/PhaseFeedHOC.jsx index 74e1127d0..d7f957d65 100644 --- a/src/projects/detail/containers/PhaseFeedHOC.jsx +++ b/src/projects/detail/containers/PhaseFeedHOC.jsx @@ -43,9 +43,9 @@ const phaseFeedHOC = (Component) => { } componentWillMount() { - const { isLoading, loadPhaseFeed, phase, project } = this.props + const { isLoading, topic, loadPhaseFeed, phase, project } = this.props - if (!isLoading) { + if (!isLoading && !topic) { loadPhaseFeed(project.id, phase.id) } } From b84c5cabdff5723ba2e74b5090e5631e2d8eea38 Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Thu, 23 May 2019 12:51:53 +0530 Subject: [PATCH 06/14] fixed specification tab auto scrolling --- src/components/ScrollToAnchors.jsx | 2 +- .../detail/components/EditProjectForm/EditProjectForm.jsx | 7 +++++-- src/projects/detail/components/ProjectStage.jsx | 1 + src/projects/detail/components/SpecSection.jsx | 1 + src/projects/detail/containers/FeedContainer.js | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/ScrollToAnchors.jsx b/src/components/ScrollToAnchors.jsx index 19058226c..90ba4db22 100644 --- a/src/components/ScrollToAnchors.jsx +++ b/src/components/ScrollToAnchors.jsx @@ -43,7 +43,7 @@ export function scrollToAnchors(Component) { componentDidMount() { const { hash } = window.location - if (hash !== '') { + if (!this.props.disableAutoScrolling && hash !== '') { // Push onto callback queue so it runs after the DOM is updated, // this is required when navigating from a different page so that // the element is rendered on the page before trying to getElementById. diff --git a/src/projects/detail/components/EditProjectForm/EditProjectForm.jsx b/src/projects/detail/components/EditProjectForm/EditProjectForm.jsx index 9f6bb7eeb..584045f7b 100644 --- a/src/projects/detail/components/EditProjectForm/EditProjectForm.jsx +++ b/src/projects/detail/components/EditProjectForm/EditProjectForm.jsx @@ -268,7 +268,7 @@ class EditProjectForm extends Component { render() { - const { isEdittable, showHidden, productTemplates, productCategories } = this.props + const { isEdittable, showHidden, productTemplates, productCategories, disableAutoScrolling } = this.props const { template } = this.state const { project, dirtyProject } = this.state const onLeaveMessage = this.onLeave() || '' @@ -287,6 +287,7 @@ class EditProjectForm extends Component { sectionNumber={idx + 1} resetFeatures={this.onFeaturesSaveAttachedClick} showFeaturesDialog={this.showFeaturesDialog} + disableAutoScrolling={disableAutoScrolling} // TODO we shoudl not update the props (section is coming from props) validate={(isInvalid) => section.isInvalid = isInvalid} showHidden={showHidden} @@ -353,7 +354,8 @@ class EditProjectForm extends Component { } EditProjectForm.defaultProps = { - shouldUpdateTemplate: false + shouldUpdateTemplate: false, + disableAutoScrolling: false, } EditProjectForm.propTypes = { @@ -371,6 +373,7 @@ EditProjectForm.propTypes = { updateAttachment: PropTypes.func.isRequired, removeAttachment: PropTypes.func.isRequired, shouldUpdateTemplate: PropTypes.bool, + disableAutoScrolling: PropTypes.bool, } export default EditProjectForm diff --git a/src/projects/detail/components/ProjectStage.jsx b/src/projects/detail/components/ProjectStage.jsx index 78a62c576..4985afe91 100644 --- a/src/projects/detail/components/ProjectStage.jsx +++ b/src/projects/detail/components/ProjectStage.jsx @@ -286,6 +286,7 @@ class ProjectStage extends React.Component{ removeAttachment={this.removeProductAttachment} attachmentsStorePath={attachmentsStorePath} canManageAttachments={!!currentMemberRole} + disableAutoScrolling={true} /> } diff --git a/src/projects/detail/components/SpecSection.jsx b/src/projects/detail/components/SpecSection.jsx index da9efb25e..ed278e4b5 100644 --- a/src/projects/detail/components/SpecSection.jsx +++ b/src/projects/detail/components/SpecSection.jsx @@ -425,6 +425,7 @@ SpecSection.propTypes = { updateAttachment: PropTypes.func, removeAttachment: PropTypes.func, productCategories: PropTypes.array.isRequired, + disableAutoScrolling: PropTypes.bool, } export default scrollToAnchors(SpecSection) diff --git a/src/projects/detail/containers/FeedContainer.js b/src/projects/detail/containers/FeedContainer.js index 156dfbd53..ec34c9b0b 100644 --- a/src/projects/detail/containers/FeedContainer.js +++ b/src/projects/detail/containers/FeedContainer.js @@ -198,7 +198,7 @@ class FeedView extends React.Component { return item } - init(props, prevProps) {console.log('infinite') + init(props, prevProps) { const { feeds } = props let resetNewPost = false if (prevProps) { From 78e67b889ae09ac81649ae3c35ed194722cc2d4d Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Thu, 23 May 2019 12:55:43 +0530 Subject: [PATCH 07/14] lint fix --- src/projects/detail/components/ProjectStage.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/projects/detail/components/ProjectStage.jsx b/src/projects/detail/components/ProjectStage.jsx index 4985afe91..96df9bfb3 100644 --- a/src/projects/detail/components/ProjectStage.jsx +++ b/src/projects/detail/components/ProjectStage.jsx @@ -286,7 +286,7 @@ class ProjectStage extends React.Component{ removeAttachment={this.removeProductAttachment} attachmentsStorePath={attachmentsStorePath} canManageAttachments={!!currentMemberRole} - disableAutoScrolling={true} + disableAutoScrolling /> } From af91c328503328b08d7d67090b92dc64a9a850ef Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Thu, 23 May 2019 19:53:54 +0530 Subject: [PATCH 08/14] smooth scrolling fixed --- src/projects/detail/components/PhaseFeed/PhaseFeed.jsx | 2 +- src/projects/detail/components/ProjectStages.jsx | 2 +- src/projects/detail/containers/FeedContainer.js | 2 +- src/projects/detail/containers/ProjectInfoContainer.js | 1 - src/projects/detail/containers/ProjectPlanContainer.jsx | 3 ++- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx b/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx index b244d5772..dc69db229 100644 --- a/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx +++ b/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx @@ -34,7 +34,7 @@ class PhaseFeedView extends React.Component { const hashParts = _.split(location.hash.substring(1), '-') const phaseId = hashParts[0] === 'phase' ? parseInt(hashParts[1], 10) : null if (phaseId === props.phaseId) { - scrollToHash(props.location.hash) + setTimeout(() => scrollToHash(props.location.hash), 100) } } diff --git a/src/projects/detail/components/ProjectStages.jsx b/src/projects/detail/components/ProjectStages.jsx index fc4ea7c04..6c4005df2 100644 --- a/src/projects/detail/components/ProjectStages.jsx +++ b/src/projects/detail/components/ProjectStages.jsx @@ -152,7 +152,7 @@ ProjectStages.propTypes = { updateProductAttachment: PT.func.isRequired, removeProductAttachment: PT.func.isRequired, deleteProjectPhase: PT.func.isRequired, - isLoadingPhases: PT.func.isRequired, + isLoadingPhases: PT.bool.isRequired, } const enhance = spinnerWhileLoading(props => !props.isLoadingPhases) diff --git a/src/projects/detail/containers/FeedContainer.js b/src/projects/detail/containers/FeedContainer.js index 0c0250c16..124d462c5 100644 --- a/src/projects/detail/containers/FeedContainer.js +++ b/src/projects/detail/containers/FeedContainer.js @@ -223,7 +223,7 @@ class FeedView extends React.Component { } const scrollTo = window.location.hash ? window.location.hash.substring(1) : null if (scrollTo) { - scrollToHash(scrollTo) + setTimeout(() => scrollToHash(scrollTo), 100) } }) } diff --git a/src/projects/detail/containers/ProjectInfoContainer.js b/src/projects/detail/containers/ProjectInfoContainer.js index 69bb04a36..92e26d96e 100644 --- a/src/projects/detail/containers/ProjectInfoContainer.js +++ b/src/projects/detail/containers/ProjectInfoContainer.js @@ -507,7 +507,6 @@ class ProjectInfoContainer extends React.Component { ...this.extractAttachmentLinksFromPosts(feeds), ...this.extractAttachmentLinksFromPosts(phaseFeeds) ] - console.dir(attachments) return (
diff --git a/src/projects/detail/containers/ProjectPlanContainer.jsx b/src/projects/detail/containers/ProjectPlanContainer.jsx index 2d069ce26..cc5b550bd 100644 --- a/src/projects/detail/containers/ProjectPlanContainer.jsx +++ b/src/projects/detail/containers/ProjectPlanContainer.jsx @@ -96,6 +96,7 @@ class ProjectPlanContainer extends React.Component { productsTimelines, phasesTopics, isProcessing, + isLoadingPhases } = this.props // manager user sees all phases @@ -161,7 +162,7 @@ class ProjectPlanContainer extends React.Component { ) : ( )} - {isProjectLive && checkPermission(PERMISSIONS.EDIT_PROJECT_PLAN, project, phases) && (
+ {isProjectLive && checkPermission(PERMISSIONS.EDIT_PROJECT_PLAN, project, phases) && !isLoadingPhases && (
Add New Phase
)} From 197b5f54fdfd0999daa63c0fa01fba466ab165d9 Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Fri, 24 May 2019 13:56:23 +0530 Subject: [PATCH 09/14] fix timeline on new phase --- src/projects/actions/projectDashboard.js | 55 ++---------------- src/projects/actions/projectPlan.js | 58 +++++++++++++++++++ .../detail/containers/ProjectInfoContainer.js | 14 ++--- 3 files changed, 69 insertions(+), 58 deletions(-) create mode 100644 src/projects/actions/projectPlan.js diff --git a/src/projects/actions/projectDashboard.js b/src/projects/actions/projectDashboard.js index d20494ed1..131e3706b 100644 --- a/src/projects/actions/projectDashboard.js +++ b/src/projects/actions/projectDashboard.js @@ -1,15 +1,9 @@ import _ from 'lodash' import { loadMembers } from '../../actions/members' -import { loadProject, loadProjectInvite, loadDirectProjectData, loadProjectPhasesWithProducts } from './project' +import { loadProject, loadProjectInvite, loadDirectProjectData } from './project' +import { loadProjectPlan } from './projectPlan' import { loadProjectsMetadata } from '../../actions/templates' -import { loadProductTimelineWithMilestones } from './productsTimelines' -import { loadFeedsForPhases } from './phasesTopics' -import { LOAD_PROJECT_DASHBOARD, - LOAD_ADDITIONAL_PROJECT_DATA, - DISCOURSE_BOT_USERID, - CODER_BOT_USERID, - TC_SYSTEM_USERID -} from '../../config/constants' +import { LOAD_PROJECT_DASHBOARD, LOAD_ADDITIONAL_PROJECT_DATA } from '../../config/constants' /** * Load all project data to paint the dashboard @@ -44,28 +38,7 @@ const getDashboardData = (dispatch, getState, projectId, isOnlyLoadProjectInfo) // for new projects load phases, products, project template and product templates if (project.version === 'v3') { promises.push( - dispatch(loadProjectPhasesWithProducts(projectId)) - .then(({ value: phases }) => { - loadFeedsForPhases(projectId, phases, dispatch) - .then((phaseFeeds) => { - let phaseUserIds = [] - _.forEach(phaseFeeds, phaseFeed => { - phaseUserIds = _.union(phaseUserIds, _.map(phaseFeed.topics, 'userId')) - _.forEach(phaseFeed.topics, topic => { - phaseUserIds = _.union(phaseUserIds, _.map(topic.posts, 'userId')) - }) - // this is to remove any nulls from the list (dev had some bad data) - _.remove(phaseUserIds, i => !i || [DISCOURSE_BOT_USERID, CODER_BOT_USERID, TC_SYSTEM_USERID].indexOf(i) > -1) - }) - // take difference of userIds identified from project members - phaseUserIds = _.difference(phaseUserIds, userIds) - - dispatch(loadMembers(phaseUserIds)) - }) - // load timelines for phase products here together with all dashboard data - // as we need to know timeline data not only inside timeline container - loadTimelinesForPhasesProducts(phases, dispatch) - }) + dispatch(loadProjectPlan(projectId, userIds)) ) } @@ -96,26 +69,6 @@ const getData = (dispatch, getState, projectId, isOnlyLoadProjectInfo) => { .catch(() => getDashboardData(dispatch, getState, projectId, isOnlyLoadProjectInfo)) } -/** - * Load timelines for phase's products - * - * @param {Array} phases list of phases - * @param {Function} dispatch dispatch function - */ -function loadTimelinesForPhasesProducts(phases, dispatch) { - const products = [] - - phases.forEach((phase) => { - phase.products.forEach((product) => { - products.push(product) - }) - }) - - return Promise.all( - products.map((product) => dispatch(loadProductTimelineWithMilestones(product.id))) - ) -} - export function loadProjectDashboard(projectId, isOnlyLoadProjectInfo = false) { return (dispatch, getState) => { return dispatch({ diff --git a/src/projects/actions/projectPlan.js b/src/projects/actions/projectPlan.js new file mode 100644 index 000000000..324a7615b --- /dev/null +++ b/src/projects/actions/projectPlan.js @@ -0,0 +1,58 @@ +import _ from 'lodash' +import { loadMembers } from '../../actions/members' +import { loadProjectPhasesWithProducts } from './project' +import { loadFeedsForPhases } from './phasesTopics' +import { loadProductTimelineWithMilestones } from './productsTimelines' +import { + DISCOURSE_BOT_USERID, + CODER_BOT_USERID, + TC_SYSTEM_USERID +} from '../../config/constants' + + +/** + * Load timelines for phase's products + * + * @param {Array} phases list of phases + * @param {Function} dispatch dispatch function + */ +function loadTimelinesForPhasesProducts(phases, dispatch) { + const products = [] + + phases.forEach((phase) => { + phase.products.forEach((product) => { + products.push(product) + }) + }) + + return Promise.all( + products.map((product) => dispatch(loadProductTimelineWithMilestones(product.id))) + ) +} + +export function loadProjectPlan(projectId, existingUserIds) { + return (dispatch) => {console.log('projectPlan') + return dispatch(loadProjectPhasesWithProducts(projectId)) + .then(({ value: phases }) => { + loadFeedsForPhases(projectId, phases, dispatch) + .then((phaseFeeds) => { + let phaseUserIds = [] + _.forEach(phaseFeeds, phaseFeed => { + phaseUserIds = _.union(phaseUserIds, _.map(phaseFeed.topics, 'userId')) + _.forEach(phaseFeed.topics, topic => { + phaseUserIds = _.union(phaseUserIds, _.map(topic.posts, 'userId')) + }) + // this is to remove any nulls from the list (dev had some bad data) + _.remove(phaseUserIds, i => !i || [DISCOURSE_BOT_USERID, CODER_BOT_USERID, TC_SYSTEM_USERID].indexOf(i) > -1) + }) + // take difference of existingUserIds identified from project members + phaseUserIds = _.difference(phaseUserIds, existingUserIds) + + dispatch(loadMembers(phaseUserIds)) + }) + // load timelines for phase products here together with all dashboard data + // as we need to know timeline data not only inside timeline container + loadTimelinesForPhasesProducts(phases, dispatch) + }) + } +} diff --git a/src/projects/detail/containers/ProjectInfoContainer.js b/src/projects/detail/containers/ProjectInfoContainer.js index 92e26d96e..bca064cf8 100644 --- a/src/projects/detail/containers/ProjectInfoContainer.js +++ b/src/projects/detail/containers/ProjectInfoContainer.js @@ -7,9 +7,10 @@ import _ from 'lodash' import LinksMenu from '../../../components/LinksMenu/LinksMenu' import FileLinksMenu from '../../../components/LinksMenu/FileLinksMenu' import TeamManagementContainer from './TeamManagementContainer' -import { updateProject, deleteProject, loadProjectPhasesWithProducts } from '../../actions/project' +import { updateProject, deleteProject } from '../../actions/project' import { loadDashboardFeeds, loadProjectMessages } from '../../actions/projectTopics' import { loadPhaseFeed } from '../../actions/phasesTopics' +import { loadProjectPlan } from '../../actions/projectPlan' import { setDuration } from '../../../helpers/projectHelper' import { PROJECT_ROLE_OWNER, PROJECT_ROLE_COPILOT, PROJECT_ROLE_MANAGER, DIRECT_PROJECT_URL, SALESFORCE_PROJECT_LEAD_LINK, PROJECT_STATUS_CANCELLED, PROJECT_ATTACHMENTS_FOLDER, @@ -106,7 +107,7 @@ class ProjectInfoContainer extends React.Component { // this is just to see if the comment/feed/post/phase the url hash is attempting to scroll to is loaded or not // if its not loaded then we load the appropriate item handleUrlHash(props) { - const { project, isFeedsLoading, phases, phasesTopics, feeds, loadProjectPhasesWithProducts, loadPhaseFeed, location } = props + const { project, isFeedsLoading, phases, phasesTopics, feeds, loadProjectPlan, loadPhaseFeed, location } = props const hashParts = _.split(location.hash.substring(1), '-') const hashPrimaryId = parseInt(hashParts[1], 10) @@ -130,10 +131,9 @@ class ProjectInfoContainer extends React.Component { if (phases && phasesTopics) { if (!_.some(phases, { id: hashPrimaryId})) { - loadProjectPhasesWithProducts(project.id) - .then(({ value: newPhases }) => { - _.some(newPhases, { id: hashPrimaryId}) && loadPhaseFeed(project.id, hashPrimaryId) - }) + let existingUserIds = _.map(project.members, 'userId') + existingUserIds= _.union(existingUserIds, _.map(project.invites, 'userId')) + loadProjectPlan(project.id, existingUserIds) } else if(postId && !(phasesTopics[hashPrimaryId].topic && phasesTopics[hashPrimaryId].topic.postIds.includes(postId))) { loadPhaseFeed(project.id, hashPrimaryId) } @@ -607,6 +607,6 @@ const mapStateToProps = ({ templates, projectState, members, loadUser }) => { const mapDispatchToProps = { updateProject, deleteProject, addProjectAttachment, updateProjectAttachment, loadProjectMessages, discardAttachments, uploadProjectAttachments, loadDashboardFeeds, loadPhaseFeed, changeAttachmentPermission, - removeProjectAttachment, loadProjectPhasesWithProducts, saveFeedComment } + removeProjectAttachment, loadProjectPlan, saveFeedComment } export default connect(mapStateToProps, mapDispatchToProps)(withRouter(ProjectInfoContainer)) From 0b279f58ef09fc79e25b756cfb1e049b06521c5a Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Fri, 24 May 2019 14:08:51 +0530 Subject: [PATCH 10/14] remove console --- src/projects/actions/projectPlan.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/projects/actions/projectPlan.js b/src/projects/actions/projectPlan.js index 324a7615b..71707f9da 100644 --- a/src/projects/actions/projectPlan.js +++ b/src/projects/actions/projectPlan.js @@ -31,7 +31,7 @@ function loadTimelinesForPhasesProducts(phases, dispatch) { } export function loadProjectPlan(projectId, existingUserIds) { - return (dispatch) => {console.log('projectPlan') + return (dispatch) => { return dispatch(loadProjectPhasesWithProducts(projectId)) .then(({ value: phases }) => { loadFeedsForPhases(projectId, phases, dispatch) From 562d156ea8cd60b67111941a9f60e10533ce49a2 Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Sat, 25 May 2019 21:30:38 +0530 Subject: [PATCH 11/14] fix issues --- src/projects/detail/ProjectDetail.jsx | 1 + src/projects/detail/components/PhaseFeed/PhaseFeed.jsx | 7 ------- src/projects/detail/components/ProjectStages.jsx | 2 ++ src/projects/detail/containers/DashboardContainer.jsx | 2 ++ src/projects/detail/containers/ProjectPlanContainer.jsx | 4 +++- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/projects/detail/ProjectDetail.jsx b/src/projects/detail/ProjectDetail.jsx index 56b4710c8..ae164f9eb 100644 --- a/src/projects/detail/ProjectDetail.jsx +++ b/src/projects/detail/ProjectDetail.jsx @@ -76,6 +76,7 @@ const ProjectDetailView = (props) => { isProcessing: props.isProcessing, allProductTemplates: props.allProductTemplates, productsTimelines: props.productsTimelines, + location: props.location, } return } diff --git a/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx b/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx index dc69db229..0269568ff 100644 --- a/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx +++ b/src/projects/detail/components/PhaseFeed/PhaseFeed.jsx @@ -22,13 +22,6 @@ class PhaseFeedView extends React.Component { !_.isEmpty(this.props.location.hash) && this.handleUrlHash(this.props) } - componentDidUpdate(prevProps) { - const { location } = this.props - if (!_.isEmpty(location.hash) && location.hash !== prevProps.location.hash) { - this.handleUrlHash(this.props) - } - } - // when the phase feed is actually loaded/rendered scroll to the appropriate post depending on url hash handleUrlHash(props) { const hashParts = _.split(location.hash.substring(1), '-') diff --git a/src/projects/detail/components/ProjectStages.jsx b/src/projects/detail/components/ProjectStages.jsx index 6c4005df2..595cf0aa3 100644 --- a/src/projects/detail/components/ProjectStages.jsx +++ b/src/projects/detail/components/ProjectStages.jsx @@ -94,6 +94,7 @@ const ProjectStages = ({ collapseProjectPhase, feedId, commentId, + location }) => (
@@ -101,6 +102,7 @@ const ProjectStages = ({ { phases.map((phase, index) => ( Date: Mon, 27 May 2019 13:10:19 +0530 Subject: [PATCH 12/14] moved scrollTo to singleFeedContainer --- src/projects/detail/containers/FeedContainer.js | 10 ---------- src/projects/detail/containers/SingleFeedContainer.jsx | 9 +++++++++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/projects/detail/containers/FeedContainer.js b/src/projects/detail/containers/FeedContainer.js index 124d462c5..9eddbaee6 100644 --- a/src/projects/detail/containers/FeedContainer.js +++ b/src/projects/detail/containers/FeedContainer.js @@ -32,7 +32,6 @@ import Section from '../components/Section' import SectionTitle from '../components/SectionTitle' import SingleFeedContainer from './SingleFeedContainer' -import { scrollToHash } from '../../../components/ScrollToAnchors' import { isSystemUser } from '../../../helpers/tcHelpers' import { checkPermission } from '../../../helpers/permissions' import PERMISSIONS from '../../../config/permissions' @@ -216,15 +215,6 @@ class FeedView extends React.Component { const resetNewComment = prevFeed && prevFeed.isAddingComment && !feed.isAddingComment && !feed.error return this.mapFeed(feed, this.state.showAll.indexOf(feed.id) > -1, resetNewComment, prevProps) }).filter(item => item) - }, () => { - if (prevProps) { - // only scroll at first time - return - } - const scrollTo = window.location.hash ? window.location.hash.substring(1) : null - if (scrollTo) { - setTimeout(() => scrollToHash(scrollTo), 100) - } }) } diff --git a/src/projects/detail/containers/SingleFeedContainer.jsx b/src/projects/detail/containers/SingleFeedContainer.jsx index 844b9671c..692fb31d2 100644 --- a/src/projects/detail/containers/SingleFeedContainer.jsx +++ b/src/projects/detail/containers/SingleFeedContainer.jsx @@ -14,6 +14,7 @@ import React from 'react' import _ from 'lodash' import ScrollableFeed from '../../../components/Feed/ScrollableFeed' +import { scrollToHash } from '../../../components/ScrollToAnchors' const bindMethods = [ 'onNewCommentChange', @@ -43,6 +44,14 @@ class SingleFeedContainer extends React.Component { }) } + componentDidMount() { + // we use this to just scroll to a feed block or comment in a feed block, if there is a url hash + const scrollTo = window.location.hash ? window.location.hash.substring(1) : null + if (scrollTo) { + setTimeout(() => scrollToHash(scrollTo), 100) + } + } + render() { const nonBindProps = _.omit(this.props, bindMethods) const bindProps = _.zipObject(bindMethods, bindMethods.map((method) => this[method])) From 2bde4297f3db027a3e68a3ae7242e0ec821ea03b Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Mon, 27 May 2019 13:52:02 +0530 Subject: [PATCH 13/14] check on scrollTo --- .../detail/containers/SingleFeedContainer.jsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/projects/detail/containers/SingleFeedContainer.jsx b/src/projects/detail/containers/SingleFeedContainer.jsx index 692fb31d2..84f4687fa 100644 --- a/src/projects/detail/containers/SingleFeedContainer.jsx +++ b/src/projects/detail/containers/SingleFeedContainer.jsx @@ -45,10 +45,18 @@ class SingleFeedContainer extends React.Component { } componentDidMount() { - // we use this to just scroll to a feed block or comment in a feed block, if there is a url hash + // we use this to just scroll to a feed block or comment in a feed block, + // only if there is a url hash and the feed id and comment id match this feed const scrollTo = window.location.hash ? window.location.hash.substring(1) : null if (scrollTo) { - setTimeout(() => scrollToHash(scrollTo), 100) + const hashParts = _.split(scrollTo, '-') + const hashId = parseInt(hashParts[1], 10) + if ( + (hashParts[0] === 'feed' && hashId === this.props.id) || + (hashParts[0] === 'comment' && this.props.comments && _.some(this.props.comments, { id: hashId })) + ) { + setTimeout(() => scrollToHash(scrollTo), 100) + } } } From b33a32717a0b52ddb5ddafd9f61f2982182e0efa Mon Sep 17 00:00:00 2001 From: sumitdaga Date: Tue, 28 May 2019 10:29:42 +0530 Subject: [PATCH 14/14] small fix --- src/projects/detail/containers/FeedContainer.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/projects/detail/containers/FeedContainer.js b/src/projects/detail/containers/FeedContainer.js index 9eddbaee6..ff0978d81 100644 --- a/src/projects/detail/containers/FeedContainer.js +++ b/src/projects/detail/containers/FeedContainer.js @@ -78,6 +78,9 @@ class FeedView extends React.Component { componentDidMount() { window.addEventListener('beforeunload', this.onLeave) + } + + componentWillMount() { this.init(this.props) }