@@ -280,9 +283,14 @@ PhaseCard.propTypes = {
const mapStateToProps = ({loadUser, projectState}) => {
+ const adminRoles = [
+ ROLE_ADMINISTRATOR,
+ ROLE_CONNECT_ADMIN,
+ ]
return {
currentUserRoles: loadUser.user.roles,
- isUpdating: projectState.processing
+ isUpdating: projectState.processing,
+ isAdmin: _.intersection(loadUser.user.roles, adminRoles).length > 0
}
}
diff --git a/src/projects/detail/components/timeline/FormFieldDate/FormFieldDate.jsx b/src/projects/detail/components/timeline/FormFieldDate/FormFieldDate.jsx
index 153b649f4..c62b5030d 100644
--- a/src/projects/detail/components/timeline/FormFieldDate/FormFieldDate.jsx
+++ b/src/projects/detail/components/timeline/FormFieldDate/FormFieldDate.jsx
@@ -5,32 +5,21 @@
*/
import React from 'react'
import PT from 'prop-types'
-import _ from 'lodash'
-import cn from 'classnames'
import FormsyForm from 'appirio-tech-react-components/components/Formsy'
+import './FormFieldDate.scss'
const TCFormFields = FormsyForm.Fields
-import styles from './FormFieldDate.scss'
-const FormFieldDate = ({ startDate, endDate, theme }) => {
- const startDateProps = _.omit(startDate, 'label')
- startDateProps.type = 'date'
- startDateProps.wrapperClass = styles['field-wrapper']
-
- const endDateProps = _.omit(endDate, 'label')
- endDateProps.type = 'date'
- endDateProps.wrapperClass = styles['field-wrapper']
+const FormFieldDate = (props) => {
return (
-
+
-
+
-
-
-
+
)
diff --git a/src/projects/detail/components/timeline/Milestone/Milestone.jsx b/src/projects/detail/components/timeline/Milestone/Milestone.jsx
index 3d092febe..c9ea78c9a 100644
--- a/src/projects/detail/components/timeline/Milestone/Milestone.jsx
+++ b/src/projects/detail/components/timeline/Milestone/Milestone.jsx
@@ -102,10 +102,32 @@ class Milestone extends React.Component {
this.setState({ isMobileEditing: true })
}
+ isActualStartDateEditable() {
+ const { milestone, currentUser } = this.props
+ const isActive = milestone.status === MILESTONE_STATUS.ACTIVE
+ const isCompleted = milestone.status === MILESTONE_STATUS.COMPLETED
+ return (isActive || isCompleted) && currentUser.isAdmin
+
+ }
+
+ isCompletionDateEditable() {
+ const { milestone, currentUser } = this.props
+ const isCompleted = milestone.status === MILESTONE_STATUS.COMPLETED
+ return isCompleted && currentUser.isAdmin
+ }
+
updateMilestoneWithData(values) {
const { milestone, updateMilestone } = this.props
-
- updateMilestone(milestone.id, values)
+ const milestoneData = {
+ ...values
+ }
+ if (values.actualStartDate) {
+ milestoneData.actualStartDate = moment.utc(new Date(values.actualStartDate))
+ }
+ if (values.completionDate) {
+ milestoneData.completionDate = moment.utc(new Date(values.completionDate))
+ }
+ updateMilestone(milestone.id, milestoneData)
}
milestoneEditorChanged(values) {
@@ -211,6 +233,8 @@ class Milestone extends React.Component {
const date = startDate.format('D')
const title = milestone.name
const isUpdating = milestone.isUpdating
+ const isActualDateEditable = this.isActualStartDateEditable()
+ const isCompletionDateEditable = this.isCompletionDateEditable()
const editForm = (
diff --git a/src/routes/metadata/components/MetaDataPanel.scss b/src/routes/metadata/components/MetaDataPanel.scss
index 9bfd96569..cff4fd7db 100644
--- a/src/routes/metadata/components/MetaDataPanel.scss
+++ b/src/routes/metadata/components/MetaDataPanel.scss
@@ -37,7 +37,7 @@
.ProjectWizard {
padding: 10px;
-
+
.section-footer {
margin-top: 0px;// resets the negative margin which is used in actual rendering
}
@@ -242,4 +242,8 @@
}
}
}
+
+ .hide {
+ display: none;
+ }
}
diff --git a/src/routes/metadata/containers/FormDetails.jsx b/src/routes/metadata/containers/FormDetails.jsx
index fdec345e3..daa1f15e7 100644
--- a/src/routes/metadata/containers/FormDetails.jsx
+++ b/src/routes/metadata/containers/FormDetails.jsx
@@ -16,6 +16,7 @@ import {
getRevisionList,
} from '../../../actions/templates'
import spinnerWhileLoading from '../../../components/LoadingSpinner'
+import LoadingIndicator from '../../../components/LoadingIndicator/LoadingIndicator'
import CoderBot from '../../../components/CoderBot/CoderBot'
import { requiresAuthentication } from '../../../components/AuthenticatedComponent'
import MetaDataPanel from '../components/MetaDataPanel'
@@ -68,6 +69,7 @@ class FormDetails extends React.Component {
templates,
isAdmin,
match,
+ isLoading
} = this.props
const key = match.params.key
let form
@@ -76,20 +78,23 @@ class FormDetails extends React.Component {
}
return (
-
+ {isLoading && (
)}
+
+
+
)
}
@@ -138,7 +143,14 @@ const page500 = compose(
const showErrorMessageIfError = hasLoaded =>
branch(hasLoaded, renderComponent(page500(CoderBot)), t => t)
const errorHandler = showErrorMessageIfError(props => props.error)
-const enhance = spinnerWhileLoading(props => !props.isLoading && !props.isRemoving && !props.versionOptionsLoading)
+const enhance = spinnerWhileLoading(
+ props =>
+ (!props.isLoading ||
+ // avoid resetting state of child when saving
+ (props.templates && props.templates.versionMetadata)) &&
+ !props.isRemoving &&
+ !props.versionOptionsLoading
+)
const FormDetailsWithLoaderEnhanced = enhance(errorHandler(FormDetails))
const FormDetailsWithLoaderAndAuth = requiresAuthentication(FormDetailsWithLoaderEnhanced)
diff --git a/src/routes/metadata/containers/MetaDataContainer.scss b/src/routes/metadata/containers/MetaDataContainer.scss
index 65a84c07b..fcf6553c0 100644
--- a/src/routes/metadata/containers/MetaDataContainer.scss
+++ b/src/routes/metadata/containers/MetaDataContainer.scss
@@ -45,4 +45,8 @@
}
}
}
+
+ .hide {
+ display: none;
+ }
}
diff --git a/src/routes/metadata/containers/MilestoneTemplateDetails.jsx b/src/routes/metadata/containers/MilestoneTemplateDetails.jsx
index 8840b5bf9..96d9d6f18 100644
--- a/src/routes/metadata/containers/MilestoneTemplateDetails.jsx
+++ b/src/routes/metadata/containers/MilestoneTemplateDetails.jsx
@@ -13,6 +13,7 @@ import {
updateProjectsMetadata,
} from '../../../actions/templates'
import spinnerWhileLoading from '../../../components/LoadingSpinner'
+import LoadingIndicator from '../../../components/LoadingIndicator/LoadingIndicator'
import CoderBot from '../../../components/CoderBot/CoderBot'
import { requiresAuthentication } from '../../../components/AuthenticatedComponent'
import MetaDataPanel from '../components/MetaDataPanel'
@@ -43,7 +44,7 @@ class MilestoneTemplateDetails extends React.Component {
createMilestoneTemplate,
updateProjectsMetadata,
templates,
- // isLoading,
+ isLoading,
isAdmin,
match,
} = this.props
@@ -52,17 +53,20 @@ class MilestoneTemplateDetails extends React.Component {
const milestoneTemplate = _.find(milestoneTemplates, t => String(t.id) === id)
return (
-
+ {isLoading && (
)}
+
+
+
)
}
@@ -104,7 +108,13 @@ const page500 = compose(
const showErrorMessageIfError = hasLoaded =>
branch(hasLoaded, renderComponent(page500(CoderBot)), t => t)
const errorHandler = showErrorMessageIfError(props => props.error)
-const enhance = spinnerWhileLoading(props => !props.isLoading && !props.isRemoving)
+const enhance = spinnerWhileLoading(
+ props =>
+ (!props.isLoading ||
+ // avoid resetting state of child when saving
+ (props.templates && props.templates.milestoneTemplates)) &&
+ !props.isRemoving
+)
const MilestoneTemplateDetailsWithLoaderEnhanced = enhance(errorHandler(MilestoneTemplateDetails))
const MilestoneTemplateDetailsWithLoaderAndAuth = requiresAuthentication(MilestoneTemplateDetailsWithLoaderEnhanced)
diff --git a/src/routes/metadata/containers/PlanConfigDetails.jsx b/src/routes/metadata/containers/PlanConfigDetails.jsx
index 1c84a796d..3f2bd781b 100644
--- a/src/routes/metadata/containers/PlanConfigDetails.jsx
+++ b/src/routes/metadata/containers/PlanConfigDetails.jsx
@@ -16,6 +16,7 @@ import {
getRevisionList,
} from '../../../actions/templates'
import spinnerWhileLoading from '../../../components/LoadingSpinner'
+import LoadingIndicator from '../../../components/LoadingIndicator/LoadingIndicator'
import CoderBot from '../../../components/CoderBot/CoderBot'
import { requiresAuthentication } from '../../../components/AuthenticatedComponent'
import MetaDataPanel from '../components/MetaDataPanel'
@@ -68,6 +69,7 @@ class PlanConfigDetails extends React.Component {
templates,
isAdmin,
match,
+ isLoading
} = this.props
const key = match.params.key
let planConfig
@@ -76,20 +78,23 @@ class PlanConfigDetails extends React.Component {
}
return (
-
+ {isLoading && (
)}
+
+
+
)
}
@@ -138,7 +143,14 @@ const page500 = compose(
const showErrorMessageIfError = hasLoaded =>
branch(hasLoaded, renderComponent(page500(CoderBot)), t => t)
const errorHandler = showErrorMessageIfError(props => props.error)
-const enhance = spinnerWhileLoading(props => !props.isLoading && !props.isRemoving && !props.versionOptionsLoading)
+const enhance = spinnerWhileLoading(
+ props =>
+ (!props.isLoading ||
+ // avoid resetting state of child when saving
+ (props.templates && props.templates.versionMetadata)) &&
+ !props.isRemoving &&
+ !props.versionOptionsLoading
+)
const PlanConfigDetailsWithLoaderEnhanced = enhance(errorHandler(PlanConfigDetails))
const PlanConfigDetailsWithLoaderAndAuth = requiresAuthentication(PlanConfigDetailsWithLoaderEnhanced)
diff --git a/src/routes/metadata/containers/PriceConfigDetails.jsx b/src/routes/metadata/containers/PriceConfigDetails.jsx
index 9a098e979..b6954f965 100644
--- a/src/routes/metadata/containers/PriceConfigDetails.jsx
+++ b/src/routes/metadata/containers/PriceConfigDetails.jsx
@@ -16,6 +16,7 @@ import {
getRevisionList,
} from '../../../actions/templates'
import spinnerWhileLoading from '../../../components/LoadingSpinner'
+import LoadingIndicator from '../../../components/LoadingIndicator/LoadingIndicator'
import CoderBot from '../../../components/CoderBot/CoderBot'
import { requiresAuthentication } from '../../../components/AuthenticatedComponent'
import MetaDataPanel from '../components/MetaDataPanel'
@@ -68,6 +69,7 @@ class PriceConfigDetails extends React.Component {
templates,
isAdmin,
match,
+ isLoading
} = this.props
const key = match.params.key
let priceConfig
@@ -76,20 +78,23 @@ class PriceConfigDetails extends React.Component {
}
return (
-
+ {isLoading && (
)}
+
+
+
)
}
@@ -138,7 +143,14 @@ const page500 = compose(
const showErrorMessageIfError = hasLoaded =>
branch(hasLoaded, renderComponent(page500(CoderBot)), t => t)
const errorHandler = showErrorMessageIfError(props => props.error)
-const enhance = spinnerWhileLoading(props => !props.isLoading && !props.isRemoving && !props.versionOptionsLoading)
+const enhance = spinnerWhileLoading(
+ props =>
+ (!props.isLoading ||
+ // avoid resetting state of child when saving
+ (props.templates && props.templates.versionMetadata)) &&
+ !props.isRemoving &&
+ !props.versionOptionsLoading
+)
const PriceConfigDetailsWithLoaderEnhanced = enhance(errorHandler(PriceConfigDetails))
const PriceConfigDetailsWithLoaderAndAuth = requiresAuthentication(PriceConfigDetailsWithLoaderEnhanced)
diff --git a/src/routes/metadata/containers/ProductCategoryDetails.jsx b/src/routes/metadata/containers/ProductCategoryDetails.jsx
index f94a177a5..7fd6d4285 100644
--- a/src/routes/metadata/containers/ProductCategoryDetails.jsx
+++ b/src/routes/metadata/containers/ProductCategoryDetails.jsx
@@ -13,6 +13,7 @@ import {
updateProjectsMetadata,
} from '../../../actions/templates'
import spinnerWhileLoading from '../../../components/LoadingSpinner'
+import LoadingIndicator from '../../../components/LoadingIndicator/LoadingIndicator'
import CoderBot from '../../../components/CoderBot/CoderBot'
import { requiresAuthentication } from '../../../components/AuthenticatedComponent'
import MetaDataPanel from '../components/MetaDataPanel'
@@ -43,7 +44,7 @@ class ProductCategoryDetails extends React.Component {
createProductCategory,
updateProjectsMetadata,
templates,
- // isLoading,
+ isLoading,
isAdmin,
match,
} = this.props
@@ -52,17 +53,20 @@ class ProductCategoryDetails extends React.Component {
const productCategory = _.find(productCategories, t => t.key === key)
return (
-
+ {isLoading && (
)}
+
+
+
)
}
@@ -104,7 +108,13 @@ const page500 = compose(
const showErrorMessageIfError = hasLoaded =>
branch(hasLoaded, renderComponent(page500(CoderBot)), t => t)
const errorHandler = showErrorMessageIfError(props => props.error)
-const enhance = spinnerWhileLoading(props => !props.isLoading && !props.isRemoving)
+const enhance = spinnerWhileLoading(
+ props =>
+ (!props.isLoading ||
+ // avoid resetting state of child when saving
+ (props.templates && props.templates.productCategories)) &&
+ !props.isRemoving
+)
const ProductCategoryDetailsWithLoaderEnhanced = enhance(errorHandler(ProductCategoryDetails))
const ProductCategoryDetailsWithLoaderAndAuth = requiresAuthentication(ProductCategoryDetailsWithLoaderEnhanced)
diff --git a/src/routes/metadata/containers/ProductTemplateDetails.jsx b/src/routes/metadata/containers/ProductTemplateDetails.jsx
index 8bb8cbf91..fe72b0cf4 100644
--- a/src/routes/metadata/containers/ProductTemplateDetails.jsx
+++ b/src/routes/metadata/containers/ProductTemplateDetails.jsx
@@ -13,6 +13,7 @@ import {
createProductTemplate,
} from '../../../actions/templates'
import spinnerWhileLoading from '../../../components/LoadingSpinner'
+import LoadingIndicator from '../../../components/LoadingIndicator/LoadingIndicator'
import CoderBot from '../../../components/CoderBot/CoderBot'
import { requiresAuthentication } from '../../../components/AuthenticatedComponent'
import MetaDataPanel from '../components/MetaDataPanel'
@@ -43,7 +44,7 @@ class ProductTemplateDetails extends React.Component {
createProductTemplate,
updateProjectsMetadata,
templates,
- // isLoading,
+ isLoading,
isAdmin,
match,
} = this.props
@@ -53,17 +54,20 @@ class ProductTemplateDetails extends React.Component {
const productTemplate = _.find(productTemplates, t => t.id === templateId)
return (
-
+ {isLoading && (
)}
+
+
+
)
}
@@ -106,7 +110,13 @@ const page500 = compose(
const showErrorMessageIfError = hasLoaded =>
branch(hasLoaded, renderComponent(page500(CoderBot)), t => t)
const errorHandler = showErrorMessageIfError(props => props.errorTemp)
-const enhance = spinnerWhileLoading(props => !props.isLoading && !props.isRemoving)
+const enhance = spinnerWhileLoading(
+ props =>
+ (!props.isLoading ||
+ // avoid resetting state of child when saving
+ (props.templates && props.templates.productTemplates)) &&
+ !props.isRemoving
+)
const ProductTemplateDetailsWithLoaderEnhanced = enhance(errorHandler(ProductTemplateDetails))
const ProductTemplateDetailsWithLoaderAndAuth = requiresAuthentication(ProductTemplateDetailsWithLoaderEnhanced)
diff --git a/src/routes/metadata/containers/ProjectTemplateDetails.jsx b/src/routes/metadata/containers/ProjectTemplateDetails.jsx
index 536f2a2a3..cacc4820c 100644
--- a/src/routes/metadata/containers/ProjectTemplateDetails.jsx
+++ b/src/routes/metadata/containers/ProjectTemplateDetails.jsx
@@ -14,6 +14,7 @@ import {
} from '../../../actions/templates'
import { fireProjectDirty } from '../../../projects/actions/project'
import spinnerWhileLoading from '../../../components/LoadingSpinner'
+import LoadingIndicator from '../../../components/LoadingIndicator/LoadingIndicator'
import CoderBot from '../../../components/CoderBot/CoderBot'
import { requiresAuthentication } from '../../../components/AuthenticatedComponent'
import MetaDataPanel from '../components/MetaDataPanel'
@@ -44,7 +45,7 @@ class ProjectTemplateDetails extends React.Component {
createProjectTemplate,
updateProjectsMetadata,
templates,
- // isLoading,
+ isLoading,
isAdmin,
match,
previewProject,
@@ -56,19 +57,22 @@ class ProjectTemplateDetails extends React.Component {
const projectTemplate = _.find(projectTemplates, t => t.id === templateId)
return (
-
+ {isLoading && (
)}
+
+
+
)
}
@@ -115,7 +119,13 @@ const page500 = compose(
const showErrorMessageIfError = hasLoaded =>
branch(hasLoaded, renderComponent(page500(CoderBot)), t => t)
const errorHandler = showErrorMessageIfError(props => props.errorTemp)
-const enhance = spinnerWhileLoading(props => !props.isLoading && !props.isRemoving)
+const enhance = spinnerWhileLoading(
+ props =>
+ (!props.isLoading ||
+ // avoid resetting state of child when saving
+ (props.templates && props.templates.projectTemplates)) &&
+ !props.isRemoving
+)
const ProjectTemplateDetailsWithLoaderEnhanced = enhance(errorHandler(ProjectTemplateDetails))
const ProjectTemplateDetailsWithLoaderAndAuth = requiresAuthentication(ProjectTemplateDetailsWithLoaderEnhanced)
diff --git a/src/routes/metadata/containers/ProjectTypeDetails.jsx b/src/routes/metadata/containers/ProjectTypeDetails.jsx
index c261146e1..3a5c7bf1f 100644
--- a/src/routes/metadata/containers/ProjectTypeDetails.jsx
+++ b/src/routes/metadata/containers/ProjectTypeDetails.jsx
@@ -13,6 +13,7 @@ import {
updateProjectsMetadata,
} from '../../../actions/templates'
import spinnerWhileLoading from '../../../components/LoadingSpinner'
+import LoadingIndicator from '../../../components/LoadingIndicator/LoadingIndicator'
import CoderBot from '../../../components/CoderBot/CoderBot'
import { requiresAuthentication } from '../../../components/AuthenticatedComponent'
import MetaDataPanel from '../components/MetaDataPanel'
@@ -43,7 +44,7 @@ class ProjectTypeDetails extends React.Component {
createProjectType,
updateProjectsMetadata,
templates,
- // isLoading,
+ isLoading,
isAdmin,
match,
} = this.props
@@ -52,17 +53,20 @@ class ProjectTypeDetails extends React.Component {
const projectType = _.find(projectTypes, t => t.key === key)
return (
-
+ {isLoading && (
)}
+
+
+
)
}
@@ -104,7 +108,13 @@ const page500 = compose(
const showErrorMessageIfError = hasLoaded =>
branch(hasLoaded, renderComponent(page500(CoderBot)), t => t)
const errorHandler = showErrorMessageIfError(props => props.error)
-const enhance = spinnerWhileLoading(props => !props.isLoading && !props.isRemoving)
+const enhance = spinnerWhileLoading(
+ props =>
+ (!props.isLoading ||
+ // avoid resetting state of child when saving
+ (props.templates && props.templates.projectTypes)) &&
+ !props.isRemoving
+)
const ProjectTypeDetailsWithLoaderEnhanced = enhance(errorHandler(ProjectTypeDetails))
const ProjectTypeDetailsWithLoaderAndAuth = requiresAuthentication(ProjectTypeDetailsWithLoaderEnhanced)
diff --git a/src/routes/notifications/helpers/notifications.js b/src/routes/notifications/helpers/notifications.js
index 16540ec58..36fcbe193 100644
--- a/src/routes/notifications/helpers/notifications.js
+++ b/src/routes/notifications/helpers/notifications.js
@@ -262,6 +262,20 @@ export const filterTopicAndPostChangedNotifications = (notifications, tagRegExp)
return topicAndPostNotifications
}
+/**
+ * Filter notifications about Link and File changed
+ *
+ * @param {Array} notifications list of notifications
+ *
+ * @return {Array} notifications list filtered of notifications
+ */
+export const filterFileAndLinkChangedNotifications = (notifications) => {
+ return _.filter(notifications, (notification) => (
+ notification.eventType === EVENT_TYPE.PROJECT.FILE_UPLOADED ||
+ notification.eventType === EVENT_TYPE.PROJECT.LINK_CREATED
+ ))
+}
+
/**
* Filter notification about post mentions
* @param {Array} notifications list of notifications