Skip to content

Commit 4224987

Browse files
authored
Merge pull request #972 from appirio-tech/feature/messageEditDelete
Feature/message edit delete
2 parents f145647 + 96af853 commit 4224987

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1993
-504
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ bower_components
55
build
66
dist
77
npm-debug.log
8+
.history

docs/dependency-notes.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
This document outlines the dependency concerns faced during the development of the application.
3+
4+
1. We have overridden the version to 1.1.2 of to-ico library which is used indirectly by "favicon-webpack-plugin" which in turn is used for generating the favicons for different devices and browser combinations. This was required because with versions above 1.1.2 to-ico library is using some features from node v5.10+.

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
"deep-freeze-node": "^1.1.2",
1919
"eslint": "^2.2.0",
2020
"eslint-plugin-react": "^4.1.0",
21+
"favicons-webpack-plugin": "0.0.7",
22+
"to-ico": "1.1.2",
2123
"ignore-styles": "^1.2.0",
2224
"mocha": "^2.4.5",
2325
"mocha-jsdom": "^1.1.0",
@@ -34,8 +36,9 @@
3436
"axios": "^0.13.1",
3537
"classnames": "^2.2.3",
3638
"draft-js": "^0.7.0",
37-
"draft-js-export-html": "^0.4.0",
39+
"draft-js-export-html": "^0.5.0",
3840
"draft-js-export-markdown": "^0.2.1",
41+
"draft-js-import-html": "^0.3.2",
3942
"fbemitter": "^2.1.1",
4043
"filepicker-js": "^2.4.17",
4144
"filesize": "^3.3.0",

src/api/messages.js

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import _ from 'lodash'
22
import { axiosInstance as axios } from './requestInterceptor'
3-
import { TC_API_URL } from '../config/constants'
3+
import { CONNECT_MESSAGE_API_URL } from '../config/constants'
4+
5+
const timeout = 1.5 * 60 * 1000
46

