Skip to content

Commit c6da221

Browse files
author
Parth Shah
committed
Merge branch 'dev'
2 parents fab8c44 + bf407da commit c6da221

File tree

11 files changed

+159
-50
lines changed

11 files changed

+159
-50
lines changed

src/api/messages.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,18 @@ export function getTopics(criteria) {
2121
})
2222
}
2323

24+
export function getTopic(topicId) {
25+
return axios.get(`${TC_API_URL}/v4/topics/${topicId}`)
26+
.then( resp => {
27+
return {
28+
totalCount: _.get(resp.data, 'result.metadata.totalCount', 0),
29+
topics: _.get(resp.data, 'result.content', []),
30+
topicId
31+
}
32+
})
33+
}
34+
2435
export function getTopicPosts(topicId, postIds) {
25-
console.log(postIds)
2636
const params = { postIds : postIds.join(',') }
2737
return axios.get(`${TC_API_URL}/v4/topics/${topicId}/posts`, { params })
2838
.then( resp => {

src/components/ColorSelector/ColorSelector.jsx

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, {PropTypes} from 'react'
22
import './ColorSelector.scss'
33
import { SketchPicker } from 'react-color'
4-
import _ from 'lodash'
54
import { HOC as hoc } from 'formsy-react'
65
import {PROJECT_MAX_COLORS} from '../../config/constants'
76
import { Icons } from 'appirio-tech-react-components'
@@ -13,15 +12,19 @@ class ColorSelector extends React.Component {
1312

1413
this.state = {
1514
isPickerVisible: false,
16-
newColor: '#fff',
17-
colors: _.uniq([...props.defaultColors, ...props.value])
15+
newColor: '#fff'
1816
}
1917
}
2018

2119
render() {
22-
const {getValue, name, onChange, setValue} = this.props
23-
const value = getValue() || []
24-
const {isPickerVisible, colors, newColor} = this.state
20+
const {getValue, name, onChange, setValue, defaultColors } = this.props
21+
const value = getValue() || defaultColors
22+
const {isPickerVisible, newColor} = this.state
23+
24+
const updateNewColorPalette = (palette) => {
25+
setValue(palette)
26+
onChange(name, palette)
27+
}
2528

2629
const onColorToggle = (color) => {
2730
const index = value.indexOf(color)
@@ -34,8 +37,7 @@ class ColorSelector extends React.Component {
3437
newValue = tmp
3538
}
3639

37-
setValue(newValue)
38-
onChange(name, newValue)
40+
updateNewColorPalette(newValue)
3941
}
4042

4143
return (
@@ -53,8 +55,8 @@ class ColorSelector extends React.Component {
5355
</span>
5456
</a>
5557
)}
56-
57-
{colors.length < PROJECT_MAX_COLORS &&
58+
59+
{value.length < PROJECT_MAX_COLORS &&
5860
<a
5961
href="javascript:"
6062
onClick={() => this.setState({isPickerVisible: true})}
@@ -72,14 +74,11 @@ class ColorSelector extends React.Component {
7274
<button type="button" className="tc-btn tc-btn-primary tc-btn-md"
7375
onClick={() => {
7476
this.setState({isPickerVisible: false})
75-
if (colors.indexOf(newColor) === -1) {
76-
this.setState({colors: [...colors, newColor], newColor: '#fff'})
77-
} else {
78-
this.setState({newColor: '#fff'})
77+
const index = value.indexOf(this.state.newColor)
78+
if (index === -1) {
79+
const newValue = [ ...value, newColor ]
80+
updateNewColorPalette(newValue)
7981
}
80-
const newValue = [...value, newColor]
81-
setValue(newValue)
82-
onChange(name, newValue)
8382
}}
8483
>Add</button>
8584
<button

src/components/MessageList/MessageList.jsx

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {PropTypes} from 'react'
1+
import React, {Component, PropTypes} from 'react'
22
import Panel from '../Panel/Panel'
33
import './MessageList.scss'
44
import cn from 'classnames'
@@ -49,18 +49,40 @@ const MessageRow = ({title, messages, isActive, unreadCount, onClick}) => {
4949
}
5050

5151

52-
const MessageList = ({threads, onSelect, onAdd, showAddButton, showEmptyState}) => (
53-
<Panel className="message-list">
54-
<Panel.Title>
55-
Discussions
56-
{ showAddButton && <Panel.AddBtn onClick={onAdd} /> }
57-
</Panel.Title>
58-
<div className="panel-messages">
59-
{ showEmptyState && <MessageRow title="First discussion post" isActive messages={[{ content: ''}]} /> }
60-
{threads.map((item) => <MessageRow key={item.id} onClick={(e) => onSelect(item, e) } {...item} />)}
61-
</div>
62-
</Panel>
63-
)
52+
class MessageList extends Component {
53+
constructor(props) {
54+
super(props)
55+
}
56+
57+
componentDidMount() {
58+
const { scrollPosition } = this.props
59+
if (scrollPosition) {
60+
const panelMessages = this.refs.panelMessages
61+
// We use requestAnimationFrame because this function may be executed before
62+
// the DOM elements are actually drawn.
63+
// Source: http://stackoverflow.com/a/28748160
64+
requestAnimationFrame(() => {
65+
panelMessages.scrollTop += scrollPosition
66+
})
67+
}
68+
}
69+
70+
render() {
71+
const {threads, onSelect, onAdd, showAddButton, showEmptyState } = this.props
72+
return (
73+
<Panel className="message-list">
74+
<Panel.Title>
75+
Discussions
76+
{ showAddButton && <Panel.AddBtn onClick={onAdd} /> }
77+
</Panel.Title>
78+
<div className="panel-messages" ref="panelMessages">
79+
{ showEmptyState && <MessageRow title="First discussion post" isActive messages={[{ content: ''}]} /> }
80+
{threads.map((item) => <MessageRow key={item.id} onClick={(e) => onSelect(item, e) } {...item} />)}
81+
</div>
82+
</Panel>
83+
)
84+
}
85+
}
6486

6587
MessageList.propTypes = {
6688
/**

src/components/TopBar/TopBar.jsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ require('./TopBar.scss')
33
import React, {PropTypes, Component} from 'react'
44
import { Link } from 'react-router'
55
import cn from 'classnames'
6+
import _ from 'lodash'
67
import { UserDropdown, Icons } from 'appirio-tech-react-components'
78

89
const { ConnectLogoBeta } = Icons
@@ -66,7 +67,7 @@ class TopBar extends Component {
6667
]
6768
const logo = (
6869
<div className="logo-wrapper">
69-
<Link className="logo" to={logoTargetUrl}><ConnectLogoBeta /></Link>
70+
<Link className="logo" to={logoTargetUrl} target="_self"><ConnectLogoBeta /></Link>
7071
</div>
7172
)
7273
const avatar = (
@@ -94,6 +95,7 @@ class TopBar extends Component {
9495
if (isProjectDetails) {
9596
return <ProjectToolBar isPowerUser={isPowerUser} logo={logo} avatar={avatar} project={project} />
9697
}
98+
const noOfFilters = _.keys(criteria).length - 1 // -1 for default sort criteria
9799

98100
return (
99101
// <Sticky>
@@ -116,7 +118,7 @@ class TopBar extends Component {
116118
href="javascript:"
117119
className={cn('tc-btn tc-btn-sm', {active: isFilterVisible})}
118120
onClick={this.props.onToggleFilter}
119-
>Filters</a>
121+
>Filters { noOfFilters > 0 && <span className="filter-indicator">{ noOfFilters }</span> }</a>
120122
</div>}
121123
</div>
122124
{avatar}

src/components/TopBar/TopBar.scss

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ $tc-body-large : 20px;
7676

7777
.search-bar{
7878
margin: 0 auto;
79-
width: 585px;
79+
width: 605px;
8080
padding-top: 15px;
8181
display: flex;
8282
justify-content:space-between;
@@ -88,9 +88,11 @@ $tc-body-large : 20px;
8888
height: 30px;
8989
}
9090
.search-filter{
91-
width: 77px;
91+
width: 97px;
9292
.tc-btn{
93-
display: block;
93+
display: flex;
94+
align-items: center;
95+
justfiy-content: center;
9496
padding: 5px 0 5px 34px;
9597
text-align: left;
9698
color: $tc-gray-40;
@@ -118,6 +120,18 @@ $tc-body-large : 20px;
118120
}
119121
}
120122
}
123+
124+
.filter-indicator {
125+
width: 15px;
126+
height: 15px;
127+
margin-left: $base-unit;
128+
background-color: $tc-dark-blue-90;
129+
border-radius: 26px;
130+
color: $tc-white;
131+
display: flex;
132+
justify-content: center;
133+
align-items: center;
134+
}
121135
}
122136
}
123137
.welcome-info{

src/projects/create/components/NewProjectForm.scss

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,11 @@
273273
&.padding-top-30{
274274
padding-top: 60px;
275275
}
276-
.row{
276+
.row {
277277
margin-bottom: 20px;
278+
input::-ms-clear {
279+
display: none;
280+
}
278281
&.center{
279282
display: table;
280283
margin: 0 auto;
@@ -405,6 +408,9 @@
405408
height: 80px;
406409
resize: none;
407410
}
411+
input::-ms-clear {
412+
display: none;
413+
}
408414
&.center {
409415
display: flex;
410416
justify-content: center;

src/projects/detail/Messages.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import MessagesContainer from './containers/MessagesContainer'
44

55
require('./Messages.scss')
66

7-
const Messages = ({ project, currentMemberRole }) => (
8-
<MessagesContainer project={ project } currentMemberRole={ currentMemberRole } />
7+
const Messages = ({ location, project, currentMemberRole }) => (
8+
<MessagesContainer location={ location } project={ project } currentMemberRole={ currentMemberRole } />
99
)
1010
export default Messages

src/projects/detail/containers/MessagesContainer.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,14 @@ class MessagesView extends React.Component {
9292

9393
init(props) {
9494
const { activeThreadId } = this.state
95-
const activeThreadIndex = activeThreadId
96-
? _.findIndex(this.state.threads, (thread) => thread.id === activeThreadId )
95+
const propsThreadId = _.get(props, 'location.state.threadId', null)
96+
const threadId = activeThreadId ? activeThreadId : propsThreadId
97+
const activeThreadIndex = threadId
98+
? _.findIndex(props.threads, (thread) => thread.id === threadId )
9799
: 0
100+
98101
this.setState({
102+
scrollPosition: activeThreadIndex * 71,
99103
threads: props.threads.map((thread, idx) => {
100104
return this.mapFeed(thread,
101105
idx === activeThreadIndex,
@@ -187,7 +191,7 @@ class MessagesView extends React.Component {
187191
}
188192

189193
render() {
190-
const {threads, isCreateNewMessage, showEmptyState} = this.state
194+
const {threads, isCreateNewMessage, showEmptyState, scrollPosition} = this.state
191195
const { currentUser, isCreatingFeed, currentMemberRole, error } = this.props
192196
const activeThread = threads.filter((item) => item.isActive)[0]
193197
const renderRightPanel = () => {
@@ -228,6 +232,7 @@ class MessagesView extends React.Component {
228232
onSelect={this.onThreadSelect}
229233
showAddButton={ !!currentMemberRole }
230234
showEmptyState={ showEmptyState && !threads.length }
235+
scrollPosition={ scrollPosition }
231236
/>
232237
</div>
233238
<div className="right-area">

src/projects/detail/containers/TeamManagementContainer.jsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ class TeamManagementContainer extends Component {
5050
}
5151
}
5252

53+
componentDidUpdate(prevProps, prevState) {
54+
// Trigger a resize event to make sure all <Sticky> nodes update their sizes
55+
// whenever isAddingTeamMember is toggled.
56+
if (prevState.isAddingTeamMember !== this.state.isAddingTeamMember) {
57+
// We use requestAnimationFrame because this function may be executed before
58+
// the DOM elements are actually drawn.
59+
// Source: http://stackoverflow.com/a/28748160
60+
requestAnimationFrame(() => {
61+
const event = document.createEvent('HTMLEvents')
62+
event.initEvent('resize', true, false)
63+
window.dispatchEvent(event)
64+
})
65+
}
66+
}
67+
5368
updateSearchMembers({allMembers, members}) {
5469
const {keyword, selectedNewMember } = this.state
5570
if (!keyword || !keyword.trim().length) {

src/projects/list/components/Projects/Projects.jsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@ class Projects extends Component {
2222
// check for criteria specified in URL.
2323
const queryParams = _.get(this.props, 'location.query', null)
2424
if (!_.isEmpty(queryParams)) {
25-
if (queryParams.sort) criteria.sort = queryParams.sort
26-
if (queryParams.name) criteria.name = decodeURIComponent(queryParams.name)
27-
if (queryParams.status) criteria.status = queryParams.status
28-
if (queryParams.type) criteria.type = queryParams.type
29-
if (queryParams.memberOnly) criteria.memberOnly = queryParams.memberOnly
25+
const initialCriteria = {}
26+
if (queryParams.sort) initialCriteria.sort = queryParams.sort
27+
if (queryParams.name) initialCriteria.name = decodeURIComponent(queryParams.name)
28+
if (queryParams.status) initialCriteria.status = queryParams.status
29+
if (queryParams.type) initialCriteria.type = queryParams.type
30+
if (queryParams.memberOnly) initialCriteria.memberOnly = queryParams.memberOnly
3031
if (queryParams.page) pageNum = parseInt(queryParams.page)
31-
loadProjects(criteria, pageNum)
32+
loadProjects(initialCriteria, pageNum)
3233
} else {
3334
this.routeWithParams(criteria, pageNum)
3435
}

0 commit comments

Comments
 (0)