diff --git a/client/coral-admin/src/actions/moderation.js b/client/coral-admin/src/actions/moderation.js new file mode 100644 index 000000000..25a9aed73 --- /dev/null +++ b/client/coral-admin/src/actions/moderation.js @@ -0,0 +1,5 @@ +import * as actions from 'constants/moderation'; + +export const setActiveTab = activeTab => ({type: actions.SET_ACTIVE_TAB, activeTab}); +export const toggleModal = open => ({type: actions.TOGGLE_MODAL, open}); +export const singleView = open => ({type: actions.SINGLE_VIEW}); diff --git a/client/coral-admin/src/constants/moderation.js b/client/coral-admin/src/constants/moderation.js new file mode 100644 index 000000000..1ef27eddd --- /dev/null +++ b/client/coral-admin/src/constants/moderation.js @@ -0,0 +1,3 @@ +export const SET_ACTIVE_TAB = 'SET_ACTIVE_TAB'; +export const TOGGLE_MODAL = 'TOGGLE_MODAL'; +export const SINGLE_VIEW = 'SINGLE_VIEW' diff --git a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js index d1d1afd53..095321e42 100644 --- a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js +++ b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js @@ -11,32 +11,23 @@ import { fetchFlaggedQueue, fetchModerationQueueComments, } from 'actions/comments'; -import {userStatusUpdate, sendNotificationEmail} from 'actions/users'; + import {fetchSettings} from 'actions/settings'; +import {userStatusUpdate, sendNotificationEmail} from 'actions/users'; +import {setActiveTab, toggleModal, singleView} from 'actions/moderation'; import ModerationQueue from './ModerationQueue'; class ModerationContainer extends React.Component { - - constructor(props) { - super(props); - - this.state = { - activeTab: 'all', - singleView: false, - modalOpen: false - }; - - this.onClose = this.onClose.bind(this); - this.onTabClick = this.onTabClick.bind(this); - } - componentWillMount() { + const {toggleModal, singleView} = this.props; + this.props.fetchModerationQueueComments(); this.props.fetchSettings(); - key('s', () => this.setState({singleView: !this.state.singleView})); - key('shift+/', () => this.setState({modalOpen: true})); - key('esc', () => this.setState({modalOpen: false})); + + key('s', () => singleView()); + key('shift+/', () => toggleModal(true)); + key('esc', () => toggleModal(false)); } componentWillUnmount() { @@ -45,18 +36,9 @@ class ModerationContainer extends React.Component { key.unbind('esc'); } - componentDidMount() { - - // Hack for dynamic mdl tabs - if (typeof componentHandler !== 'undefined') { - - // FIXME: fix this hack - componentHandler.upgradeAllRegistered(); // eslint-disable-line no-undef - } - } - - onTabClick(activeTab) { - this.setState({activeTab}); + onTabClick = (activeTab) => { + const {setActiveTab} = this.props; + setActiveTab(activeTab); if (activeTab === 'premod') { this.props.fetchPremodQueue(); @@ -69,12 +51,15 @@ class ModerationContainer extends React.Component { } } - onClose() { - this.setState({modalOpen: false}); + onClose = () => { + const {toggleModal} = this.props; + toggleModal(false); } render () { - const {comments, actions, settings} = this.props; + const {comments, actions, settings, moderation} = this.props; + + // Remove all this filters const premodIds = comments.ids.filter(id => comments.byId[id].status === 'PREMOD'); const rejectedIds = comments.ids.filter(id => comments.byId[id].status === 'REJECTED'); const flaggedIds = comments.ids.filter(id => @@ -97,37 +82,41 @@ class ModerationContainer extends React.Component { rejectedIds={rejectedIds} flaggedIds={flaggedIds} {...this.props} - {...this.state} + {...moderation} /> ); } } const mapStateToProps = state => ({ + moderation: state.moderation.toJS(), comments: state.comments.toJS(), settings: state.settings.toJS(), users: state.users.toJS(), - actions: state.actions.toJS(), + actions: state.actions.toJS() }); -const mapDispatchToProps = dispatch => { - return { - fetchSettings: () => dispatch(fetchSettings()), - fetchModerationQueueComments: () => dispatch(fetchModerationQueueComments()), - fetchPremodQueue: () => dispatch(fetchPremodQueue()), - fetchRejectedQueue: () => dispatch(fetchRejectedQueue()), - fetchFlaggedQueue: () => dispatch(fetchFlaggedQueue()), - showBanUserDialog: (userId, userName, commentId) => dispatch(showBanUserDialog(userId, userName, commentId)), - hideBanUserDialog: () => dispatch(hideBanUserDialog(false)), - userStatusUpdate: (status, userId, commentId) => dispatch(userStatusUpdate(status, userId, commentId)).then(() => { - dispatch(fetchModerationQueueComments()); - }), - suspendUser: (userId, subject, text) => dispatch(userStatusUpdate('suspended', userId)) - .then(() => dispatch(sendNotificationEmail(userId, subject, text))) - .then(() => dispatch(fetchModerationQueueComments())) - , - updateStatus: (action, comment) => dispatch(updateStatus(action, comment)) - }; -}; +const mapDispatchToProps = dispatch => ({ + setActiveTab: tab => dispatch(setActiveTab(tab)), + toggleModal: open => dispatch(toggleModal(open)), + singleView: () => dispatch(singleView()), + + + fetchSettings: () => dispatch(fetchSettings()), + fetchModerationQueueComments: () => dispatch(fetchModerationQueueComments()), + fetchPremodQueue: () => dispatch(fetchPremodQueue()), + fetchRejectedQueue: () => dispatch(fetchRejectedQueue()), + fetchFlaggedQueue: () => dispatch(fetchFlaggedQueue()), + showBanUserDialog: (userId, userName, commentId) => dispatch(showBanUserDialog(userId, userName, commentId)), + hideBanUserDialog: () => dispatch(hideBanUserDialog(false)), + userStatusUpdate: (status, userId, commentId) => dispatch(userStatusUpdate(status, userId, commentId)).then(() => { + dispatch(fetchModerationQueueComments()); + }), + suspendUser: (userId, subject, text) => dispatch(userStatusUpdate('suspended', userId)) + .then(() => dispatch(sendNotificationEmail(userId, subject, text))) + .then(() => dispatch(fetchModerationQueueComments())) + , + updateStatus: (action, comment) => dispatch(updateStatus(action, comment)) +}); export default connect(mapStateToProps, mapDispatchToProps)(ModerationContainer); diff --git a/client/coral-admin/src/reducers/index.js b/client/coral-admin/src/reducers/index.js index a19a5a087..415d0f581 100644 --- a/client/coral-admin/src/reducers/index.js +++ b/client/coral-admin/src/reducers/index.js @@ -1,19 +1,21 @@ import {combineReducers} from 'redux'; -import comments from 'reducers/comments'; -import settings from 'reducers/settings'; -import community from 'reducers/community'; -import users from 'reducers/users'; -import auth from 'reducers/auth'; -import actions from 'reducers/actions'; -import assets from 'reducers/assets'; -// Combine all reducers into a main one +import auth from './auth'; +import users from './users'; +import assets from './assets'; +import actions from './actions'; +import comments from './comments'; +import settings from './settings'; +import community from './community'; +import moderation from './moderation'; + export default combineReducers({ + auth, + users, + assets, + actions, settings, comments, community, - auth, - actions, - assets, - users + moderation }); diff --git a/client/coral-admin/src/reducers/moderation.js b/client/coral-admin/src/reducers/moderation.js new file mode 100644 index 000000000..3f04abfc6 --- /dev/null +++ b/client/coral-admin/src/reducers/moderation.js @@ -0,0 +1,24 @@ +import {Map} from 'immutable'; +import * as actions from '../constants/moderation'; + +const initialState = Map({ + activeTab: 'all', + singleView: false, + modalOpen: false +}); + +export default function moderation (state = initialState, action) { + switch (action.type) { + case actions.SET_ACTIVE_TAB: + return state + .set('activeTab', action.activeTab); + case actions.TOGGLE_MODAL: + return state + .set('modalOpen', action.open); + case actions.SINGLE_VIEW: + return state + .set('singleView', !state.get('singleView')); + default : + return state; + } +}