57
export function getTopics(criteria) {
68
const params = {}
@@ -12,7 +14,7 @@ export function getTopics(criteria) {
1214
params.filter = filterStr.join('&')
1315
}
1416

15-
return axios.get(`${TC_API_URL}/v4/topics/`, { params })
17+
return axios.get(`${CONNECT_MESSAGE_API_URL}/v4/topics/`, { params })
1618
.then( resp => {
1719
return {
1820
totalCount: _.get(resp.data, 'result.metadata.totalCount', 0),
@@ -22,7 +24,7 @@ export function getTopics(criteria) {
2224
}
2325

2426
export function getTopic(topicId) {
25-
return axios.get(`${TC_API_URL}/v4/topics/${topicId}`)
27+
return axios.get(`${CONNECT_MESSAGE_API_URL}/v4/topics/${topicId}`)
2628
.then( resp => {
2729
return {
2830
totalCount: _.get(resp.data, 'result.metadata.totalCount', 0),
@@ -34,7 +36,7 @@ export function getTopic(topicId) {
3436

3537
export function getTopicPosts(topicId, postIds) {
3638
const params = { postIds : postIds.join(',') }
37-
return axios.get(`${TC_API_URL}/v4/topics/${topicId}/posts`, { params })
39+
return axios.get(`${CONNECT_MESSAGE_API_URL}/v4/topics/${topicId}/posts`, { params })
3840
.then( resp => {
3941
return {
4042
totalCount: _.get(resp.data, 'result.metadata.totalCount', 0),
@@ -45,16 +47,32 @@ export function getTopicPosts(topicId, postIds) {
4547
}
4648

4749
export function createTopic(topicProps) {
48-
return axios.post(`${TC_API_URL}/v4/topics/`, topicProps, { timeout: 1.5 * 60 * 1000 })
50+
return axios.post(`${CONNECT_MESSAGE_API_URL}/v4/topics/`, topicProps, { timeout })
4951
.then( resp => {
5052
return _.get(resp.data, 'result.content', {})
5153
})
5254
}
5355

56+
export function saveTopic(topicId, topicProps) {
57+
return axios.post(`${CONNECT_MESSAGE_API_URL}/v4/topics/${topicId}/edit`, topicProps, { timeout })
58+
.then( resp => {
59+
return _.get(resp.data, 'result.content', {})
60+
})
61+
}
62+
63+
export function deleteTopic(topicId) {
64+
return axios.delete(`${CONNECT_MESSAGE_API_URL}/v4/topics/${topicId}`, null, { timeout } )
65+
.then( resp => {
66+
return {
67+
result : _.get(resp.data, 'result.content', {})
68+
}
69+
})
70+
}
71+
5472
// ignore resp
5573
/*eslint-disable no-unused-vars */
5674
export function addTopicPost(topicId, post) {
57-
return axios.post(`${TC_API_URL}/v4/topics/${topicId}/posts`, { post: post.content }, { timeout: 1.5 * 60 * 1000 } )
75+
return axios.post(`${CONNECT_MESSAGE_API_URL}/v4/topics/${topicId}/posts`, { post: post.content }, { timeout } )
5876
.then( resp => {
5977
return {
6078
topicId,
@@ -63,3 +81,22 @@ export function addTopicPost(topicId, post) {
6381
})
6482
}
6583
/*eslint-enable*/
84+
85+
export function saveTopicPost(topicId, post) {
86+
return axios.post(`${CONNECT_MESSAGE_API_URL}/v4/topics/${topicId}/posts/${post.id}/edit`, { post: post.content }, { timeout } )
87+
.then( resp => {
88+
return {
89+
topicId,
90+
comment : _.get(resp.data, 'result.content', {})
91+
}
92+
})
93+
}
94+
95+
export function deleteTopicPost(topicId, postId) {
96+
return axios.delete(`${CONNECT_MESSAGE_API_URL}/v4/topics/${topicId}/posts/${postId}`, null, { timeout } )
97+
.then( resp => {
98+
return {
99+
result : _.get(resp.data, 'result.content', {})
100+
}
101+
})
102+
}
Lines changed: 16 additions & 0 deletions
Loading
Lines changed: 17 additions & 0 deletions
Loading

src/components/ActionCard/ActionCard.jsx

Lines changed: 87 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import React, {PropTypes} from 'react'
22
import './ActionCard.scss'
33
import Panel from '../Panel/Panel'
44
import cn from 'classnames'
5+
import CommentEditToggle from './CommentEditToggle'
6+
import RichTextArea from '../RichTextArea/RichTextArea'
57

68
const ActionCard = ({children, className}) => (
79
<Panel className={cn('action-card', className)}>
@@ -14,25 +16,96 @@ ActionCard.propTypes = {
1416
className: PropTypes.string
1517
}
1618

17-
const Header = ({children, title}) => (
18-
<div className="panel-body">
19-
<div className="portrait">
20-
&nbsp;
21-
</div>
22-
<div className="object">
23-
<div className="card-header">
24-
<div className="card-title">
25-
{title}
19+
class Header extends React.Component{
20+
constructor(props) {
21+
super(props)
22+
this.state = {editTopicMode: false}
23+
this.onEditTopic = this.onEditTopic.bind(this)
24+
this.cancelEditTopic = this.cancelEditTopic.bind(this)
25+
this.onTopicChange = this.onTopicChange.bind(this)
26+
this.onSaveTopic = this.onSaveTopic.bind(this)
27+
}
28+
29+
componentWillReceiveProps(nextProps) {
30+
this.setState({editTopicMode: nextProps.editTopicMode})
31+
}
32+
33+
onEditTopic() {
34+
this.setState({editTopicMode: true})
35+
this.props.onTopicChange(this.props.topicMessage.id, null, null, true)
36+
}
37+
cancelEditTopic() {
38+
this.setState({editTopicMode: false})
39+
this.props.onTopicChange(this.props.topicMessage.id, null, null, false)
40+
}
41+
onTopicChange(title, content) {
42+
this.props.onTopicChange(this.props.topicMessage.id, title, content, true)
43+
}
44+
onSaveTopic({title, content}) {
45+
this.props.onSaveTopic(this.props.topicMessage.id, title, content)
46+
}
47+
48+
render() {
49+
if (this.state.editTopicMode) {
50+
const { topicMessage } = this.props
51+
const title = this.props.newTitle === null || this.props.newTitle === undefined ? this.props.title : this.props.newTitle
52+
const content = topicMessage.newContent === null || topicMessage.newContent === undefined ? topicMessage.content : topicMessage.newContent
53+
return (
54+
<RichTextArea
55+
editMode
56+
title={title}
57+
content={content}
58+
oldTitle={this.props.title}
59+
oldContent={topicMessage.content}
60+
onPost={this.onSaveTopic}
61+
onPostChange={this.onTopicChange}
62+
isCreating={this.props.isSavingTopic}
63+
hasError={this.props.error}
64+
avatarUrl={this.props.avatarUrl}
65+
authorName={this.props.authorName}
66+
cancelEdit={this.cancelEditTopic}
67+
/>
68+
)
69+
}
70+
71+
return (
72+
<div className="panel-body">
73+
<div className="portrait">
74+
&nbsp;
75+
</div>
76+
<div className="object">
77+
<div className="card-header">
78+
<div className="card-title">
79+
<div>{this.props.title}</div>
80+
{this.props.self && (
81+
<CommentEditToggle
82+
forTopic
83+
hideDelete={this.props.hideDelete}
84+
onEdit={this.onEditTopic}
85+
onDelete={this.props.onDeleteTopic}
86+
/>
87+
)}
88+
</div>
89+
</div>
90+
{this.props.children}
2691
</div>
2792
</div>
28-
{children}
29-
</div>
30-
</div>
31-
)
93+
)
94+
}
95+
}
3296

3397
Header.propTypes = {
3498
children: PropTypes.any.isRequired,
35-
title: PropTypes.string.isRequired
99+
title: PropTypes.string.isRequired,
100+
authorName: PropTypes.string.isRequired,
101+
avatarUrl: PropTypes.string,
102+
onTopicChange: PropTypes.func.isRequired,
103+
onSaveTopic: PropTypes.func.isRequired,
104+
onDeleteTopic: PropTypes.func.isRequired,
105+
hideDelete: PropTypes.bool,
106+
self: PropTypes.bool,
107+
isSavingTopic: PropTypes.bool,
108+
error: PropTypes.bool
36109
}
37110

38111
ActionCard.Header = Header

0 commit comments

Comments
 (0)