Skip to content

Commit ff109a6

Browse files
author
Parth Shah
committed
Merge branch 'feature/bug-fixes' into dev
2 parents f72fae7 + db612f2 commit ff109a6

File tree

17 files changed

+407
-271
lines changed

17 files changed

+407
-271
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"formsy-react": "^0.18.1",
4343
"history": "^1.17.0",
4444
"isomorphic-fetch": "^2.2.1",
45+
"lodash": "^4.16.4",
4546
"moment": "^2.14.1",
4647
"react": "^15.3.1",
4748
"react-addons-css-transition-group": "^15.3.1",

src/api/messages.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ export function getTopicPosts(topicId, postIds) {
2828
.then( resp => {
2929
return {
3030
totalCount: _.get(resp.data, 'result.metadata.totalCount', 0),
31-
posts: _.get(resp.data, 'result.content', [])
31+
posts: _.get(resp.data, 'result.content', []),
32+
topicId
3233
}
3334
})
3435
}

src/components/Feed/FeedComments.jsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Panel from '../Panel/Panel'
44
import AddComment from '../ActionCard/AddComment'
55
import Comment from '../ActionCard/Comment'
66
import cn from 'classnames'
7-
import { THREAD_MESSAGES_PAGE_SIZE } from '../../config/constants'
7+
// import { THREAD_MESSAGES_PAGE_SIZE } from '../../config/constants'
88

