Skip to content

Commit

Permalink
Merge pull request #700 from coralproject/refactor-ban-suspend-actions
Browse files Browse the repository at this point in the history
Refactor and reuse "Actions" in "Moderate" and "Community"
  • Loading branch information
cvle authored Jun 23, 2017
2 parents 32b6627 + 4a5424b commit b805451
Show file tree
Hide file tree
Showing 40 changed files with 428 additions and 547 deletions.
7 changes: 7 additions & 0 deletions client/coral-admin/src/actions/banUserDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {SHOW_BAN_USER_DIALOG, HIDE_BAN_USER_DIALOG} from '../constants/banUserDialog';

export const showBanUserDialog = ({userId, username, commentId, commentStatus}) =>
({type: SHOW_BAN_USER_DIALOG, userId, username, commentId, commentStatus});

export const hideBanUserDialog = () => ({type: HIDE_BAN_USER_DIALOG});

10 changes: 5 additions & 5 deletions client/coral-admin/src/actions/community.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
SET_COMMENTER_STATUS,
SHOW_BANUSER_DIALOG,
HIDE_BANUSER_DIALOG,
SHOW_SUSPENDUSER_DIALOG,
HIDE_SUSPENDUSER_DIALOG
SHOW_REJECT_USERNAME_DIALOG,
HIDE_REJECT_USERNAME_DIALOG
} from '../constants/community';

