diff --git a/plugin-api/beta/client/hocs/index.js b/plugin-api/beta/client/hocs/index.js index d6d5a67a0..1359143e1 100644 --- a/plugin-api/beta/client/hocs/index.js +++ b/plugin-api/beta/client/hocs/index.js @@ -7,6 +7,7 @@ export {default as connect} from 'coral-framework/hocs/connect'; export {default as withEmit} from 'coral-framework/hocs/withEmit'; export { withIgnoreUser, + withSetUserStatus, withStopIgnoringUser, withSetCommentStatus, } from 'coral-framework/graphql/mutations'; diff --git a/plugins/talk-plugin-moderation-actions/client/actions.js b/plugins/talk-plugin-moderation-actions/client/actions.js index de4714d21..6e87f94ca 100644 --- a/plugins/talk-plugin-moderation-actions/client/actions.js +++ b/plugins/talk-plugin-moderation-actions/client/actions.js @@ -1,4 +1,4 @@ -import {OPEN_MENU, CLOSE_MENU} from './constants'; +import {OPEN_MENU, CLOSE_MENU, OPEN_BAN_DIALOG, CLOSE_BAN_DIALOG} from './constants'; export const openMenu = (id) => ({ type: OPEN_MENU, @@ -8,3 +8,14 @@ export const openMenu = (id) => ({ export const closeMenu = () => ({ type: CLOSE_MENU, }); + +export const openBanDialog = ({commentId, authorId, commentStatus}) => ({ + type: OPEN_BAN_DIALOG, + commentId, + authorId, + commentStatus +}); + +export const closeBanDialog = () => ({ + type: CLOSE_BAN_DIALOG, +}); diff --git a/plugins/talk-plugin-moderation-actions/client/components/BanUserAction.js b/plugins/talk-plugin-moderation-actions/client/components/BanUserAction.js new file mode 100644 index 000000000..36f9b1489 --- /dev/null +++ b/plugins/talk-plugin-moderation-actions/client/components/BanUserAction.js @@ -0,0 +1,14 @@ +import React from 'react'; +import styles from './styles.css'; +import {t} from 'plugin-api/beta/client/services'; +import {Icon} from 'plugin-api/beta/client/components/ui'; +import cn from 'classnames'; + +export default ({onBanUser}) => ( + +); diff --git a/plugins/talk-plugin-moderation-actions/client/components/BanUserDialog.css b/plugins/talk-plugin-moderation-actions/client/components/BanUserDialog.css new file mode 100644 index 000000000..96151228c --- /dev/null +++ b/plugins/talk-plugin-moderation-actions/client/components/BanUserDialog.css @@ -0,0 +1,38 @@ +.dialog { + border: none; + box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2); +} + +.buttons { + text-align: right; + margin: 20px; + text-align: center; +} + +.cancel, .confirm { + width: 48%; +} + +.cancel { + margin-right: 10px; +} + +.copy { + font-style: italic; +} + +.close { + font-size: 20px; + line-height: 14px; + top: 10px; + right: 10px; + position: absolute; + display: block; + font-weight: bold; + color: #363636; + cursor: pointer; +} + +.close:hover { + color: #6b6b6b; +} \ No newline at end of file diff --git a/plugins/talk-plugin-moderation-actions/client/components/BanUserDialog.js b/plugins/talk-plugin-moderation-actions/client/components/BanUserDialog.js new file mode 100644 index 000000000..702ee4b10 --- /dev/null +++ b/plugins/talk-plugin-moderation-actions/client/components/BanUserDialog.js @@ -0,0 +1,23 @@ +import React from 'react'; +import styles from './BanUserDialog.css'; +import {t} from 'plugin-api/beta/client/services'; +import {Dialog, Button} from 'plugin-api/beta/client/components/ui'; + +export default ({showBanDialog, closeBanDialog, banUser}) => ( + + × +

{t('talk-plugin-moderation-actions.ban_user_dialog_headline')}

+

{t('talk-plugin-moderation-actions.ban_user_dialog_sub')}

+

+ {t('talk-plugin-moderation-actions.ban_user_dialog_copy')} +

+
+ + +
+
+); diff --git a/plugins/talk-plugin-moderation-actions/client/components/ModerationActions.js b/plugins/talk-plugin-moderation-actions/client/components/ModerationActions.js index a4a753d60..fa12500de 100644 --- a/plugins/talk-plugin-moderation-actions/client/components/ModerationActions.js +++ b/plugins/talk-plugin-moderation-actions/client/components/ModerationActions.js @@ -6,11 +6,12 @@ import {Icon} from 'plugin-api/beta/client/components/ui'; import ClickOutside from 'coral-framework/components/ClickOutside'; import RejectCommentAction from '../containers/RejectCommentAction'; import ApproveCommentAction from '../containers/ApproveCommentAction'; +import BanUserAction from '../containers/BanUserAction'; import {Slot} from 'plugin-api/beta/client/components'; export default class ModerationActions extends React.Component { render() { - const {comment, asset, data, menuVisible, toogleMenu, hideMenu} = this.props; + const {comment, root, asset, data, menuVisible, toogleMenu, hideMenu} = this.props; return( @@ -29,6 +30,7 @@ export default class ModerationActions extends React.Component { /> + )} diff --git a/plugins/talk-plugin-moderation-actions/client/constants.js b/plugins/talk-plugin-moderation-actions/client/constants.js index de3d5c909..36523affd 100644 --- a/plugins/talk-plugin-moderation-actions/client/constants.js +++ b/plugins/talk-plugin-moderation-actions/client/constants.js @@ -2,3 +2,5 @@ const prefix = 'TALK_MODERATION_ACTIONS'; export const OPEN_MENU = `${prefix}_OPEN_MENU`; export const CLOSE_MENU = `${prefix}_CLOSE_MENU`; +export const OPEN_BAN_DIALOG = `${prefix}_OPEN_BAN_DIALOG`; +export const CLOSE_BAN_DIALOG = `${prefix}_CLOSE_BAN_DIALOG`; diff --git a/plugins/talk-plugin-moderation-actions/client/containers/BanUserAction.js b/plugins/talk-plugin-moderation-actions/client/containers/BanUserAction.js new file mode 100644 index 000000000..1e2f1925d --- /dev/null +++ b/plugins/talk-plugin-moderation-actions/client/containers/BanUserAction.js @@ -0,0 +1,36 @@ +import React from 'react'; +import {compose} from 'react-apollo'; +import {openBanDialog} from '../actions'; +import {bindActionCreators} from 'redux'; +import BanUserAction from '../components/BanUserAction'; +import {connect} from 'plugin-api/beta/client/hocs'; + +class BanUserActionContainer extends React.Component { + onBanUser = () => { + this.props.openBanDialog({ + commentId: this.props.comment.id, + commentStatus: this.props.comment.status, + authorId: this.props.comment.user.id + }); + } + + render() { + const {root: {me}, comment} = this.props; + return (me.id !== comment.user.id) ? + : null; + } +} + +const mapDispatchToProps = (dispatch) => + bindActionCreators({ + openBanDialog + }, dispatch); + +const enhance = compose( + connect(null, mapDispatchToProps) +); + +export default enhance(BanUserActionContainer); diff --git a/plugins/talk-plugin-moderation-actions/client/containers/BanUserDialog.js b/plugins/talk-plugin-moderation-actions/client/containers/BanUserDialog.js new file mode 100644 index 000000000..2c081580a --- /dev/null +++ b/plugins/talk-plugin-moderation-actions/client/containers/BanUserDialog.js @@ -0,0 +1,76 @@ + +import React from 'react'; +import {compose} from 'react-apollo'; +import {bindActionCreators} from 'redux'; +import {closeBanDialog, closeMenu} from '../actions'; +import {notify} from 'plugin-api/beta/client/actions/notification'; +import {connect, withSetCommentStatus, withSetUserStatus} from 'plugin-api/beta/client/hocs'; +import {getErrorMessages} from 'plugin-api/beta/client/utils'; +import BanUserDialog from '../components/BanUserDialog'; + +class BanUserDialogContainer extends React.Component { + + banUser = async () => { + const { + notify, + authorId, + commentId, + commentStatus, + closeMenu, + closeBanDialog, + setCommentStatus, + setUserStatus + } = this.props; + + try { + await setUserStatus({ + userId: authorId, + status: 'BANNED' + }); + + closeMenu(); + closeBanDialog(); + + if (commentStatus !== 'REJECTED') { + await setCommentStatus({ + commentId: commentId, + status: 'REJECTED' + }); + } + } + catch(err) { + notify('error', getErrorMessages(err)); + } + } + + render() { + return ( + + ); + } +} + +const mapStateToProps = ({talkPluginModerationActions: state}) => ({ + showBanDialog: state.showBanDialog, + commentId: state.commentId, + authorId: state.authorId +}); + +const mapDispatchToProps = (dispatch) => + bindActionCreators({ + notify, + closeBanDialog, + closeMenu + }, dispatch); + +const enhance = compose( + connect(mapStateToProps, mapDispatchToProps), + withSetCommentStatus, + withSetUserStatus +); + +export default enhance(BanUserDialogContainer); diff --git a/plugins/talk-plugin-moderation-actions/client/containers/ModerationActions.js b/plugins/talk-plugin-moderation-actions/client/containers/ModerationActions.js index 984c7f57a..80df3fc2a 100644 --- a/plugins/talk-plugin-moderation-actions/client/containers/ModerationActions.js +++ b/plugins/talk-plugin-moderation-actions/client/containers/ModerationActions.js @@ -47,9 +47,9 @@ class ModerationActionsContainer extends React.Component { root={this.props.root} asset={this.props.asset} comment={this.props.comment} - menuVisible={this.props.showMenuForComment === this.props.comment.id} toogleMenu={this.toogleMenu} hideMenu={this.hideMenu} + menuVisible={this.props.showMenuForComment === this.props.comment.id} />; } } @@ -68,6 +68,13 @@ const mapDispatchToProps = (dispatch) => const enhance = compose( connect(mapStateToProps, mapDispatchToProps), withFragments({ + root: gql` + fragment TalkModerationActions_root on RootQuery { + me { + id + } + }` + , asset: gql` fragment TalkModerationActions_asset on Asset { id @@ -77,6 +84,9 @@ const enhance = compose( fragment TalkModerationActions_comment on Comment { id status + user { + id + } tags { tag { name diff --git a/plugins/talk-plugin-moderation-actions/client/index.js b/plugins/talk-plugin-moderation-actions/client/index.js index fefcac710..c4d3a0dfc 100644 --- a/plugins/talk-plugin-moderation-actions/client/index.js +++ b/plugins/talk-plugin-moderation-actions/client/index.js @@ -1,9 +1,11 @@ import ModerationActions from './containers/ModerationActions'; +import BanUserDialog from './containers/BanUserDialog'; import translations from './translations.yml'; import reducer from './reducer'; export default { slots: { + embed: [BanUserDialog], commentInfoBar: [ModerationActions], }, reducer, diff --git a/plugins/talk-plugin-moderation-actions/client/reducer.js b/plugins/talk-plugin-moderation-actions/client/reducer.js index d8531708b..b2ace4d85 100644 --- a/plugins/talk-plugin-moderation-actions/client/reducer.js +++ b/plugins/talk-plugin-moderation-actions/client/reducer.js @@ -1,7 +1,11 @@ -import {OPEN_MENU, CLOSE_MENU} from './constants'; +import {OPEN_MENU, CLOSE_MENU, OPEN_BAN_DIALOG, CLOSE_BAN_DIALOG} from './constants'; const initialState = { showMenuForComment: null, + showBanDialog: false, + authorId: null, + commentId: null, + commentStatus: null }; export default function reducer(state = initialState, action) { @@ -16,6 +20,22 @@ export default function reducer(state = initialState, action) { ...state, showMenuForComment: null }; + case OPEN_BAN_DIALOG: + return { + ...state, + showBanDialog: true, + authorId: action.authorId, + commentId: action.commentId, + commentStatus: action.commentStatus + }; + case CLOSE_BAN_DIALOG: + return { + ...state, + showBanDialog: false, + authorId: null, + commentId: null, + commentStatus: null + }; default : return state; } diff --git a/plugins/talk-plugin-moderation-actions/client/translations.yml b/plugins/talk-plugin-moderation-actions/client/translations.yml index 425c917f3..83fae6e4c 100644 --- a/plugins/talk-plugin-moderation-actions/client/translations.yml +++ b/plugins/talk-plugin-moderation-actions/client/translations.yml @@ -4,9 +4,22 @@ en: approve_comment: "Approve" approved_comment: "Approved" moderation_actions: "Moderation Actions" + ban_user: "Ban User" + ban_user_dialog_sub: "Are you sure you would like to ban this user?" + ban_user_dialog_copy: "Note: Banning this user will also place this comment in the Rejected queue." + ban_user_dialog_cancel: "Cancel" + ban_user_dialog_yes: "Yes. Ban user" + ban_user_dialog_headline: "Ban User?" + es: talk-plugin-moderation-actions: reject_comment: "Rechazar" approve_comment: "Aprobar" approved_comment: "Aprobado" - moderation_actions: "Acciones de Moderación" \ No newline at end of file + moderation_actions: "Acciones de Moderación" + ban_user: "Banear usuario" + ban_user_dialog_sub: "Está seguro de querer banear a este usuario?" + ban_user_dialog_copy: "Nota: Baneando a este usuario pondrá el comentario en la cola de comentarios Rechazados." + ban_user_dialog_cancel: "Cancelar" + ban_user_dialog_yes: "Si. Banear usuario" + ban_user_dialog_headline: "Banear Usuario?" \ No newline at end of file