Skip to content

Commit d709e41

Browse files
committed
Merge branch 'dev' into feature/draftjs-link-editor
# Conflicts: # package-lock.json # src/components/RichTextArea/RichTextArea.jsx
2 parents d694360 + f65e72d commit d709e41

File tree

21 files changed

+762
-148
lines changed

21 files changed

+762
-148
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ workflows:
127127
- build-dev
128128
filters:
129129
branches:
130-
only: ['dev', 'dev-msinteg', 'feature/form-redesign']
130+
only: ['dev', 'dev-msinteg']
131131

132132
- deployProd:
133133
context : org-global

src/api/messages.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ export function deleteTopic(topicId) {
7676
}
7777

7878
export function addTopicPost(topicId, post) {
79-
return axios.post(`${apiBaseUrl}/topics/${topicId}/posts/create`, { post: post.content }, { timeout } )
79+
const payload = {
80+
post: post.content,
81+
attachmentIds: post.attachmentIds
82+
}
83+
return axios.post(`${apiBaseUrl}/topics/${topicId}/posts/create`, payload, { timeout } )
8084
.then( resp => {
8185
return {
8286
topicId,
@@ -86,7 +90,11 @@ export function addTopicPost(topicId, post) {
8690
}
8791

8892
export function saveTopicPost(topicId, post) {
89-
return axios.post(`${apiBaseUrl}/topics/${topicId}/posts/${post.id}/edit`, { post: post.content }, { timeout } )
93+
const payload = {
94+
post: post.content,
95+
attachmentIds: post.attachmentIds
96+
}
97+
return axios.post(`${apiBaseUrl}/topics/${topicId}/posts/${post.id}/edit`, payload, { timeout } )
9098
.then( resp => {
9199
return {
92100
topicId,
@@ -149,3 +157,28 @@ export function getTopicsWithComments(reference, referenceId, tag, removeCoderBo
149157

150158
})
151159
}
160+
161+
export function createTopicAttachment(attachment) {
162+
return axios.post(`${apiBaseUrl}/topics/attachments/create`, attachment, { timeout } )
163+
.then( resp => {
164+
return {
165+
result : _.get(resp.data, 'result.content', {})
166+
}
167+
})
168+
}
169+
170+
export function getTopicAttachment(attachmentId) {
171+
return axios.get(`${apiBaseUrl}/topics/attachments/${attachmentId}/read`, { timeout } )
172+
.then( resp => {
173+
return _.get(resp.data, 'result.content.url', '')
174+
})
175+
}
176+
177+
export function deleteTopicAttachment(attachmentId) {
178+
return axios.delete(`${apiBaseUrl}/topics/attachments/${attachmentId}/delete`, { timeout } )
179+
.then( resp => {
180+
return {
181+
result : _.get(resp.data, 'result.content', {})
182+
}
183+
})
184+
}

src/components/ActionCard/ActionCard.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ class Header extends React.Component{
4242
onTopicChange(title, content) {
4343
this.props.onTopicChange(this.props.topicMessage.id, title, content, true)
4444
}
45-
onSaveTopic({title, content}) {
46-
this.props.onSaveTopic(this.props.topicMessage.id, title, content)
45+
onSaveTopic({title, content, onSaveTopic}) {
46+
this.props.onSaveTopic(this.props.topicMessage.id, title, content, onSaveTopic)
4747
}
4848

4949
render() {
@@ -67,6 +67,7 @@ class Header extends React.Component{
6767
avatarUrl={this.props.avatarUrl}
6868
authorName={this.props.authorName}
6969
cancelEdit={this.cancelEditTopic}
70+
canUploadAttachment
7071
/>
7172
)
7273
}

src/components/ActionCard/AddComment.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ export default class AddComment extends React.Component {
1616
}
1717
}
1818

19-
onPost({content}) {
20-
this.props.onAdd(content)
19+
onPost({ content, attachmentIds }) {
20+
this.props.onAdd(content, attachmentIds)
2121
}
2222

2323
onChange(title, content) {
@@ -40,6 +40,7 @@ export default class AddComment extends React.Component {
4040
authorName={authorName}
4141
allMembers={allMembers}
4242
projectMembers={projectMembers}
43+
canUploadAttachment
4344
/>
4445
)
4546
}

src/components/ActionCard/Comment.jsx

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@ import PropTypes from 'prop-types'
33
import cn from 'classnames'
44
import UserTooltip from '../User/UserTooltip'
55
import RichTextArea from '../RichTextArea/RichTextArea'
6-
import { Link } from 'react-router-dom'
6+
import { Link, withRouter } from 'react-router-dom'
77
import CommentEditToggle from './CommentEditToggle'
88
import _ from 'lodash'
99
import moment from 'moment'
1010
import NotificationsReader from '../../components/NotificationsReader'
11-
import {
11+
import {
1212
POST_TIME_FORMAT,
13-
EVENT_TYPE,
13+
EVENT_TYPE,
1414
} from '../../config/constants.js'
1515

1616
import './Comment.scss'
17+
import { PROJECT_ATTACHMENTS_FOLDER } from '../../config/constants'
1718

1819
class Comment extends React.Component {
1920

@@ -25,18 +26,24 @@ class Comment extends React.Component {
2526
this.edit = this.edit.bind(this)
2627
this.delete = this.delete.bind(this)
2728
this.cancelEdit = this.cancelEdit.bind(this)
29+
this.getDownloadAttachmentUrl = this.getDownloadAttachmentUrl.bind(this)
30+
this.getDownloadAttachmentFilename = this.getDownloadAttachmentFilename.bind(this)
2831
}
2932

3033
componentWillMount() {
31-
this.setState({editMode: this.props.message && this.props.message.editMode || this.props.isSaving})
34+
const projectId = this.props.match.params.projectId
35+
this.setState({
36+
editMode: this.props.message && this.props.message.editMode || this.props.isSaving,
37+
attachmentsStorePath: `${PROJECT_ATTACHMENTS_FOLDER}/${projectId}/`
38+
})
3239
}
3340

3441
componentWillReceiveProps(nextProps) {
3542
this.setState({editMode: nextProps.message && nextProps.message.editMode || nextProps.isSaving})
3643
}
3744

38-
onSave({content}) {
39-
this.props.onSave(this.props.message, content)
45+
onSave({content, attachmentIds}) {
46+
this.props.onSave(this.props.message, content, attachmentIds)
4047
}
4148

4249
onChange(title, content) {
@@ -57,6 +64,16 @@ class Comment extends React.Component {
5764
this.props.onChange(null, false)
5865
}
5966

67+
getDownloadAttachmentUrl(attachmentId) {
68+
return `/projects/messages/attachments/${attachmentId}`
69+
}
70+
71+
getDownloadAttachmentFilename(attachmentOriginalFilename) {
72+
const regex = new RegExp(`^${_.escapeRegExp(this.state.attachmentsStorePath)}.[a-zA-Z0-9]*.(.*.)`, 'g')
73+
const match = regex.exec(attachmentOriginalFilename)
74+
return match[1]
75+
}
76+
6077
render() {
6178
const {message, author, date, edited, children, noInfo, self, isSaving, hasError, readonly, allMembers, canDelete, projectMembers, commentAnchorPrefix} = this.props
6279
const messageAnchor = commentAnchorPrefix + message.id
@@ -86,18 +103,20 @@ class Comment extends React.Component {
86103
allMembers={allMembers}
87104
projectMembers={projectMembers}
88105
editingTopic = {false}
106+
canUploadAttachment
107+
attachments={message.attachments}
89108
/>
90109
</div>
91110
)
92111
}
93112

94113
return (
95114
<div styleName={cn('container', { self, 'is-deleting': isDeleting })} id={messageAnchor}>
96-
<NotificationsReader
115+
<NotificationsReader
97116
id={messageAnchor}
98117
criteria={[
99-
{ eventType: EVENT_TYPE.POST.CREATED, contents: { postId: message.id } },
100-
{ eventType: EVENT_TYPE.POST.UPDATED, contents: { postId: message.id } },
118+
{ eventType: EVENT_TYPE.POST.CREATED, contents: { postId: message.id } },
119+
{ eventType: EVENT_TYPE.POST.UPDATED, contents: { postId: message.id } },
101120
{ eventType: EVENT_TYPE.POST.MENTION, contents: { postId: message.id } },
102121
]}
103122
/>
@@ -130,6 +149,19 @@ class Comment extends React.Component {
130149
<div styleName="text" className="draftjs-post">
131150
{children}
132151
</div>
152+
{ message.attachments &&
153+
<div styleName="download-attachment-files">
154+
<ul>
155+
{
156+
message.attachments.map(attachment => (
157+
<li key={`attachment-${attachment.id}`}>
158+
<a href={this.getDownloadAttachmentUrl(attachment.id)} target="_blank">{this.getDownloadAttachmentFilename(attachment.originalFileName)}</a>
159+
</li>
160+
))
161+
}
162+
</ul>
163+
</div>
164+
}
133165
{isDeleting &&
134166
<div styleName="deleting-layer">
135167
<div>Deleting post ...</div>
@@ -214,4 +246,4 @@ Comment.propTypes = {
214246
commentAnchorPrefix: PropTypes.string,
215247
}
216248

217-
export default Comment
249+
export default withRouter(Comment)

src/components/ActionCard/Comment.scss

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
min-width: 0;
3636
}
3737

38-
.text {
38+
.text {
3939
a,
4040
a:hover {
4141
color:$tc-dark-blue-110;
@@ -120,3 +120,83 @@
120120
line-height: 20px;
121121
}
122122
}
123+
124+
.download-attachment-files {
125+
margin-top: 10px;
126+
width: 50%;
127+
li{
128+
@include roboto;
129+
font-size: $tc-label-md;
130+
color: $tc-dark-blue-110;
131+
line-height: 1;
132+
padding: $base-unit 0 $base-unit 0;
133+
display: flex;
134+
135+
&.clickable {
136+
cursor: pointer;
137+
}
138+
139+
&.is-active {
140+
background-color: $tc-gray-neutral-dark;
141+
142+
&:not(.delete-confirmation-modal):hover {
143+
background-color: $tc-gray-neutral-dark;
144+
}
145+
}
146+
147+
.button-group {
148+
margin-left: auto;
149+
padding-left:20px;
150+
width: 110px;
151+
}
152+
153+
.buttons{
154+
visibility: hidden;
155+
margin-right: 5px;
156+
margin-left: auto;
157+
button {
158+
padding: 0;
159+
background: transparent;
160+
border: none;
161+
cursor: pointer;
162+
opacity: 0.4;
163+
height: 16px;
164+
width: 16px;
165+
background-size: 16px;
166+
display: inline-block;
167+
margin-left: 15px;
168+
}
169+
}
170+
a {
171+
color: $tc-dark-blue-110;
172+
line-height: $base-unit*4;
173+
max-width: 220px;
174+
text-overflow: ellipsis;
175+
overflow-x: hidden;
176+
177+
&:visited {
178+
color: $tc-dark-blue-110;
179+
}
180+
}
181+
}
182+
@media screen and (min-width: $screen-md) {
183+
li:hover{
184+
background: $tc-gray-neutral-light;
185+
color: $tc-dark-blue;
186+
187+
.buttons{
188+
display: block;
189+
}
190+
.link-buttons{
191+
visibility: visible;
192+
}
193+
}
194+
}
195+
196+
li:before {
197+
content: '\b7\a0';
198+
font-size: 200%;
199+
color: $tc-dark-blue-110;
200+
line-height: $base-unit*3;
201+
}
202+
}

src/components/Feed/Feed.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ class Feed extends React.Component {
6767
this.props.onTopicChange(this.props.topicMessage.id, title, content, true)
6868
}
6969

70-
onSaveTopic({title, content}) {
71-
this.props.onSaveTopic(this.props.topicMessage.id, title, content)
70+
onSaveTopic({title, content, attachmentIds}) {
71+
this.props.onSaveTopic(this.props.topicMessage.id, title, content, attachmentIds)
7272
}
7373

7474
updateHeaderHeight() {

src/components/Feed/FeedComments.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ class FeedComments extends React.Component {
425425
submitText="Post"
426426
nextStepText="Add a post"
427427
onClose={this.toggleNewCommentMobile}
428-
onPost={({ content }) => onAddNewComment(content)}
428+
onPost={({ content, attachmentIds }) => onAddNewComment(content, attachmentIds)}
429429
isCreating={isAddingComment}
430430
hasError={error}
431431
onNewPostChange={this.onNewCommentChange}

src/components/Feed/NewPost.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class NewPost extends React.Component {
4040
allMembers={allMembers}
4141
projectMembers={projectMembers}
4242
hasPrivateSwitch={canAccessPrivatePosts}
43+
canUploadAttachment
4344
/>
4445
)
4546
}

0 commit comments

Comments
 (0)