import coralApi from '../../../coral-framework/helpers/request';
Expand Down Expand Up @@ -69,6 +69,6 @@ export const setCommenterStatus = (id, status) => (dispatch) => {
export const showBanUserDialog = (user) => ({type: SHOW_BANUSER_DIALOG, user});
export const hideBanUserDialog = () => ({type: HIDE_BANUSER_DIALOG});

// Suspend User Dialog
export const showSuspendUserDialog = (user) => ({type: SHOW_SUSPENDUSER_DIALOG, user});
export const hideSuspendUserDialog = () => ({type: HIDE_SUSPENDUSER_DIALOG});
// Reject Username Dialog
export const showRejectUsernameDialog = (user) => ({type: SHOW_REJECT_USERNAME_DIALOG, user});
export const hideRejectUsernameDialog = () => ({type: HIDE_REJECT_USERNAME_DIALOG});
10 changes: 0 additions & 10 deletions client/coral-admin/src/actions/moderation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@ import * as actions from 'constants/moderation';
export const toggleModal = (open) => ({type: actions.TOGGLE_MODAL, open});
export const singleView = () => ({type: actions.SINGLE_VIEW});

// Ban User Dialog
export const showBanUserDialog = (user, commentId, commentStatus, showRejectedNote) => ({type: actions.SHOW_BANUSER_DIALOG, user, commentId, commentStatus, showRejectedNote});
export const hideBanUserDialog = () => ({type: actions.HIDE_BANUSER_DIALOG});

// Suspend User Dialog
export const showSuspendUserDialog = (userId, username, commentId, commentStatus) =>
({type: actions.SHOW_SUSPEND_USER_DIALOG, userId, username, commentId, commentStatus});

export const hideSuspendUserDialog = () => ({type: actions.HIDE_SUSPEND_USER_DIALOG});

// hide shortcuts note
export const hideShortcutsNote = () => {
try {
Expand Down
7 changes: 7 additions & 0 deletions client/coral-admin/src/actions/suspendUserDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {SHOW_SUSPEND_USER_DIALOG, HIDE_SUSPEND_USER_DIALOG} from '../constants/suspendUserDialog.js';

export const showSuspendUserDialog = ({userId, username, commentId, commentStatus}) =>
({type: SHOW_SUSPEND_USER_DIALOG, userId, username, commentId, commentStatus});

export const hideSuspendUserDialog = () => ({type: HIDE_SUSPEND_USER_DIALOG});

44 changes: 44 additions & 0 deletions client/coral-admin/src/components/BanUserDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, {PropTypes} from 'react';
import {Dialog} from 'coral-ui';
import styles from './BanUserDialog.css';

import Button from 'coral-ui/components/Button';
import t from 'coral-framework/services/i18n';

const BanUserDialog = ({open, onCancel, onPerform, username, info}) => (
<Dialog
className={styles.dialog}
id="banUserDialog"
open={open}
onCancel={onCancel}
title={t('bandialog.ban_user')}>
<span className={styles.close} onClick={onCancel}>×</span>
<div>
<div className={styles.header}>
<h2>{t('bandialog.ban_user')}</h2>
</div>
<div className={styles.separator}>
<h3>{t('bandialog.are_you_sure', username)}</h3>
<i>{info}</i>
</div>
<div className={styles.buttons}>
<Button cStyle="cancel" className={styles.cancel} onClick={onCancel} raised>
{t('bandialog.cancel')}
</Button>
<Button cStyle="black" className={styles.ban} onClick={onPerform} raised>
{t('bandialog.yes_ban_user')}
</Button>
</div>
</div>
</Dialog>
);

BanUserDialog.propTypes = {
open: PropTypes.bool,
onPerform: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired,
username: PropTypes.string,
info: PropTypes.string,
};

export default BanUserDialog;
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ class SuspendUserDialog extends React.Component {
handlePerform = () => {

this.props.onPerform({
id: this.props.userId,
message: this.state.message,

// Add 1 minute more to help `timeago.js` to display the correct duration.
Expand Down Expand Up @@ -153,11 +152,10 @@ class SuspendUserDialog extends React.Component {

SuspendUserDialog.propTypes = {
open: PropTypes.bool.isRequired,
onCancel: PropTypes.func.isRequired,
onPerform: PropTypes.func.isRequired,
username: PropTypes.string,
userId: PropTypes.string,
onCancel: PropTypes.func.isRequired,
organizationName: PropTypes.string,
username: PropTypes.string,
};

export default SuspendUserDialog;
2 changes: 2 additions & 0 deletions client/coral-admin/src/constants/banUserDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const SHOW_BAN_USER_DIALOG = 'SHOW_BAN_USER_DIALOG';
export const HIDE_BAN_USER_DIALOG = 'HIDE_BAN_USER_DIALOG';
4 changes: 2 additions & 2 deletions client/coral-admin/src/constants/community.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ export const FETCH_FLAGGED_COMMENTERS_FAILURE = 'FETCH_FLAGGED_COMMENTERS_FAILUR
export const SHOW_BANUSER_DIALOG = 'SHOW_BANUSER_DIALOG';
export const HIDE_BANUSER_DIALOG = 'HIDE_BANUSER_DIALOG';

export const SHOW_SUSPENDUSER_DIALOG = 'SHOW_SUSPENDUSER_DIALOG';
export const HIDE_SUSPENDUSER_DIALOG = 'HIDE_SUSPENDUSER_DIALOG';
export const SHOW_REJECT_USERNAME_DIALOG = 'SHOW_REJECT_USERNAME_DIALOG';
export const HIDE_REJECT_USERNAME_DIALOG = 'HIDE_REJECT_USERNAME_DIALOG';
4 changes: 0 additions & 4 deletions client/coral-admin/src/constants/moderation.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
export const TOGGLE_MODAL = 'TOGGLE_MODAL';
export const SINGLE_VIEW = 'SINGLE_VIEW';
export const SHOW_BANUSER_DIALOG = 'SHOW_BANUSER_DIALOG';
export const HIDE_BANUSER_DIALOG = 'HIDE_BANUSER_DIALOG';
export const HIDE_SHORTCUTS_NOTE = 'HIDE_SHORTCUTS_NOTE';
export const SHOW_SUSPEND_USER_DIALOG = 'SHOW_SUSPEND_USER_DIALOG';
export const HIDE_SUSPEND_USER_DIALOG = 'HIDE_SUSPEND_USER_DIALOG';
export const VIEW_USER_DETAIL = 'VIEW_USER_DETAIL';
export const HIDE_USER_DETAIL = 'HIDE_USER_DETAIL';
export const SET_SORT_ORDER = 'MODERATION_SET_SORT_ORDER';
Expand Down
2 changes: 2 additions & 0 deletions client/coral-admin/src/constants/suspendUserDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const SHOW_SUSPEND_USER_DIALOG = 'SHOW_SUSPEND_USER_DIALOG';
export const HIDE_SUSPEND_USER_DIALOG = 'HIDE_SUSPEND_USER_DIALOG';
63 changes: 63 additions & 0 deletions client/coral-admin/src/containers/BanUserDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import BanUserDialog from '../components/BanUserDialog';
import {hideBanUserDialog} from '../actions/banUserDialog';
import {withSetUserStatus, withSetCommentStatus} from 'coral-framework/graphql/mutations';
import {compose} from 'react-apollo';
import t from 'coral-framework/services/i18n';

class BanUserDialogContainer extends Component {

banUser = async () => {
const {userId, commentId, commentStatus, setUserStatus, setCommentStatus, hideBanUserDialog} = this.props;
await setUserStatus({userId, status: 'BANNED'});
hideBanUserDialog();
if (commentId && commentStatus && commentStatus !== 'REJECTED') {
await setCommentStatus({commentId, status: 'REJECTED'});
}
}

getInfo() {
let note = t('bandialog.note_ban_user');
if (this.props.commentStatus && this.props.commentStatus !== 'REJECTED') {
note = t('bandialog.note_reject_comment');
}
return t('bandialog.note', note);
}

render() {
return (
<BanUserDialog
open={this.props.open}
onPerform={this.banUser}
onCancel={this.props.hideBanUserDialog}
username={this.props.username}
info={this.getInfo()}
/>
);
}
}

const mapStateToProps = ({banUserDialog: {open, userId, username, commentId, commentStatus}}) => ({
open,
userId,
username,
commentId,
commentStatus,
});

const mapDispatchToProps = (dispatch) => ({
...bindActionCreators({
hideBanUserDialog,
}, dispatch),
});

export default compose(
withSetUserStatus,
withSetCommentStatus,
connect(
mapStateToProps,
mapDispatchToProps,
),
)(BanUserDialogContainer);
8 changes: 7 additions & 1 deletion client/coral-admin/src/containers/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {fetchConfig} from '../actions/config';
import AdminLogin from '../components/AdminLogin';
import {logout} from 'coral-framework/actions/auth';
import {FullLoading} from '../components/FullLoading';
import BanUserDialog from './BanUserDialog';
import SuspendUserDialog from './SuspendUserDialog';
import {toggleModal as toggleShortcutModal} from '../actions/moderation';
import {checkLogin, handleLogin, requestPasswordReset} from '../actions/auth';
import {can} from 'coral-framework/services/perms';
Expand Down Expand Up @@ -52,7 +54,11 @@ class LayoutContainer extends Component {
handleLogout={handleLogout}
toggleShortcutModal={toggleShortcutModal}
{...this.props}
/>
>
<BanUserDialog />
<SuspendUserDialog />
{this.props.children}
</Layout>
);
} else if (loggedIn) {
return (
Expand Down
83 changes: 83 additions & 0 deletions client/coral-admin/src/containers/SuspendUserDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import SuspendUserDialog from '../components/SuspendUserDialog';
import {hideSuspendUserDialog} from '../actions/suspendUserDialog';
import {withSetCommentStatus, withSuspendUser} from 'coral-framework/graphql/mutations';
import {compose, gql} from 'react-apollo';
import * as notification from 'coral-admin/src/services/notification';
import t, {timeago} from 'coral-framework/services/i18n';
import withQuery from 'coral-framework/hocs/withQuery';
import get from 'lodash/get';

class SuspendUserDialogContainer extends Component {

suspendUser = async ({message, until}) => {
const {userId, username, commentStatus, commentId, hideSuspendUserDialog, setCommentStatus, suspendUser} = this.props;
hideSuspendUserDialog();
try {
const result = await suspendUser({id: userId, message, until});
if (result.data.suspendUser.errors) {
throw result.data.suspendUser.errors;
}
notification.success(
t('suspenduser.notify_suspend_until', username, timeago(until)),
);
if (commentId && commentStatus && commentStatus !== 'REJECTED') {
return setCommentStatus({commentId, status: 'REJECTED'})
.then((result) => {
if (result.data.setCommentStatus.errors) {
throw result.data.setCommentStatus.errors;
}
});
}
}
catch(err) {
notification.showMutationErrors(err);
}
};

render() {
return (
<SuspendUserDialog
open={this.props.open}
onPerform={this.suspendUser}
onCancel={this.props.hideSuspendUserDialog}
organizationName={get(this.props, 'root.settings.organizationName')}
username={this.props.username}
/>
);
}
}

const withOrganizationName = withQuery(gql`
query CoralAdmin_SuspendUserDialog {
settings {
organizationName
}
}
`);

const mapStateToProps = ({suspendUserDialog: {open, userId, username, commentId, commentStatus}}) => ({
open,
userId,
username,
commentId,
commentStatus,
});

const mapDispatchToProps = (dispatch) => ({
...bindActionCreators({
hideSuspendUserDialog,
}, dispatch),
});

export default compose(
connect(
mapStateToProps,
mapDispatchToProps,
),
withSuspendUser,
withSetCommentStatus,
withOrganizationName,
)(SuspendUserDialogContainer);
30 changes: 30 additions & 0 deletions client/coral-admin/src/reducers/banUserDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {SHOW_BAN_USER_DIALOG, HIDE_BAN_USER_DIALOG} from '../constants/banUserDialog';

const initialState = {
open: false,
userId: null,
username: '',
commentId: null,
commentStatus: '',
};

export default function banUserDialog(state = initialState, action) {
switch (action.type) {
case SHOW_BAN_USER_DIALOG:
return {
...state,
open: true,
userId: action.userId,
username: action.username,
commentId: action.commentId,
commentStatus: action.commentStatus,
};
case HIDE_BAN_USER_DIALOG:
return {
...state,
open: false,
};
default:
return state;
}
}
14 changes: 7 additions & 7 deletions client/coral-admin/src/reducers/community.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
SET_COMMENTER_STATUS,
SHOW_BANUSER_DIALOG,
HIDE_BANUSER_DIALOG,
SHOW_SUSPENDUSER_DIALOG,
HIDE_SUSPENDUSER_DIALOG
SHOW_REJECT_USERNAME_DIALOG,
HIDE_REJECT_USERNAME_DIALOG
} from '../constants/community';

const initialState = Map({
Expand All @@ -24,7 +24,7 @@ const initialState = Map({
pagePeople: 0,
user: Map({}),
banDialog: false,
suspendDialog: false
rejectUsernameDialog: false
});

export default function community (state = initialState, action) {
Expand Down Expand Up @@ -79,14 +79,14 @@ export default function community (state = initialState, action) {
user: Map(action.user),
banDialog: true
});
case HIDE_SUSPENDUSER_DIALOG:
case HIDE_REJECT_USERNAME_DIALOG:
return state
.set('suspendDialog', false);
case SHOW_SUSPENDUSER_DIALOG:
.set('rejectUsernameDialog', false);
case SHOW_REJECT_USERNAME_DIALOG:
return state
.merge({
user: Map(action.user),
suspendDialog: true
rejectUsernameDialog: true
});
default :
return state;
Expand Down
4 changes: 4 additions & 0 deletions client/coral-admin/src/reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import community from './community';
import moderation from './moderation';
import install from './install';
import config from './config';
import banUserDialog from './banUserDialog';
import suspendUserDialog from './suspendUserDialog';

export default {
auth,
banUserDialog,
suspendUserDialog,
assets,
settings,
community,
Expand Down
Loading

0 comments on commit b805451

Please sign in to comment.