Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
0793ad3
Github issue#2970, Scope Change Workflow
Jul 9, 2019
8a890b4
Disable "Save Changes" button again if there is no changes.
gets0ul Jul 14, 2019
391d26c
Added reset values in case of deselected option
gets0ul Jul 14, 2019
84b914c
Using general fix without hardcoded fields.
gets0ul Jul 15, 2019
312e8c2
Hotfix/post release 2.4.13.2 (#3192)
Jul 18, 2019
8b32698
Implement scope change request workflow
vignesh-at-alation Jul 18, 2019
166702a
Merge pull request #3200 from appirio-tech/hotfix/post-release-2.4.13.4
Jul 20, 2019
05d2506
Merge pull request #3201 from appirio-tech/hotfix/post-release-2.4.13.5
Jul 20, 2019
5dff685
Merge pull request #3175 from gets0ul/issue-3149
maxceem Jul 22, 2019
bb52f4c
Github issue#3202, Progress bar is showing wrong progress for Final f…
Jul 22, 2019
b70343e
Merge pull request #3205 from appirio-tech/hotfix/redirect-comments
Jul 22, 2019
6fdf17e
Merge pull request #3203 from appirio-tech/feature/issue-3202
Jul 23, 2019
2095e60
Scope change review fixes
vignesh-at-alation Jul 23, 2019
8b5dfc3
fix logic for cleaning empty keys while creating new scope change req…
vignesh-at-alation Jul 23, 2019
9a32f31
fix review issues in Scope change workflow
vignesh-at-alation Jul 23, 2019
80f43e6
Merge pull request #3193 from vigneshTheDev/feature/scope_change_work…
Jul 24, 2019
5dab3c5
Merge pull request #3218 from appirio-tech/hotfix/post-release-2.4.13.7
Jul 25, 2019
491f050
Github issue#3221, [Sentry] this.props.onToggle is not a function
Jul 26, 2019
52c769f
Github issue#3220, Error in console `this.isChanged is not a function`
Jul 26, 2019
3a4844e
support projects with workstreamsConfigs
maxceem Jul 28, 2019
e9c4724
Changes for Project Reporting - Part1
mishacucicea Jul 28, 2019
b4cd561
Merge branch 'dev' into feature/scope_change_workflow
Jul 29, 2019
514d932
Merge pull request #3226 from appirio-tech/feature/scope_change_workflow
Jul 29, 2019
a3b76c4
Fixed wrong conflict resolution.
Jul 29, 2019
de1ac08
changing kafka topic name
Jul 30, 2019
dc90576
Fix #3228 - show value labels instead of values in scope change request.
vignesh-at-alation Aug 1, 2019
4a78959
Fix #3229 - after scope form reset, reset summary labels
vignesh-at-alation Aug 1, 2019
d41e005
Fix #3230 - merge array fields properly after activating scope change…
vignesh-at-alation Aug 1, 2019
b746e86
update logic for deducing value label in scope change request
vignesh-at-alation Aug 2, 2019
5ff1e1a
Merge pull request #3242 from vigneshTheDev/dev
Aug 2, 2019
7f55078
Initial Reports API integration.
mishacucicea Aug 5, 2019
c9f8f71
hide values and adjust the UI
mishacucicea Aug 5, 2019
50d085f
Temporary deployable feature branch to test reports
Aug 6, 2019
bd2a5f4
Merge pull request #3241 from appirio-tech/feature/kafka-topic-name-c…
Aug 6, 2019
fc2c381
Removing feature branch from deployable list as going to merge it int…
Aug 6, 2019
7b5f050
Merge pull request #3247 from appirio-tech/feature/reports
Aug 6, 2019
4b209f5
Fixing the difference between sample JSON and actual JSON.
Aug 6, 2019
e56705f
Minor style fix
Aug 6, 2019
7de9b56
Hide 'Reports' menu item.
mishacucicea Aug 6, 2019
ed521ab
Enabled support for email-change vai connect for customers.
RishiRajSahu Aug 7, 2019
243c961
Merge pull request #3248 from appirio-tech/feature/enable_email_chang…
RishiRajSahu Aug 7, 2019
49fb2d9
Merge pull request #3256 from appirio-tech/hotfix/added_support_for_h…
RishiRajSahu Aug 9, 2019
a6e0fb0
fix #3251
vignesh-at-alation Aug 10, 2019
99d5ce5
map fields to new report
mishacucicea Aug 11, 2019
7c9f6f6
Merge pull request #3257 from vigneshTheDev/feature/scope_change_acti…
Aug 12, 2019
5a1b82e
Merge pull request #3250 from appirio-tech/feature/reports
Aug 12, 2019
e6749ff
Showing 0 value as well
Aug 12, 2019
fe7254e
Some refactoring
Aug 12, 2019
3f90f3e
Lint fix
Aug 12, 2019
71a435e
Refactoring Post component
phoenix303 Aug 12, 2019
108b56d
Merge pull request #3259 from phoenix303/refactor-post-component
maxceem Aug 13, 2019
5aaa324
remove PostContainer demo
maxceem Aug 13, 2019
cf39dc6
Merge branch 'dev' into feature/posts-component
maxceem Aug 13, 2019
0c1e764
refactored ProjectStage to not be connected to the Redux store
maxceem Aug 13, 2019
c91d074
Merge pull request #3260 from appirio-tech/feature/posts-component
Aug 13, 2019
a0537b8
Fixed logic for determining the valid data for the reports
Aug 13, 2019
2535586
Fixed parsing of connect project id to be type independent
Aug 13, 2019
cdebe8f
Fixed margin as per designs 30px => 20px
Aug 13, 2019
6f7dd6c
Removed console log
Aug 13, 2019
1bef8f7
adding temporary condition to avoid old notitications missing after d…
Aug 14, 2019
9a06308
More fine grained permissions checks
Aug 14, 2019
cce5a6e
Lint fix
Aug 14, 2019
8ce017b
Better naming for the prop of the ProjectEstimation component
Aug 14, 2019
2b7d906
Removed projectestimation component for now. We need to build and inc…
Aug 14, 2019
cdad37f
Merge pull request #3265 from appirio-tech/feature/kafka-topic-name-c…
Aug 14, 2019
23f7986
Fixed error alert message for project update failure
Aug 16, 2019
b7d481a
Lint fix
Aug 16, 2019
a541787
Added default error string even if server does not sends one.
Aug 16, 2019
61b7268
Revert "adding temporary condition to avoid old notifications missing"
Aug 17, 2019
42da01a
Merge pull request #3269 from appirio-tech/revert-3265-feature/kafka-…
Aug 19, 2019
bca9a6a
fix #3263
vignesh-at-alation Aug 20, 2019
4648784
fix: showing attachments in reusable PostsContainer component
maxceem Aug 21, 2019
4ae4f00
fix: show correct number of unread posts on project listing page
maxceem Aug 21, 2019
6fbdc3c
refactor: put logic into class methods
maxceem Aug 26, 2019
6074d2a
https://tcprod.productboard.com/roadmap/282713-customer-portal-presen…
Aug 27, 2019
07834bd
Removed unused old project estimation component and its usage
Aug 27, 2019
259fa78
https://tcprod.productboard.com/roadmap/282713-customer-portal-presen…
Aug 27, 2019
848626f
Lint fixes
Aug 27, 2019
b50598c
Merge pull request #3272 from vigneshTheDev/fix-3263
RishiRajSahu Aug 27, 2019
c549480
Merge branch 'dev' of github.com:appirio-tech/connect-app into dev
maxceem Aug 27, 2019
0a390c7
feat: use query params in evaluating wizard form conditions
maxceem Aug 27, 2019
8e0870a
Disabled the scope change work flow for the immediate release of quer…
Aug 28, 2019
e5be063
fix alerts in profile settings
vignesh-at-alation Aug 28, 2019
0070ea1
Merge pull request #3284 from vigneshTheDev/profile-settings-alert-fix
RishiRajSahu Aug 29, 2019
7a76b29
Revert "feat: use query params in evaluating wizard form conditions"
maxceem Aug 29, 2019
442830d
hide country selection alert on outside click in
vignesh-at-alation Aug 29, 2019
78bc430
feat: "queryParamSelectCondition" to per-select form options based on…
maxceem Aug 29, 2019
5d1f68c
Merge pull request #3286 from vigneshTheDev/profile-settings-alert-fix
RishiRajSahu Aug 29, 2019
cbc060e
fix phone number alert in profile settings
vignesh-at-alation Aug 29, 2019
261a723
Merge pull request #3287 from vigneshTheDev/profile-settings-alert-fix
RishiRajSahu Aug 29, 2019
312da78
feat: log project template info during project creating
maxceem Aug 29, 2019
9386e19
feat: query params during project creation forms are treated as diffe…
maxceem Aug 29, 2019
7c0f44f
fix: comments
maxceem Aug 29, 2019
687be57
Updated package lock for react components
Aug 30, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13,640 changes: 6,298 additions & 7,342 deletions package-lock.json

Large diffs are not rendered by default.

208 changes: 208 additions & 0 deletions src/actions/topics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/**
* Topic actions
*/
import _ from 'lodash'
import {
getTopicsWithComments,
addTopicPost as addTopicPostAPI,
saveTopicPost as saveTopicPostAPI,
deleteTopicPost as deleteTopicPostAPI,
} from '../api/messages'
import {
LOAD_TOPIC_MEMBERS,
LOAD_TOPIC,
CREATE_TOPIC_POST,
DELETE_TOPIC_POST,
UPDATE_TOPIC_POST,
DISCOURSE_BOT_USERID,
CODER_BOT_USERID,
TC_SYSTEM_USERID,
} from '../config/constants'
import { loadMembers } from './members'
import { EventTypes } from 'redux-segment'

/**
* Load topics for given tags
* @param {integer} projectId project identifier
* @param {Array} tags list of tags
* @param {Function} dispatch dispatch function
* @return {Array} topics
*/
export function loadTopics(projectId, tags, dispatch) {
return Promise.all(
tags.map((tag) => getTopicWithoutMembers(dispatch, projectId, tag))
).then((responses) => {
return _.map(responses, (resp) => ({
topics: _.get(resp, 'value') ? [_.get(resp, 'value')] : [],
tag: _.get(resp, 'action.meta.tag'),
}))
})
}

/**
* Load topic for a given tag
* @param {integer} projectId project identifier
* @param {String} tag tag
* @return {Object} action
*/
export function loadTopic(projectId, tag) {
return (dispatch) => {
return dispatch({
type: LOAD_TOPIC_MEMBERS,
payload: getTopicWithMember(dispatch, projectId, tag),
meta: { tag }
})
}
}

/**
* Get topics without members
* @param {Function} dispatch dispatch function
* @param {integer} projectId project identifier
* @param {String} tag tag
* @return {Object} topic
*/
function getTopicWithoutMembers(dispatch, projectId, tag) {
return dispatch({
type: LOAD_TOPIC_MEMBERS,
payload: new Promise((resolve, reject) => {
return getTopicsWithComments('project', `${projectId}`, tag, false)
.then((resp) => resolve(_.get(resp, 'topics[0]')))
.catch(err => reject(err))
}),
meta: { tag }
})
}

/**
* Get topics with members
* @param {Function} dispatch dispatch function
* @param {integer} projectId project identifier
* @param {String} tag tag
* @return {Promise}
*/
function getTopicWithMember(dispatch, projectId, tag) {
return new Promise((resolve, reject) => {
return dispatch({
type: LOAD_TOPIC,
payload: getTopicsWithComments('project', `${projectId}`, tag, false),
meta: { tag }
})
.then(({ value }) => {
let userIds = []
userIds = _.union(userIds, _.map(value.topics, 'userId'))
_.forEach(value.topics, topic => {
userIds = _.union(userIds, _.map(topic.posts, 'userId'))
})
// this is to remove any nulls from the list (dev had some bad data)
_.remove(userIds, i => !i || [DISCOURSE_BOT_USERID, CODER_BOT_USERID, TC_SYSTEM_USERID].indexOf(i) > -1)
// return if there are no userIds to retrieve, empty result set
if (!userIds.length)
resolve(value.topics[0])
return dispatch(loadMembers(userIds))
.then(() => resolve(value.topics[0]))
.catch(err => reject(err))
})
.catch(err => reject(err))
})
}

/**
* Add post to the topic
* @param {String} tag tag
* @param {integer} topicId topic identifier
* @param {Object} post post
* @return {Object} action
*/
export function addTopicPost(tag, topicId, post) {
return (dispatch, getState) => {
const projectStatus = getState().projectState.project.status
return dispatch({
type: CREATE_TOPIC_POST,
payload: addTopicPostAPI(topicId, post),
meta: {
feedId: topicId,
tag,
rawContent: post.content,
onSuccessAnalytics: {
eventType: EventTypes.track,
eventPayload: {
event: 'Post Created',
properties: {
topicCategory: tag,
topicId,
projectStatus
}
}
}
}
})
}
}

/**
* Delete post
* @param {String} tag tag
* @param {integer} topicId topic identifier
* @param {integer} postId post identifier
* @return {Object} action
*/
export function deleteTopicPost(tag, topicId, postId) {
return (dispatch, getState) => {
const projectStatus = getState().projectState.project.status
return dispatch({
type: DELETE_TOPIC_POST,
payload: deleteTopicPostAPI(topicId, postId),
meta: {
feedId: topicId,
tag,
commentId: postId,
onSuccessAnalytics: {
eventType: EventTypes.track,
eventPayload: {
event: 'Post Deleted',
properties: {
topicCategory: tag,
topicId,
projectStatus
}
}
}
}
})
}
}

/**
* Update post
* @param {String} tag tag
* @param {integer} topicId topic identifier
* @param {Object} post post
* @return {Object} action
*/
export function updateTopicPost(tag, topicId, post) {
return (dispatch, getState) => {
const projectStatus = getState().projectState.project.status
return dispatch({
type: UPDATE_TOPIC_POST,
payload: saveTopicPostAPI(topicId, post),
meta: {
feedId: topicId,
tag,
commentId: post.id,
rawContent: post.content,
onSuccessAnalytics: {
eventType: EventTypes.track,
eventPayload: {
event: 'Post Saved',
properties: {
topicCategory: tag,
topicId,
projectStatus
}
}
}
}
})
}
}
44 changes: 44 additions & 0 deletions src/api/projectReports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import _ from 'lodash'
import { axiosInstance as axios } from './requestInterceptor'
import { PROJECTS_API_URL } from '../config/constants'

/**
* Get a project summary
*
* @param {integer} projectId unique identifier of the project
*/
export function getProjectSummary(projectId) {

const summaryPromise = axios.get(`${PROJECTS_API_URL}/v4/projects/${projectId}/reports?reportName=summary`)
const budgetPromise = axios.get(`${PROJECTS_API_URL}/v4/projects/${projectId}/reports?reportName=projectBudget`)

return Promise.all([summaryPromise, budgetPromise]).then(responses => {
const res = _.get(responses[0].data, 'result.content', {})
const designMetrics = _.find(res, c => c['challenge.track'] === 'Design') || {}
const totalRegistrants = _.sumBy(res, c => c['challenge.num_registrations'])

const res1 = _.get(responses[1].data, 'result.content', {})
const filterReport = c => `${c['project_stream.tc_connect_project_id']}` === projectId.toString()
const projectBudget = _.find(res1, filterReport) || {}

return {
projectId,
budget: {
work: parseFloat(projectBudget['project_stream.total_actual_member_payment'] || 0),
fees: parseFloat(projectBudget['project_stream.total_actual_challenge_fee'] || 0),
revenue: parseFloat(projectBudget['project_stream.total_invoiced_amount'] || 0),
remaining: parseFloat(projectBudget['project_stream.remaining_invoiced_budget'] || 0)
},
// null values will be filled in as back-end implementation/integration is done.
topcoderDifference: {
countries: null,
registrants: totalRegistrants,
designs: designMetrics['challenge.num_submissions'],
linesOfCode: null,
hoursSaved: null,
costSavings: null,
valueCreated: null,
}
}
})
}
25 changes: 25 additions & 0 deletions src/api/projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,31 @@ export function updateProject(projectId, updatedProps, updateExisting) {
})
}

