From 83ded4bda960420ecb9ea676e547f44addf4951e Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Thu, 10 Aug 2017 18:37:14 +0700 Subject: [PATCH] Refactor into queueConfig --- client/coral-admin/src/AppRouter.js | 24 +- .../Moderation/components/Moderation.js | 41 +--- .../Moderation/components/ModerationMenu.js | 67 +----- .../Moderation/containers/Moderation.js | 226 ++++++------------ .../utils.js => routes/Moderation/graphql.js} | 57 ++--- .../src/routes/Moderation/queueConfig.js | 35 +++ .../client/containers/ModSubscription.js | 25 +- 7 files changed, 170 insertions(+), 305 deletions(-) rename client/coral-admin/src/{graphql/utils.js => routes/Moderation/graphql.js} (74%) create mode 100644 client/coral-admin/src/routes/Moderation/queueConfig.js diff --git a/client/coral-admin/src/AppRouter.js b/client/coral-admin/src/AppRouter.js index 4b3ea0f0b..9772ebf17 100644 --- a/client/coral-admin/src/AppRouter.js +++ b/client/coral-admin/src/AppRouter.js @@ -37,27 +37,11 @@ const routes = ( - - - - - - - - - - - - - - - - - - - - + + + + diff --git a/client/coral-admin/src/routes/Moderation/components/Moderation.js b/client/coral-admin/src/routes/Moderation/components/Moderation.js index ce0c31e33..f50ff9c50 100644 --- a/client/coral-admin/src/routes/Moderation/components/Moderation.js +++ b/client/coral-admin/src/routes/Moderation/components/Moderation.js @@ -101,33 +101,19 @@ export default class Moderation extends Component { } render () { - const {root, data, moderation, settings, viewUserDetail, hideUserDetail, activeTab, getModPath, premodEnabled, ...props} = this.props; - const assetId = this.props.params.id; + const {root, data, moderation, settings, viewUserDetail, hideUserDetail, activeTab, getModPath, queueConfig, handleCommentChange, ...props} = this.props; const {asset} = root; + const assetId = asset && asset.id; const comments = root[activeTab]; - let activeTabCount; - switch(activeTab) { - case 'all': - activeTabCount = root.allCount; - break; - case 'new': - activeTabCount = root.newCount; - break; - case 'approved': - activeTabCount = root.approvedCount; - break; - case 'premod': - activeTabCount = root.premodCount; - break; - case 'reported': - activeTabCount = root.reportedCount; - break; - case 'rejected': - activeTabCount = root.rejectedCount; - break; - } + const activeTabCount = root[`${activeTab}Count`]; + const menuItems = Object.keys(queueConfig).map((queue) => ({ + key: queue, + name: queueConfig[queue].name, + icon: queueConfig[queue].icon, + count: root[`${queue}Count`] + })); return (
@@ -139,16 +125,10 @@ export default class Moderation extends Component { />
diff --git a/client/coral-admin/src/routes/Moderation/components/ModerationMenu.js b/client/coral-admin/src/routes/Moderation/components/ModerationMenu.js index 62bbd4d2e..7b427ac54 100644 --- a/client/coral-admin/src/routes/Moderation/components/ModerationMenu.js +++ b/client/coral-admin/src/routes/Moderation/components/ModerationMenu.js @@ -9,16 +9,10 @@ import cn from 'classnames'; import t from 'coral-framework/services/i18n'; const ModerationMenu = ({ - asset = {}, - allCount, - approvedCount, - premodCount, - newCount, - rejectedCount, - reportedCount, + asset = {}, + items, selectSort, sort, - premodEnabled, getModPath, activeTab }) => { @@ -27,49 +21,15 @@ const ModerationMenu = ({
- - { - premodEnabled ? ( - - {t('modqueue.premod')} - - ) : ( - - {t('modqueue.new')} - - ) - } - - - {t('modqueue.reported')} - - - {t('modqueue.approved')} - - - {t('modqueue.rejected')} - - - {t('modqueue.all')} - + {items.map((queue) => + + {queue.name} + + )}
{ + return handleCommentChange(root, comment, this.props.data.variables.sort, notify, queueConfig, this.activeTab); + }; + get activeTab() { - const {root: {asset, settings}, router, route} = this.props; + const {root: {asset, settings}} = this.props; + const id = getAssetId(this.props); + const tab = getTab(this.props); // Grab premod from asset or from settings - const premod = !router.params.id ? settings.moderation : asset.settings.moderation; + const premod = !id ? settings.moderation : asset.settings.moderation; const queue = isPremod(premod) ? 'premod' : 'new'; - const activeTab = route.path && route.path !== ':id' ? route.path : queue; + const activeTab = tab ? tab : queue; return activeTab; } @@ -57,15 +78,10 @@ class ModerationContainer extends Component { variables, updateQuery: (prev, {subscriptionData: {data: {commentAccepted: comment}}}) => { const user = comment.status_history[comment.status_history.length - 1].assigned_by; - const sort = this.props.moderation.sortOrder; const notify = this.props.auth.user.id === user.id - ? {} - : { - activeQueue: this.activeTab, - text: t('modqueue.notify_accepted', user.username, prepareNotificationText(comment.body)), - anyQueue: false, - }; - return handleCommentChange(prev, comment, sort, notify); + ? '' + : t('modqueue.notify_accepted', user.username, prepareNotificationText(comment.body)); + return this.handleCommentChange(prev, comment, notify); }, }); @@ -74,15 +90,10 @@ class ModerationContainer extends Component { variables, updateQuery: (prev, {subscriptionData: {data: {commentRejected: comment}}}) => { const user = comment.status_history[comment.status_history.length - 1].assigned_by; - const sort = this.props.moderation.sortOrder; const notify = this.props.auth.user.id === user.id - ? {} - : { - activeQueue: this.activeTab, - text: t('modqueue.notify_rejected', user.username, prepareNotificationText(comment.body)), - anyQueue: false, - }; - return handleCommentChange(prev, comment, sort, notify); + ? '' + : t('modqueue.notify_rejected', user.username, prepareNotificationText(comment.body)); + return this.handleCommentChange(prev, comment, notify); }, }); @@ -90,13 +101,8 @@ class ModerationContainer extends Component { document: COMMENT_EDITED_SUBSCRIPTION, variables, updateQuery: (prev, {subscriptionData: {data: {commentEdited: comment}}}) => { - const sort = this.props.moderation.sortOrder; - const notify = { - activeQueue: this.activeTab, - text: t('modqueue.notify_edited', comment.user.username, prepareNotificationText(comment.body)), - anyQueue: false, - }; - return handleCommentChange(prev, comment, sort, notify); + const notify = t('modqueue.notify_edited', comment.user.username, prepareNotificationText(comment.body)); + return this.handleCommentChange(prev, comment, notify); }, }); @@ -105,13 +111,8 @@ class ModerationContainer extends Component { variables, updateQuery: (prev, {subscriptionData: {data: {commentFlagged: comment}}}) => { const user = comment.actions[comment.actions.length - 1].user; - const sort = this.props.moderation.sortOrder; - const notify = { - activeQueue: this.activeTab, - text: t('modqueue.notify_flagged', user.username, prepareNotificationText(comment.body)), - anyQueue: true, - }; - return handleCommentChange(prev, comment, sort, notify); + const notify = t('modqueue.notify_flagged', user.username, prepareNotificationText(comment.body)); + return this.handleCommentChange(prev, comment, notify); }, }); @@ -160,28 +161,9 @@ class ModerationContainer extends Component { cursor: this.props.root[tab].endCursor, sort: this.props.data.variables.sort, asset_id: this.props.data.variables.asset_id, + statuses: queueConfig[tab].statuses, + action_type: queueConfig[tab].action_type, }; - switch(tab) { - case 'all': - variables.statuses = null; - break; - case 'new': - variables.statuses = ['NONE', 'PREMOD']; - break; - case 'approved': - variables.statuses = ['ACCEPTED']; - break; - case 'premod': - variables.statuses = ['PREMOD']; - break; - case 'reported': - variables.statuses = ['NONE', 'PREMOD']; - variables.action_type = 'FLAG'; - break; - case 'rejected': - variables.statuses = ['REJECTED']; - break; - } return this.props.data.fetchMore({ query: LOAD_MORE_QUERY, variables, @@ -199,7 +181,8 @@ class ModerationContainer extends Component { }; render () { - const {root, root: {asset, settings}, data, params: {id: assetId}} = this.props; + const {root, root: {asset, settings}, data} = this.props; + const assetId = getAssetId(this.props); if (data.error) { return
Error
; @@ -222,6 +205,14 @@ class ModerationContainer extends Component { return ; } + const premodEnabled = assetId ? isPremod(asset.settings.moderation) : isPremod(settings.moderation); + const currentQueueConfig = Object.assign({}, queueConfig); + if (premodEnabled) { + delete currentQueueConfig.new; + } else { + delete currentQueueConfig.premod; + } + return ; } } @@ -314,49 +306,25 @@ const commentConnectionFragment = gql` const withModQueueQuery = withQuery(gql` query CoralAdmin_Moderation($asset_id: ID, $sort: SORT_ORDER, $allAssets: Boolean!) { - all: comments(query: { - statuses: [NONE, PREMOD, ACCEPTED, REJECTED], - asset_id: $asset_id, - sort: $sort - }) { - ...CoralAdmin_Moderation_CommentConnection - } - new: comments(query: { - statuses: [NONE, PREMOD], - asset_id: $asset_id, - sort: $sort - }) { - ...CoralAdmin_Moderation_CommentConnection - } - approved: comments(query: { - statuses: [ACCEPTED], - asset_id: $asset_id, - sort: $sort - }) { - ...CoralAdmin_Moderation_CommentConnection - } - premod: comments(query: { - statuses: [PREMOD], + ${Object.keys(queueConfig).map((queue) => ` + ${queue}: comments(query: { + ${queueConfig[queue].statuses ? `statuses: [${queueConfig[queue].statuses.join(', ')}],` : ''} + ${queueConfig[queue].tags ? `tags: ["${queueConfig[queue].tags.join('", "')}"],` : ''} + ${queueConfig[queue].action_type ? `action_type: ${queueConfig[queue].action_type}` : ''} asset_id: $asset_id, sort: $sort - }) { - ...CoralAdmin_Moderation_CommentConnection - } - reported: comments(query: { - action_type: FLAG, + }) { + ...CoralAdmin_Moderation_CommentConnection + } + `)} + ${Object.keys(queueConfig).map((queue) => ` + ${queue}Count: commentCount(query: { + ${queueConfig[queue].statuses ? `statuses: [${queueConfig[queue].statuses.join(', ')}],` : ''} + ${queueConfig[queue].tags ? `tags: ["${queueConfig[queue].tags.join('", "')}"],` : ''} + ${queueConfig[queue].action_type ? `action_type: ${queueConfig[queue].action_type}` : ''} asset_id: $asset_id, - statuses: [NONE, PREMOD], - sort: $sort - }) { - ...CoralAdmin_Moderation_CommentConnection - } - rejected: comments(query: { - statuses: [REJECTED], - asset_id: $asset_id, - sort: $sort - }) { - ...CoralAdmin_Moderation_CommentConnection - } + }) + `)} asset(id: $asset_id) @skip(if: $allAssets) { id title @@ -365,30 +333,6 @@ const withModQueueQuery = withQuery(gql` moderation } } - allCount: commentCount(query: { - asset_id: $asset_id - }) - newCount: commentCount(query: { - statuses: [NONE, PREMOD], - asset_id: $asset_id - }) - approvedCount: commentCount(query: { - statuses: [ACCEPTED], - asset_id: $asset_id - }) - premodCount: commentCount(query: { - statuses: [PREMOD], - asset_id: $asset_id - }) - rejectedCount: commentCount(query: { - statuses: [REJECTED], - asset_id: $asset_id - }) - reportedCount: commentCount(query: { - action_type: FLAG, - asset_id: $asset_id, - statuses: [NONE, PREMOD] - }) settings { organizationName moderation @@ -396,11 +340,12 @@ const withModQueueQuery = withQuery(gql` } ${commentConnectionFragment} `, { - options: ({params: {id = null}, moderation: {sortOrder}}) => { + options: (props) => { + const id = getAssetId(props); return { variables: { asset_id: id, - sort: sortOrder, + sort: props.moderation.sortOrder, allAssets: id === null } }; @@ -409,33 +354,18 @@ const withModQueueQuery = withQuery(gql` const withQueueCountPolling = withQuery(gql` query CoralAdmin_ModerationCountPoll($asset_id: ID) { - allCount: commentCount(query: { - asset_id: $asset_id - }) - newCount: commentCount(query: { - statuses: [NONE, PREMOD], - asset_id: $asset_id - }) - approvedCount: commentCount(query: { - statuses: [ACCEPTED], - asset_id: $asset_id - }) - premodCount: commentCount(query: { - statuses: [PREMOD], - asset_id: $asset_id - }) - rejectedCount: commentCount(query: { - statuses: [REJECTED], - asset_id: $asset_id - }) - reportedCount: commentCount(query: { - action_type: FLAG, - asset_id: $asset_id, - statuses: [NONE, PREMOD] - }) + ${Object.keys(queueConfig).map((queue) => ` + ${queue}Count: commentCount(query: { + ${queueConfig[queue].statuses ? `statuses: [${queueConfig[queue].statuses.join(', ')}],` : ''} + ${queueConfig[queue].tags ? `tags: ["${queueConfig[queue].tags.join('", "')}"],` : ''} + ${queueConfig[queue].action_type ? `action_type: ${queueConfig[queue].action_type}` : ''} + asset_id: $asset_id, + }) + `)} } `, { - options: ({params: {id = null}}) => { + options: (props) => { + const id = getAssetId(props); return { pollInterval: 5000, variables: { diff --git a/client/coral-admin/src/graphql/utils.js b/client/coral-admin/src/routes/Moderation/graphql.js similarity index 74% rename from client/coral-admin/src/graphql/utils.js rename to client/coral-admin/src/routes/Moderation/graphql.js index f729cc0ea..0d4991f72 100644 --- a/client/coral-admin/src/graphql/utils.js +++ b/client/coral-admin/src/routes/Moderation/graphql.js @@ -1,7 +1,6 @@ import update from 'immutability-helper'; import * as notification from 'coral-admin/src/services/notification'; -const queues = ['all', 'premod', 'reported', 'approved', 'rejected', 'new']; const limit = 10; const ascending = (a, b) => { @@ -67,32 +66,24 @@ function addCommentToQueue(root, queue, comment, sort) { /** * getCommentQueues determines in which queues a comment should be placed. */ -function getCommentQueues(comment) { - const queues = ['all']; - const isFlagged = comment.actions && comment.actions.some((a) => a.__typename === 'FlagAction'); - - switch(comment.status) { - case 'ACCEPTED': - queues.push('approved'); - break; - case 'REJECTED': - queues.push('rejected'); - break; - case 'PREMOD': - queues.push('premod'); - queues.push('new'); - if (isFlagged) { - queues.push('reported'); +function getCommentQueues(comment, queueConfig) { + const queues = []; + Object.keys(queueConfig).forEach((key) => { + const {action_type, statuses, tags} = queueConfig[key]; + let addToQueues = false; + if (statuses && statuses.indexOf(comment.status) >= 0) { + addToQueues = true; } - break; - case 'NONE': - queues.push('new'); - if (isFlagged) { - queues.push('reported'); + if (tags && comment.tags && comment.tags.some((tagLink) => tags.indexOf(tagLink.tag.name) >= 0)) { + addToQueues = true; } - break; - } - + if (action_type && comment.actions && comment.actions.some((a) => a.__typename.toLowerCase() === `${action_type}action`)) { + addToQueues = true; + } + if (addToQueues) { + queues.push(key); + } + }); return queues; } @@ -106,42 +97,42 @@ function getCommentQueues(comment) { * @param {string} notify.text notification text to show * @param {bool} notify.anyQueue if true show the notification when the comment is shown * in the current active queue besides the 'all' queue. + * @param {Object} queueConfig queue configuration * @return {Object} next state of the store */ -export function handleCommentChange(root, comment, sort, notify) { +export function handleCommentChange(root, comment, sort, notify, queueConfig, activeQueue) { let next = root; - const nextQueues = getCommentQueues(comment); + const nextQueues = getCommentQueues(comment, queueConfig); let notificationShown = false; const showNotificationOnce = () => { if (notificationShown) { return; } - notification.info(notify.text); + notification.info(notify); notificationShown = true; }; - queues.forEach((queue) => { + Object.keys(queueConfig).forEach((queue) => { if (nextQueues.indexOf(queue) >= 0) { if (!queueHasComment(next, queue, comment.id)) { next = addCommentToQueue(next, queue, comment, sort); - if (notify && notify.activeQueue === queue && shouldCommentBeAdded(next, queue, comment, sort)) { + if (notify && activeQueue === queue && shouldCommentBeAdded(next, queue, comment, sort)) { showNotificationOnce(comment); } } } else if(queueHasComment(next, queue, comment.id)){ next = removeCommentFromQueue(next, queue, comment.id); - if (notify && notify.activeQueue === queue) { + if (notify && activeQueue === queue) { showNotificationOnce(comment); } } if ( notify - && (queue === 'all' || notify.anyQueue) && queueHasComment(next, queue, comment.id) - && notify.activeQueue === queue + && activeQueue === queue ) { showNotificationOnce(comment); } diff --git a/client/coral-admin/src/routes/Moderation/queueConfig.js b/client/coral-admin/src/routes/Moderation/queueConfig.js new file mode 100644 index 000000000..5385b5e23 --- /dev/null +++ b/client/coral-admin/src/routes/Moderation/queueConfig.js @@ -0,0 +1,35 @@ +import t from 'coral-framework/services/i18n'; + +export default { + premod: { + statuses: ['PREMOD'], + icon: 'access_time', + name: t('modqueue.premod'), + }, + new: { + statuses: ['NONE', 'PREMOD'], + icon: 'question_answer', + name: t('modqueue.new'), + }, + reported: { + action_type: 'FLAG', + statuses: ['NONE', 'PREMOD'], + icon: 'flag', + name: t('modqueue.reported'), + }, + approved: { + statuses: ['ACCEPTED'], + icon: 'check', + name: t('modqueue.approved'), + }, + rejected: { + statuses: ['REJECTED'], + icon: 'close', + name: t('modqueue.rejected'), + }, + all: { + statuses: ['NONE', 'PREMOD', 'ACCEPTED', 'REJECTED'], + icon: 'question_answer', + name: t('modqueue.all'), + } +}; diff --git a/plugins/talk-plugin-featured-comments/client/containers/ModSubscription.js b/plugins/talk-plugin-featured-comments/client/containers/ModSubscription.js index 647c7ecfd..85e0d8fe2 100644 --- a/plugins/talk-plugin-featured-comments/client/containers/ModSubscription.js +++ b/plugins/talk-plugin-featured-comments/client/containers/ModSubscription.js @@ -2,7 +2,6 @@ import React from 'react'; import {gql} from 'react-apollo'; import {connect} from 'react-redux'; import Comment from 'coral-admin/src/routes/Moderation/containers/Comment'; -import {handleCommentChange} from 'coral-admin/src/graphql/utils'; import {getDefinitionName} from 'coral-framework/utils'; import truncate from 'lodash/truncate'; import t from 'coral-framework/services/i18n'; @@ -22,20 +21,14 @@ class ModSubscription extends React.Component { assetId: this.props.data.variables.asset_id, }, updateQuery: (prev, {subscriptionData: {data: {commentFeatured: {user, comment}}}}) => { - const sort = this.props.data.variables.sort; - const text = this.props.user.id === user.id - ? {} + const notify = this.props.user.id === user.id + ? '' : t( 'talk-plugin-featured-comments.notify_featured', user.username, prepareNotificationText(comment.body), ); - const notify = { - activeQueue: this.props.activeTab, - text, - anyQueue: true, - }; - return handleCommentChange(prev, comment, sort, notify); + return this.props.handleCommentChange(prev, comment, notify); }, }, { @@ -44,20 +37,14 @@ class ModSubscription extends React.Component { assetId: this.props.data.variables.asset_id, }, updateQuery: (prev, {subscriptionData: {data: {commentUnfeatured: {user, comment}}}}) => { - const sort = this.props.data.variables.sort; - const text = this.props.user.id === user.id - ? {} + const notify = this.props.user.id === user.id + ? '' : t( 'talk-plugin-featured-comments.notify_unfeatured', user.username, prepareNotificationText(comment.body), ); - const notify = { - activeQueue: this.props.activeTab, - text, - anyQueue: true, - }; - return handleCommentChange(prev, comment, sort, notify); + return this.props.handleCommentChange(prev, comment, notify); } }, ];