Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
Migrate delete_post_modal.jsx to be pure and use Redux (#989)
Browse files Browse the repository at this point in the history
* Migrate DeletePostModal to be pure and use Redux

Migrate DeletePostModal to be pure and use Redux

* Fix styling problem

* Changes based on reviews

* Removed old post action

Added some functionality from the old action to the component

* Remove unused imports from post_actions

* Add browserhistory test

Clean up test baseProps
Pass teamname instead of team object

* Fix styling problem
  • Loading branch information
JasperVanEsveld authored and jwilander committed Mar 23, 2018
1 parent 5c2d636 commit bc48cd4
Show file tree
Hide file tree
Showing 17 changed files with 498 additions and 141 deletions.
10 changes: 0 additions & 10 deletions actions/global_actions.jsx
Expand Up @@ -188,16 +188,6 @@ export function toggleShortcutsModal() {
});
}

export function showDeletePostModal(post, commentCount = 0, isRHS) {
AppDispatcher.handleViewAction({
type: ActionTypes.TOGGLE_DELETE_POST_MODAL,
value: true,
isRHS,
post,
commentCount,
});
}

export function showChannelHeaderUpdateModal(channel) {
AppDispatcher.handleViewAction({
type: ActionTypes.TOGGLE_CHANNEL_HEADER_UPDATE_MODAL,
Expand Down
44 changes: 1 addition & 43 deletions actions/post_actions.jsx
Expand Up @@ -8,16 +8,14 @@ import * as PostActions from 'mattermost-redux/actions/posts';
import * as Selectors from 'mattermost-redux/selectors/entities/posts';
import {comparePosts} from 'mattermost-redux/utils/post_utils';

import {browserHistory} from 'utils/browser_history';
import {sendDesktopNotification} from 'actions/notification_actions.jsx';
import {loadNewDMIfNeeded, loadNewGMIfNeeded} from 'actions/user_actions.jsx';
import * as RhsActions from 'actions/views/rhs';
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import PostStore from 'stores/post_store.jsx';
import store from 'stores/redux_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import {getSelectedPostId, getRhsState} from 'selectors/rhs';
import {getRhsState} from 'selectors/rhs';
import {ActionTypes, Constants, RHSStates} from 'utils/constants.jsx';
import {EMOJI_PATTERN} from 'utils/emoticons.jsx';
import * as UserAgent from 'utils/user_agent';
Expand Down Expand Up @@ -202,46 +200,6 @@ export function emitEmojiPosted(emoji) {
});
}

export async function deletePost(channelId, post, success) {
const {currentUserId} = getState().entities.users;

let hardDelete = false;
if (post.user_id === currentUserId) {
hardDelete = true;
}

await PostActions.deletePost(post, hardDelete)(dispatch, getState);

if (post.id === getSelectedPostId(getState())) {
dispatch({
type: ActionTypes.SELECT_POST,
postId: '',
channelId: '',
});
}

dispatch({
type: PostTypes.REMOVE_POST,
data: post,
});

// Needed for search store
AppDispatcher.handleViewAction({
type: Constants.ActionTypes.REMOVE_POST,
post,
});

const {focusedPostId} = getState().views.channel;
const channel = getState().entities.channels.channels[post.channel_id];
if (post.id === focusedPostId && channel) {
browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/channels/' + channel.name);
}

if (success) {
success();
}
}

const POST_INCREASE_AMOUNT = Constants.POST_CHUNK_SIZE / 2;

// Returns true if there are more posts to load
Expand Down
2 changes: 0 additions & 2 deletions components/channel_layout/channel_controller.jsx
Expand Up @@ -7,7 +7,6 @@ import {Route} from 'react-router-dom';

import Pluggable from 'plugins/pluggable';
import AnnouncementBar from 'components/announcement_bar';
import DeletePostModal from 'components/delete_post_modal.jsx';
import EditPostModal from 'components/edit_post_modal';
import GetPostLinkModal from 'components/get_post_link_modal';
import GetTeamInviteLinkModal from 'components/get_team_invite_link_modal';
Expand Down Expand Up @@ -64,7 +63,6 @@ export default class ChannelController extends React.Component {
<ImportThemeModal/>
<TeamSettingsModal/>
<EditPostModal/>
<DeletePostModal/>
<RemovedFromChannelModal/>
<ResetStatusModal/>
<LeavePrivateChannelModal/>
Expand Down
@@ -1,106 +1,102 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import PropTypes from 'prop-types';
import React from 'react';
import {Modal} from 'react-bootstrap';
import {FormattedMessage} from 'react-intl';

import {deletePost} from 'actions/post_actions.jsx';
import ModalStore from 'stores/modal_store.jsx';
import Constants from 'utils/constants.jsx';
import {browserHistory} from 'utils/browser_history';
import * as UserAgent from 'utils/user_agent.jsx';

var ActionTypes = Constants.ActionTypes;
export default class DeletePostModal extends React.PureComponent {
static propTypes = {

channelName: PropTypes.string,
focusedPostId: PropTypes.string,
teamName: PropTypes.string,
post: PropTypes.object.isRequired,
commentCount: PropTypes.number.isRequired,

/**
* Does the post come from RHS mode
*/
isRHS: PropTypes.bool.isRequired,

/**
* Function called when modal is dismissed
*/
onHide: PropTypes.func.isRequired,

actions: PropTypes.shape({

/**
* Function called for deleting post
*/
deletePost: PropTypes.func.isRequired,
}),
}

export default class DeletePostModal extends React.Component {
constructor(props) {
super(props);

this.handleDelete = this.handleDelete.bind(this);
this.onHide = this.onHide.bind(this);
this.state = {
show: false,
post: null,
commentCount: 0,
error: '',
show: true,
};
}

componentDidMount() {
ModalStore.addModalListener(ActionTypes.TOGGLE_DELETE_POST_MODAL, this.handleToggle);
}
handleDelete = async () => {
const {
actions,
channelName,
focusedPostId,
post,
teamName,
} = this.props;

componentWillUnmount() {
ModalStore.removeModalListener(ActionTypes.TOGGLE_DELETE_POST_MODAL, this.handleToggle);
}
const {data} = await actions.deletePost(post);

componentDidUpdate(prevProps, prevState) {
if (this.state.show && !prevState.show) {
setTimeout(() => {
if (this.deletePostBtn) {
this.deletePostBtn.focus();
}
}, 200);
if (post.id === focusedPostId && channelName) {
browserHistory.push('/' + teamName + '/channels/' + channelName);
}
}

handleDelete = () => {
deletePost(
this.state.post.channel_id,
this.state.post,
() => {
this.handleHide();
},
(err) => {
this.setState({error: err.message});
}
);
}

handleToggle = (value, args) => {
this.setState({
show: value,
post: args.post,
isRHS: args.isRHS,
commentCount: args.commentCount,
error: '',
});
if (data) {
this.onHide();
}
}

handleHide = () => {
onHide() {
this.setState({show: false});

if (!UserAgent.isMobile()) {
if (this.state.isRHS) {
document.getElementById('reply_textbox').focus();
var element;
if (this.props.isRHS) {
element = document.getElementById('reply_textbox');
} else {
document.getElementById('post_textbox').focus();
element = document.getElementById('post_textbox');
}
if (element) {
element.focus();
}
}
}

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.commentCount > 0) {
if (this.props.commentCount > 0) {
commentWarning = (
<FormattedMessage
id='delete_post.warning'
defaultMessage='This post has {count, number} {count, plural, one {comment} other {comments}} on it.'
values={{
count: this.state.commentCount,
count: this.props.commentCount,
}}
/>
);
}

const postTerm = this.state.post.root_id ? (
const postTerm = this.props.post.root_id ? (
<FormattedMessage
id='delete_post.comment'
defaultMessage='Comment'
Expand All @@ -115,7 +111,8 @@ export default class DeletePostModal extends React.Component {
return (
<Modal
show={this.state.show}
onHide={this.handleHide}
onHide={this.onHide}
onExited={this.props.onHide}
enforceFocus={false}
>
<Modal.Header closeButton={true}>
Expand All @@ -140,7 +137,6 @@ export default class DeletePostModal extends React.Component {
<br/>
<br/>
{commentWarning}
{error}
</Modal.Body>
<Modal.Footer>
<button
Expand Down
36 changes: 36 additions & 0 deletions components/delete_post_modal/index.js
@@ -0,0 +1,36 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {deletePost} from 'mattermost-redux/actions/posts';
import {getChannel} from 'mattermost-redux/selectors/entities/channels';
import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams';

import DeletePostModal from './delete_post_modal.jsx';

function mapStateToProps(state, ownProps) {
const channel = getChannel(state, ownProps.post.channel_id);
let channelName = '';
if (channel) {
channelName = channel.name;
}

const {focusedPostId} = state.views.channel;

return {
channelName,
focusedPostId,
teamName: getCurrentTeam(state).name,
};
}

function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
deletePost,
}, dispatch),
};
}

export default connect(mapStateToProps, mapDispatchToProps)(DeletePostModal);
20 changes: 14 additions & 6 deletions components/dot_menu/dot_menu.jsx
Expand Up @@ -27,30 +27,35 @@ export default class DotMenu extends Component {

actions: PropTypes.shape({

/*
/**
* Function flag the post
*/
flagPost: PropTypes.func.isRequired,

/*
/**
* Function to unflag the post
*/
unflagPost: PropTypes.func.isRequired,

/*
* Function to set the edting post
/**
* Function to set the editing post
*/
setEditingPost: PropTypes.func.isRequired,

/*
/**
* Function to pin the post
*/
pinPost: PropTypes.func.isRequired,

/*
/**
* Function to unpin the post
*/
unpinPost: PropTypes.func.isRequired,

/**
* Function to open a modal
*/
openModal: PropTypes.func.isRequired,
}).isRequired,
}

Expand Down Expand Up @@ -185,6 +190,9 @@ export default class DotMenu extends Component {
idCount={this.props.idCount}
post={this.props.post}
commentCount={type === 'Post' ? this.props.commentCount : 0}
actions={{
openModal: this.props.actions.openModal,
}}
/>
);
}
Expand Down

0 comments on commit bc48cd4

Please sign in to comment.