/**
* Create scope change request for the given project with the given details
* @param {integer} projectId project Id
* @param {object} request scope change request object
* @return {promise} created scope change request
*/
export function createScopeChangeRequest(projectId, request) {
return axios.post(`${PROJECTS_API_URL}/v4/projects/${projectId}/scopeChangeRequests`, { param: request })
.then(resp => {
return _.get(resp.data, 'result.content')
})
}/**
* Create scope change request for the given project with the given details
* @param {integer} projectId project Id
* @param {integer} requestId scope change request Id
* @param {object} updatedProps updated request properties
* @return {promise} updated request
*/
export function updateScopeChangeRequest(projectId, requestId, updatedProps) {
return axios.patch(`${PROJECTS_API_URL}/v4/projects/${projectId}/scopeChangeRequests/${requestId}`, { param: updatedProps })
.then(resp => {
return _.get(resp.data, 'result.content')
})
}

/**
* Update phase using patch
* @param {integer} projectId project Id
Expand Down
2 changes: 1 addition & 1 deletion src/api/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export const getPreSignedUrl = (handle, file) => {
* @returns {Promise<Object>} response body
*/
export const checkEmailValidity = (email) => {
return axios.get(`${TC_API_URL}/v3/users/validateEmail?email=${email}`)
return axios.get(`${TC_API_URL}/v3/users/validateEmail?email=${encodeURIComponent(email)}`)
.then(resp => _.get(resp.data, 'result.content', {}))
}