99
const getCommentCount = (totalComments) => {
1010
if (!totalComments) {
@@ -24,7 +24,7 @@ class FeedComments extends React.Component {
2424

2525
render() {
2626
const {
27-
comments, currentUser, totalComments, /*onLoadMoreComments,*/ isLoadingComments, hasMoreComments, onAdd,
27+
comments, currentUser, totalComments, onLoadMoreComments, isLoadingComments, hasMoreComments, onAdd,
2828
onChange, content, avatarUrl, isAddingComment
2929
} = this.props
3030
let authorName = currentUser.firstName
@@ -35,17 +35,17 @@ class FeedComments extends React.Component {
3535
this.setState({showAll: true})
3636
// TODO - handle the case when a topic has more than 20 comments
3737
// since those will have to retrieved from the server
38-
// if (!isLoadingComments) {
39-
// onLoadMoreComments()
40-
// }
38+
if (!isLoadingComments) {
39+
onLoadMoreComments()
40+
}
4141
}
4242

43-
let _comments = comments
44-
let _hasMoreComments = hasMoreComments
45-
if (!this.state.showAll && _comments.length > THREAD_MESSAGES_PAGE_SIZE) {
46-
_comments = _comments.slice(-THREAD_MESSAGES_PAGE_SIZE)
47-
_hasMoreComments = true
48-
}
43+
// let _comments = comments
44+
// let _hasMoreComments = hasMoreComments
45+
// if (!this.state.showAll && _comments.length > THREAD_MESSAGES_PAGE_SIZE) {
46+
// _comments = _comments.slice(-THREAD_MESSAGES_PAGE_SIZE)
47+
// _hasMoreComments = true
48+
// }
4949

5050
return (
5151
<div>
@@ -57,15 +57,15 @@ class FeedComments extends React.Component {
5757
{getCommentCount(totalComments)}
5858
</div>
5959
<hr className={cn({'no-margin': !comments.length})} />
60-
{_hasMoreComments && <div className={cn('comment-collapse', {'loading-comments': isLoadingComments})}>
60+
{hasMoreComments && <div className={cn('comment-collapse', {'loading-comments': isLoadingComments})}>
6161
<a href="javascript:" onClick={ handleLoadMoreClick } className="comment-collapse-button">
6262
{isLoadingComments ? 'Loading...' : 'View older comments'}
6363
</a>
6464
</div>}
6565
</div>
6666
</div>
6767
</Panel.Body>
68-
{_comments.map((item, idx) =>
68+
{comments.map((item, idx) =>
6969
<Comment
7070
key={idx}
7171
avatarUrl={item.author.photoURL}

src/components/Feed/NewPost.jsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ class NewPost extends React.Component {
5858
document.removeEventListener('click', this.onClickOutside)
5959
}
6060

61+
componentWillReceiveProps(nextProps) {
62+
if (!(nextProps.isCreating || nextProps.hasError && !nextProps.isCreating)) {
63+
this.setState({editorState: EditorState.createEmpty()})
64+
this.refs.title.value = ''
65+
}
66+
this.onNewPostChange()
67+
}
68+
6169
onClickOutside(evt) {
6270
let currNode = evt.target
6371
let isEditor = false
@@ -150,8 +158,8 @@ class NewPost extends React.Component {
150158
const content = stateToMarkdown(editorState.getCurrentContent())
151159
if (title && content) {
152160
this.props.onPost({title, content})
153-
this.setState({editorState: EditorState.createEmpty()})
154-
this.refs.title.value = ''
161+
// this.setState({editorState: EditorState.createEmpty()})
162+
// this.refs.title.value = ''
155163
}
156164
}
157165

src/components/MessageDetails/MessageDetails.jsx

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,56 +5,43 @@ import ActionCard from '../ActionCard/ActionCard'
55
import BtnSeparator from '../ActionCard/BtnSeparator'
66
import Comment from '../ActionCard/Comment'
77
import AddComment from '../ActionCard/AddComment'
8-
import { THREAD_MESSAGES_PAGE_SIZE } from '../../config/constants'
98

109
class MessageDetails extends React.Component {
1110

1211
constructor(props) {
1312
super(props)
1413
this.handleLoadMoreClick = this.handleLoadMoreClick.bind(this)
15-
this.state = { showAll: false }
1614
}
1715

1816
handleLoadMoreClick() {
19-
this.setState({showAll: true})
20-
// TODO - handle the case when a topic has more than 20 comments
21-
// since those will have to retrieved from the server
22-
// if (!isLoadingComments) {
23-
// onLoadMoreComments()
24-
// }
17+
this.props.onLoadMoreMessages()
2518
}
2619

2720
render() {
2821
const {
29-
title,
30-
messages,
31-
// onLoadMoreMessages,
32-
hasMoreMessages,
33-
newMessage,
34-
onNewMessageChange,
35-
onAddNewMessage,
36-
isLoadingComments,
37-
currentUser,
38-
isAddingComment,
39-
allowAddingComment} = this.props
22+
title,
23+
messages,
24+
hasMoreMessages,
25+
newMessage,
26+
onNewMessageChange,
27+
onAddNewMessage,
28+
isLoadingComments,
29+
currentUser,
30+
isAddingComment,
31+
error,
32+
allowAddingComment} = this.props
4033
let authorName = currentUser.firstName
4134
if (authorName && currentUser.lastName) {
4235
authorName += ' ' + currentUser.lastName
4336
}
44-
let _messages = messages
45-
let _hasMoreMessages = hasMoreMessages
46-
if (!this.state.showAll && _messages.length > THREAD_MESSAGES_PAGE_SIZE) {
47-
_messages = _messages.slice(-THREAD_MESSAGES_PAGE_SIZE)
48-
_hasMoreMessages = true
49-
}
5037
return (
5138
<ActionCard className="main-messaging">
5239
<ActionCard.Header title={title}>
53-
{_hasMoreMessages && <BtnSeparator onClick={this.handleLoadMoreClick} isLoadingComments={ isLoadingComments }>
40+
{hasMoreMessages && <BtnSeparator onClick={this.handleLoadMoreClick} isLoadingComments={ isLoadingComments }>
5441
{isLoadingComments ? 'Loading...' : 'Load earlier messages'}
5542
</BtnSeparator>}
5643
</ActionCard.Header>
57-
{_messages && _messages.map((item, idx) =>
44+
{messages && messages.map((item, idx) =>
5845
<Comment
5946
key={idx}
6047
avatarUrl={item.author.photoURL}
@@ -71,6 +58,7 @@ class MessageDetails extends React.Component {
7158
<AddComment
7259
className="messaging-comment-section"
7360
isAdding={isAddingComment}
61+
hasError={error}
7462
avatarUrl={currentUser.photoURL}
7563
authorName={ authorName }
7664
onAdd={onAddNewMessage}

src/components/ProjectProgress/ProjectProgress.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const ProjectProgress = ({title, type, percent, children }) => (
2222
ProjectProgress.defaultProps = {
2323
type: 'completed'
2424
}
25+
2526
ProjectProgress.propTypes = {
2627
title: PropTypes.string.isRequired,
2728
type: PropTypes.oneOf(['working', 'error', 'completed']),

src/components/TopBar/TopBarContainer.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import TopBar from './TopBar'
88
import CreateView from '../../projects/create/components/CreateView'
99
import { TCEmitter } from '../../helpers'
1010
import {
11+
DOMAIN,
1112
ROLE_CONNECT_COPILOT,
1213
ROLE_CONNECT_MANAGER,
1314
ROLE_ADMINISTRATOR,
1415
EVENT_ROUTE_CHANGE,
15-
ACCOUNTS_APP_LOGIN_URL,
1616
ACCOUNTS_APP_REGISTER_URL
1717
} from '../../config/constants'
1818

@@ -97,7 +97,8 @@ class TopBarContainer extends React.Component {
9797
const {isCreatingProject, currentPath, isFilterVisible } = this.state
9898
const isProjectDetails = /projects\/\d+/.test(currentPath)
9999
const isHomePage = this.context.router.isActive('/', true)
100-
const loginUrl = ACCOUNTS_APP_LOGIN_URL
100+
// NOTE: hardcoding to connectv2, once connect v1
101+
const loginUrl = `ACCOUNTS_APP_LOGIN_URL?retUrl=https://connectv2.${DOMAIN}/`
101102
const registerUrl = !isHomePage ? ACCOUNTS_APP_REGISTER_URL : null
102103
return (
103104
<div>

src/projects/detail/containers/Specification.jsx renamed to src/config/projectQuestions/topcoder.v1.js

Lines changed: 1 addition & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,6 @@
1-
'use strict'
2-
3-
import React, { Component, PropTypes } from 'react'
4-
import { connect } from 'react-redux'
51
import _ from 'lodash'
6-
import Sticky from 'react-stickynode'
7-
8-
import ProjectSpecSidebar from '../components/ProjectSpecSidebar'
9-
import FooterV2 from '../../../components/FooterV2/FooterV2'
10-
import EditProjectForm from '../components/EditProjectForm'
11-
import { updateProject } from '../../actions/project'
12-
import spinnerWhileLoading from '../../../components/LoadingSpinner'
132
import { Icons } from 'appirio-tech-react-components'
143

15-
16-
require('./Specification.scss')
17-
184
const isFileRequired = (project, subSections) => {
195
const subSection = _.find(subSections, (s) => s.type === 'questions')
206
const fields = _.filter(subSection.questions, q => q.type.indexOf('see-attached') > -1)
@@ -199,69 +185,4 @@ const sections = [
199185
}
200186
]
201187

202-
// This handles showing a spinner while the state is being loaded async
203-
const enhance = spinnerWhileLoading(props => !props.processing)
204-
const EnhancedEditProjectForm = enhance(EditProjectForm)
205-
206-
class ProjectSpecification extends Component {
207-
constructor(props) {
208-
super(props)
209-
this.saveProject = this.saveProject.bind(this)
210-
}
211-
212-
saveProject(model) {
213-
// compare old & new
214-
this.props.updateProject(this.props.project.id, model)
215-
}
216-
217-
render() {
218-
const { project, currentMemberRole } = this.props
219-
220-
return (
221-
<section className="two-col-content content">
222-
<div className="container">
223-
<div className="left-area">
224-
<Sticky top={80}>
225-
<ProjectSpecSidebar project={project} sections={sections} currentMemberRole={currentMemberRole} />
226-
<FooterV2 />
227-
</Sticky>
228-
</div>
229-
230-
<div className="right-area">
231-
<EnhancedEditProjectForm
232-
project={project}
233-
sections={sections}
234-
isEdittable={!!currentMemberRole}
235-
submitHandler={this.saveProject}
236-
/>
237-
</div>
238-
239-
</div>
240-
</section>
241-
)
242-
}
243-
}
244-
245-
ProjectSpecification.propTypes = {
246-
project: PropTypes.object.isRequired,
247-
currentMemberRole: PropTypes.string,
248-
processing: PropTypes.bool,
249-
error: PropTypes.oneOfType([
250-
PropTypes.bool,
251-
PropTypes.object
252-
])
253-
}
254-
255-
const mapStateToProps = ({projectState, loadUser}) => {
256-
return {
257-
processing: projectState.processing,
258-
error: projectState.error,
259-
currentUserId: parseInt(loadUser.user.id)
260-
}
261-
}
262-
263-
const mapDispatchToProps = { updateProject }
264-
265-
ProjectSpecification.sections = sections
266-
267-
export default connect(mapStateToProps, mapDispatchToProps)(ProjectSpecification)
188+
export default sections

src/projects/actions/projectTopics.js

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,40 @@ export function laodProjectMessages(projectId) {
4141

4242
// ignore action param
4343
/*eslint-disable no-unused-vars */
44+
45+
const getTopicsWithComments = (projectId, tag) => {
46+
return getTopics({ reference : 'project', referenceId: projectId, tag })
47+
.then(({topics, totalCount}) => {
48+
const additionalPosts = []
49+
// if a topic has more than 20 posts then to display the latest posts,
50+
// we'll have to first retrieve them from the server
51+
_.forEach(topics, (t) => {
52+
if (t.postIds.length > 20) {
53+
const postIds = t.postIds.slice(20).slice(-6)
54+
additionalPosts.push(getTopicPosts(t.id, postIds))
55+
}
56+
t.posts = _.sortBy(t.posts, ['id'])
57+
})
58+
if (additionalPosts.length === 0) {
59+
// we dont need to retrieve any additional posts
60+
return { topics, totalCount }
61+
}
62+
return Promise.all(additionalPosts)
63+
.then(postArr => {
64+
_.forEach(postArr, (p) => {
65+
const topic = _.find(topics, t => p.topicId)
66+
topic.posts = _.sortBy(topic.posts.concat(p.posts), ['id'])
67+
})
68+
return { topics, totalCount }
69+
})
70+
71+
})
72+
}
4473
const getProjectTopicsWithMember = (dispatch, projectId, tag) => {
4574
return new Promise((resolve, reject) => {
4675
return dispatch({
4776
type: LOAD_PROJECT_FEEDS,
48-
payload: getTopics({ reference : 'project', referenceId: projectId, tag }),
77+
payload: getTopicsWithComments(projectId, tag),
4978
meta: { tag, projectId }
5079
})
5180
.then(({ value, action }) => {
@@ -84,11 +113,11 @@ export function createProjectTopic(projectId, topic) {
84113
}
85114
}
86115

87-
export function loadFeedComments(feedId, tag, fromIndex) {
116+
export function loadFeedComments(feedId, tag, postIds) {
88117
return (dispatch) => {
89118
return dispatch({
90119
type: LOAD_PROJECT_FEED_COMMENTS,
91-
payload: getTopicPosts(feedId, fromIndex),
120+
payload: getTopicPosts(feedId, postIds),
92121
meta: {
93122
topicId: feedId,
94123
tag

0 commit comments

Comments
 (0)