summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2015-11-18 09:07:57 -0500
committerChristopher Speller <crspeller@gmail.com>2015-11-18 09:07:57 -0500
commit9660adb00775aba822d2d684d215c55679a456c6 (patch)
tree0db5c19e03609cbce3f70e20c7fe45a10f640d18
parent7b01528d17c61a762ded17a23ccd9a2a728910a0 (diff)
parenta4267471a57c95dd99e17ee5e9fcc95892970764 (diff)
downloadchat-9660adb00775aba822d2d684d215c55679a456c6.tar.gz
chat-9660adb00775aba822d2d684d215c55679a456c6.tar.bz2
chat-9660adb00775aba822d2d684d215c55679a456c6.zip
Merge pull request #1430 from hmhealey/plt737a
PLT-737 Converted DeletePostModal to React-Bootstrap
-rw-r--r--web/react/components/create_comment.jsx3
-rw-r--r--web/react/components/create_post.jsx3
-rw-r--r--web/react/components/delete_post_modal.jsx155
-rw-r--r--web/react/components/edit_post_modal.jsx3
-rw-r--r--web/react/components/post_info.jsx14
-rw-r--r--web/react/components/rhs_comment.jsx8
-rw-r--r--web/react/components/rhs_root_post.jsx12
-rw-r--r--web/react/stores/modal_store.jsx8
-rw-r--r--web/react/stores/post_store.jsx19
-rw-r--r--web/react/utils/constants.jsx3
-rw-r--r--web/react/utils/utils.jsx9
11 files changed, 140 insertions, 97 deletions
diff --git a/web/react/components/create_comment.jsx b/web/react/components/create_comment.jsx
index 058594165..22a659ed5 100644
--- a/web/react/components/create_comment.jsx
+++ b/web/react/components/create_comment.jsx
@@ -194,7 +194,8 @@ export default class CreateComment extends React.Component {
title: 'Comment',
message: lastPost.message,
postId: lastPost.id,
- channelId: lastPost.channel_id
+ channelId: lastPost.channel_id,
+ comments: PostStore.getCommentCount(lastPost)
});
}
}
diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx
index 5a69c9bfb..6f25ef608 100644
--- a/web/react/components/create_post.jsx
+++ b/web/react/components/create_post.jsx
@@ -372,7 +372,8 @@ export default class CreatePost extends React.Component {
title: type,
message: lastPost.message,
postId: lastPost.id,
- channelId: lastPost.channel_id
+ channelId: lastPost.channel_id,
+ comments: PostStore.getCommentCount(lastPost)
});
}
}
diff --git a/web/react/components/delete_post_modal.jsx b/web/react/components/delete_post_modal.jsx
index f3bead1c2..e0489856f 100644
--- a/web/react/components/delete_post_modal.jsx
+++ b/web/react/components/delete_post_modal.jsx
@@ -3,7 +3,8 @@
var Client = require('../utils/client.jsx');
var PostStore = require('../stores/post_store.jsx');
-var BrowserStore = require('../stores/browser_store.jsx');
+var ModalStore = require('../stores/modal_store.jsx');
+var Modal = ReactBootstrap.Modal;
var Utils = require('../utils/utils.jsx');
var AsyncClient = require('../utils/async_client.jsx');
var AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
@@ -15,18 +16,40 @@ export default class DeletePostModal extends React.Component {
super(props);
this.handleDelete = this.handleDelete.bind(this);
+ this.handleToggle = this.handleToggle.bind(this);
+ this.handleHide = this.handleHide.bind(this);
this.onListenerChange = this.onListenerChange.bind(this);
- this.onShow = this.onShow.bind(this);
- this.state = {title: '', postId: '', channelId: '', selectedList: PostStore.getSelectedPost(), comments: 0};
+ this.selectedList = null;
+
+ this.state = {
+ show: true,
+ post: null,
+ commentCount: 0,
+ error: ''
+ };
+ }
+
+ componentDidMount() {
+ ModalStore.addModalListener(ActionTypes.TOGGLE_DELETE_POST_MODAL, this.handleToggle);
+ PostStore.addSelectedPostChangeListener(this.onListenerChange);
+ }
+
+ componentWillUnmount() {
+ PostStore.removeSelectedPostChangeListener(this.onListenerChange);
+ ModalStore.removeModalListener(ActionTypes.TOGGLE_DELETE_POST_MODAL, this.handleToggle);
}
+
handleDelete() {
- Client.deletePost(this.state.channelId, this.state.postId,
- function deleteSuccess() {
- var selectedList = this.state.selectedList;
+ Client.deletePost(
+ this.state.post.channel_id,
+ this.state.post.id,
+ () => {
+ var selectedList = this.selectedList;
+
if (selectedList && selectedList.order && selectedList.order.length > 0) {
var selectedPost = selectedList.posts[selectedList.order[0]];
- if ((selectedPost.id === this.state.postId && this.state.title === 'Post') || selectedPost.root_id === this.state.postId) {
+ if ((selectedPost.id === this.state.post.id && !this.state.root_id) || selectedPost.root_id === this.state.post.id) {
AppDispatcher.handleServerAction({
type: ActionTypes.RECIEVED_SEARCH,
results: null
@@ -36,7 +59,7 @@ export default class DeletePostModal extends React.Component {
type: ActionTypes.RECIEVED_POST_SELECTED,
results: null
});
- } else if (selectedPost.id === this.state.postId && this.state.title === 'Comment') {
+ } else if (selectedPost.id === this.state.post.id && this.state.root_id) {
if (selectedPost.root_id && selectedPost.root_id.length > 0 && selectedList.posts[selectedPost.root_id]) {
selectedList.order = [selectedPost.root_id];
delete selectedList.posts[selectedPost.id];
@@ -53,98 +76,96 @@ export default class DeletePostModal extends React.Component {
}
}
}
- PostStore.removePost(this.state.postId, this.state.channelId);
- AsyncClient.getPosts(this.state.channelId);
- }.bind(this),
- function deleteFailed(err) {
+
+ PostStore.removePost(this.state.post.id, this.state.post.channel_id);
+ AsyncClient.getPosts(this.state.post.channel_id);
+ },
+ (err) => {
AsyncClient.dispatchError(err, 'deletePost');
}
);
+
+ this.handleHide();
}
- onShow(e) {
- var newState = {};
- if (BrowserStore.getItem('edit_state_transfer')) {
- newState = BrowserStore.getItem('edit_state_transfer');
- BrowserStore.removeItem('edit_state_transfer');
- } else {
- var button = e.relatedTarget;
- newState = {title: $(button).attr('data-title'), channelId: $(button).attr('data-channelid'), postId: $(button).attr('data-postid'), comments: $(button).attr('data-comments')};
- }
- this.setState(newState);
- }
- componentDidMount() {
- $(ReactDOM.findDOMNode(this.refs.modal)).on('show.bs.modal', this.onShow);
- PostStore.addSelectedPostChangeListener(this.onListenerChange);
+
+ handleToggle(value, args) {
+ this.setState({
+ show: value,
+ post: args.post,
+ commentCount: args.commentCount,
+ error: ''
+ });
}
- componentWillUnmount() {
- PostStore.removeSelectedPostChangeListener(this.onListenerChange);
+
+ handleHide() {
+ this.setState({show: false});
}
+
onListenerChange() {
var newList = PostStore.getSelectedPost();
- if (!Utils.areObjectsEqual(this.state.selectedList, newList)) {
- this.setState({selectedList: newList});
+ if (!Utils.areObjectsEqual(this.selectedList, newList)) {
+ this.selectedList = newList;
}
}
+
render() {
+ if (!this.state.post) {
+ return null;
+ }
+
var error = null;
if (this.state.error) {
error = <div className='form-group has-error'><label className='control-label'>{this.state.error}</label></div>;
}
var commentWarning = '';
- if (this.state.comments > 0) {
- commentWarning = 'This post has ' + this.state.comments + ' comment(s) on it.';
+ if (this.state.commentCount > 0) {
+ commentWarning = 'This post has ' + this.state.commentCount + ' comment(s) on it.';
}
+ const postTerm = Utils.getPostTerm(this.state.post);
+
return (
- <div
- className='modal fade'
- id='delete_post'
- ref='modal'
- role='dialog'
- tabIndex='-1'
- aria-hidden='true'
+ <Modal
+ show={this.state.show}
+ onHide={this.handleHide}
>
- <div className='modal-dialog modal-push-down'>
- <div className='modal-content'>
- <div className='modal-header'>
- <button
- type='button'
- className='close'
- data-dismiss='modal'
- aria-label='Close'
- >
- <span aria-hidden='true'>&times;</span>
- </button>
- <h4 className='modal-title'>Confirm {this.state.title} Delete</h4>
- </div>
- <div className='modal-body'>
- Are you sure you want to delete the {this.state.title.toLowerCase()}?
- <br/>
- <br/>
+ <Modal.Header closeButton={true}>
+ {`Confirm ${postTerm} Delete`}
+ </Modal.Header>
+ <Modal.Body>
+ {`Are you sure you want to delete this ${postTerm.toLowerCase()}?`}
+ <br />
+ <br />
{commentWarning}
- </div>
- {error}
- <div className='modal-footer'>
+ {error}
+ </Modal.Body>
+ <Modal.Footer>
<button
type='button'
className='btn btn-default'
- data-dismiss='modal'
+ onClick={this.handleHide}
>
- Cancel
+ {'Cancel'}
</button>
<button
type='button'
className='btn btn-danger'
- data-dismiss='modal'
onClick={this.handleDelete}
>
- Delete
+ {'Delete'}
</button>
- </div>
- </div>
- </div>
- </div>
+ </Modal.Footer>
+ </Modal>
);
}
+
+ static show(post, commentCount) {
+ AppDispatcher.handleViewAction({
+ type: ActionTypes.TOGGLE_DELETE_POST_MODAL,
+ value: true,
+ post,
+ commentCount: commentCount || 0
+ });
+ }
}
diff --git a/web/react/components/edit_post_modal.jsx b/web/react/components/edit_post_modal.jsx
index ef32baa7d..c75da75c9 100644
--- a/web/react/components/edit_post_modal.jsx
+++ b/web/react/components/edit_post_modal.jsx
@@ -3,6 +3,7 @@
var Client = require('../utils/client.jsx');
var AsyncClient = require('../utils/async_client.jsx');
+var DeletePostModal = require('./delete_post_modal.jsx');
var Textbox = require('./textbox.jsx');
var BrowserStore = require('../stores/browser_store.jsx');
var PostStore = require('../stores/post_store.jsx');
@@ -34,7 +35,7 @@ export default class EditPostModal extends React.Component {
delete tempState.editText;
BrowserStore.setItem('edit_state_transfer', tempState);
$('#edit_post').modal('hide');
- $('#delete_post').modal('show');
+ DeletePostModal.show(PostStore.getPost(this.state.channel_id, this.state.post_id), this.state.comments);
return;
}
diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx
index a01d842e5..fffa5b19a 100644
--- a/web/react/components/post_info.jsx
+++ b/web/react/components/post_info.jsx
@@ -1,6 +1,7 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
+var DeletePostModal = require('./delete_post_modal.jsx');
var UserStore = require('../stores/user_store.jsx');
var utils = require('../utils/utils.jsx');
var TimeSince = require('./time_since.jsx');
@@ -50,7 +51,7 @@ export default class PostInfo extends React.Component {
data-channelid={post.channel_id}
data-comments={dataComments}
>
- Edit
+ {'Edit'}
</a>
</li>
);
@@ -65,14 +66,9 @@ export default class PostInfo extends React.Component {
<a
href='#'
role='menuitem'
- data-toggle='modal'
- data-target='#delete_post'
- data-title={type}
- data-postid={post.id}
- data-channelid={post.channel_id}
- data-comments={dataComments}
+ onClick={() => DeletePostModal.show(post, dataComments)}
>
- Delete
+ {'Delete'}
</a>
</li>
);
@@ -89,7 +85,7 @@ export default class PostInfo extends React.Component {
href='#'
onClick={this.props.handleCommentClick}
>
- Reply
+ {'Reply'}
</a>
</li>
);
diff --git a/web/react/components/rhs_comment.jsx b/web/react/components/rhs_comment.jsx
index 58cc1cac7..c16f9ff0e 100644
--- a/web/react/components/rhs_comment.jsx
+++ b/web/react/components/rhs_comment.jsx
@@ -8,6 +8,7 @@ var UserStore = require('../stores/user_store.jsx');
var AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
var Utils = require('../utils/utils.jsx');
var Constants = require('../utils/constants.jsx');
+var DeletePostModal = require('./delete_post_modal.jsx');
var FileAttachmentList = require('./file_attachment_list.jsx');
var Client = require('../utils/client.jsx');
var AsyncClient = require('../utils/async_client.jsx');
@@ -114,12 +115,7 @@ export default class RhsComment extends React.Component {
<a
href='#'
role='menuitem'
- data-toggle='modal'
- data-target='#delete_post'
- data-title='Comment'
- data-postid={post.id}
- data-channelid={post.channel_id}
- data-comments={0}
+ onClick={() => DeletePostModal.show(post, 0)}
>
{'Delete'}
</a>
diff --git a/web/react/components/rhs_root_post.jsx b/web/react/components/rhs_root_post.jsx
index 69de5d523..84fdc014a 100644
--- a/web/react/components/rhs_root_post.jsx
+++ b/web/react/components/rhs_root_post.jsx
@@ -6,6 +6,7 @@ var UserProfile = require('./user_profile.jsx');
var UserStore = require('../stores/user_store.jsx');
var TextFormatting = require('../utils/text_formatting.jsx');
var utils = require('../utils/utils.jsx');
+var DeletePostModal = require('./delete_post_modal.jsx');
var FileAttachmentList = require('./file_attachment_list.jsx');
var twemoji = require('twemoji');
var Constants = require('../utils/constants.jsx');
@@ -86,21 +87,16 @@ export default class RhsRootPost extends React.Component {
data-postid={post.id}
data-channelid={post.channel_id}
>
- Edit
+ {'Edit'}
</a>
</li>
<li role='presentation'>
<a
href='#'
role='menuitem'
- data-toggle='modal'
- data-target='#delete_post'
- data-title={type}
- data-postid={post.id}
- data-channelid={post.channel_id}
- data-comments={this.props.commentCount}
+ onClick={() => DeletePostModal.show(post, this.props.commentCount)}
>
- Delete
+ {'Delete'}
</a>
</li>
</ul>
diff --git a/web/react/stores/modal_store.jsx b/web/react/stores/modal_store.jsx
index dc65d48da..809f83a59 100644
--- a/web/react/stores/modal_store.jsx
+++ b/web/react/stores/modal_store.jsx
@@ -27,12 +27,14 @@ class ModalStoreClass extends EventEmitter {
}
handleEventPayload(payload) {
- const action = payload.action;
+ // toggle event handlers should accept a boolean show/hide value and can accept a map of arguments
+ const {type, value, ...args} = payload.action;
- switch (action.type) {
+ switch (type) {
case ActionTypes.TOGGLE_IMPORT_THEME_MODAL:
case ActionTypes.TOGGLE_INVITE_MEMBER_MODAL:
- this.emit(action.type, action.value);
+ case ActionTypes.TOGGLE_DELETE_POST_MODAL:
+ this.emit(type, value, args);
break;
}
}
diff --git a/web/react/stores/post_store.jsx b/web/react/stores/post_store.jsx
index 0fe253310..a564a2435 100644
--- a/web/react/stores/post_store.jsx
+++ b/web/react/stores/post_store.jsx
@@ -40,6 +40,7 @@ class PostStoreClass extends EventEmitter {
this.storePosts = this.storePosts.bind(this);
this.pStorePosts = this.pStorePosts.bind(this);
this.getPosts = this.getPosts.bind(this);
+ this.getPost = this.getPost.bind(this);
this.storePost = this.storePost.bind(this);
this.pStorePost = this.pStorePost.bind(this);
this.removePost = this.removePost.bind(this);
@@ -68,6 +69,7 @@ class PostStoreClass extends EventEmitter {
this.storeLatestUpdate = this.storeLatestUpdate.bind(this);
this.getLatestUpdate = this.getLatestUpdate.bind(this);
this.getCurrentUsersLatestPost = this.getCurrentUsersLatestPost.bind(this);
+ this.getCommentCount = this.getCommentCount.bind(this);
}
emitChange() {
this.emit(CHANGE_EVENT);
@@ -193,6 +195,9 @@ class PostStoreClass extends EventEmitter {
getPosts(channelId) {
return BrowserStore.getItem('posts_' + channelId);
}
+ getPost(channelId, postId) {
+ return this.getPosts(channelId).posts[postId];
+ }
getCurrentUsersLatestPost(channelId, rootId) {
const userId = UserStore.getCurrentId();
var postList = makePostListNonNull(this.getPosts(channelId));
@@ -402,6 +407,20 @@ class PostStoreClass extends EventEmitter {
getLatestUpdate(channelId) {
return BrowserStore.getItem('latest_post_' + channelId, 0);
}
+ getCommentCount(post) {
+ const posts = this.getPosts(post.channel_id).posts;
+
+ let commentCount = 0;
+ for (let id in posts) {
+ if (posts.hasOwnProperty(id)) {
+ if (posts[id].root_id === post.id) {
+ commentCount += 1;
+ }
+ }
+ }
+
+ return commentCount;
+ }
}
var PostStore = new PostStoreClass();
diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx
index 58ee8e2d2..6be87254f 100644
--- a/web/react/utils/constants.jsx
+++ b/web/react/utils/constants.jsx
@@ -40,7 +40,8 @@ module.exports = {
RECIEVED_ALL_TEAMS: null,
TOGGLE_IMPORT_THEME_MODAL: null,
- TOGGLE_INVITE_MEMBER_MODAL: null
+ TOGGLE_INVITE_MEMBER_MODAL: null,
+ TOGGLE_DELETE_POST_MODAL: null
}),
PayloadSources: keyMirror({
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index 77b3ecb57..5af837822 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -1232,3 +1232,12 @@ export function getChannelTerm(channelType) {
return channelTerm;
}
+
+export function getPostTerm(post) {
+ let postTerm = 'Post';
+ if (post.root_id) {
+ postTerm = 'Comment';
+ }
+
+ return postTerm;
+}