Expand Down
6 changes: 4 additions & 2 deletions src/components/ActionCard/Comment.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import cn from 'classnames'
import Handlebars from 'handlebars'
import UserTooltip from '../User/UserTooltip'
import RichTextArea from '../RichTextArea/RichTextArea'
import { Link, withRouter } from 'react-router-dom'
Expand Down Expand Up @@ -76,7 +77,8 @@ class Comment extends React.Component {

render() {
const {message, author, date, edited, children, noInfo, self, isSaving, hasError, readonly, allMembers, canDelete, projectMembers, commentAnchorPrefix} = this.props
const messageAnchor = commentAnchorPrefix + message.id
const template = Handlebars.compile(commentAnchorPrefix)
const messageAnchor = template({ postId: message.id })
const messageLink = window.location.pathname.substr(0, window.location.pathname.indexOf('#')) + `#${messageAnchor}`
const authorName = author ? (author.firstName + ' ' + author.lastName) : 'Connect user'
const avatarUrl = _.get(author, 'photoURL', null)
Expand Down Expand Up @@ -174,7 +176,7 @@ class Comment extends React.Component {
}

Comment.defaultProps = {
commentAnchorPrefix: 'comment-',
commentAnchorPrefix: 'comment-{{postId}}',
}

Comment.propTypes = {
Expand Down
4 changes: 2 additions & 2 deletions src/components/MenuItem/MenuItem.scss
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@

.active .icon.stroke g,
.active .icon.stroke path {
stroke: $tc-dark-blue-100;
stroke: #0AB88A;
}

.active .icon.fill circle,
.active .icon.fill path {
fill: $tc-dark-blue-100;
fill: #0AB88A;
}

.active {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@ class NotificationsDropdown extends React.Component {

toggle(isOpen) {
if (typeof isOpen === 'object') {
this.props.onToggle(!this.state.isOpen)
if (this.props.onToggle) {
this.props.onToggle(!this.state.isOpen)
}
this.setState({ isOpen: !this.state.isOpen})
} else {
this.props.onToggle(isOpen)
if (this.props.onToggle) {
this.props.onToggle(isOpen)
}
this.setState({ isOpen })
}
}
Expand Down
Loading