Merge pull request #1159 from coralproject/more-undo

Enhanced undo
This commit is contained in:
Kim Gardner
2017-11-15 18:09:04 +00:00
committed by GitHub
15 changed files with 73 additions and 9 deletions
@@ -48,7 +48,7 @@ class SuspendUserDialogContainer extends Component {
SuspendUserDialogContainer.propTypes = {
open: PropTypes.bool,
hideSuspendUserDialog: PropTypes.func,
username: PropTypes.object,
username: PropTypes.string,
};
const withOrganizationName = withQuery(gql`
@@ -111,6 +111,17 @@ class ModerationContainer extends Component {
return this.handleCommentChange(prev, comment, notifyText);
},
},
{
document: COMMENT_RESET_SUBSCRIPTION,
variables,
updateQuery: (prev, {subscriptionData: {data: {commentReset: comment}}}) => {
const user = comment.status_history[comment.status_history.length - 1].assigned_by;
const notifyText = this.props.auth.user.id === user.id
? ''
: t('modqueue.notify_reset', user.username, prepareNotificationText(comment.body));
return this.handleCommentChange(prev, comment, notifyText);
},
},
{
document: COMMENT_EDITED_SUBSCRIPTION,
variables,
@@ -299,6 +310,23 @@ const COMMENT_REJECTED_SUBSCRIPTION = gql`
${Comment.fragments.comment}
`;
const COMMENT_RESET_SUBSCRIPTION = gql`
subscription CommentReset($asset_id: ID){
commentReset(asset_id: $asset_id){
...${getDefinitionName(Comment.fragments.comment)}
status_history {
type
created_at
assigned_by {
id
username
}
}
}
}
${Comment.fragments.comment}
`;
const LOAD_MORE_QUERY = gql`
query CoralAdmin_Moderation_LoadMore($limit: Int = 10, $cursor: Cursor, $sortOrder: SORT_ORDER, $asset_id: ID, $tags:[String!], $statuses:[COMMENT_STATUS!], $action_type: ACTION_TYPE) {
comments(query: {limit: $limit, cursor: $cursor, asset_id: $asset_id, statuses: $statuses, sortOrder: $sortOrder, action_type: $action_type, tags: $tags}) {
@@ -345,7 +345,10 @@ export default class Comment extends React.Component {
if (!highlighted && this.commentIsRejected(comment)) {
return <CommentTombstone action='reject' onUndo={() => {
this.props.setCommentStatus({commentId: comment.id, status: 'NONE'});
this.props.setCommentStatus({
commentId: comment.id,
status: comment.status_history[comment.status_history.length - 2].type,
});
}}/>;
}
@@ -25,7 +25,7 @@ class CommentTombstone extends React.Component {
<p className={styles.commentTombstone}>
{this.getCopy()}
{this.props.action === 'reject' &&
<span className={styles.undo} onClick={this.props.onUndo}>Undo</span>
<span className={styles.undo} onClick={this.props.onUndo}>{t('comment.undo_reject')}</span>
}
</p>
</div>
@@ -76,6 +76,9 @@ const singleCommentFragment = gql`
id
username
}
status_history {
type
}
action_summaries {
__typename
count
@@ -102,6 +102,9 @@ export default {
}
}
}
status_history {
type
}
action_summaries {
count
current_user {
@@ -182,6 +185,7 @@ export default {
editableUntil: new Date().toISOString(),
edited: false,
},
status_history: [],
id: `pending-${uuid()}`,
}
}
@@ -138,6 +138,9 @@ export const withSetCommentStatus = withMutation(
const fragment = gql`
fragment Talk_SetCommentStatus on Comment {
status
status_history {
type
}
}`;
const fragmentId = `Comment_${commentId}`;
@@ -145,6 +148,8 @@ export const withSetCommentStatus = withMutation(
const data = proxy.readFragment({fragment, id: fragmentId});
data.status = status;
data.status_history = data.status_history ? data.status_history : [];
data.status_history.push({__typename: 'CommentStatusHistory', type: status});
proxy.writeFragment({fragment, id: fragmentId, data});
}
+2 -4
View File
@@ -43,13 +43,11 @@ const RootMutation = {
setCommentStatus: async (_, {id, status}, {mutators: {Comment}, pubsub}) => {
const comment = await Comment.setStatus({id, status});
if (status === 'ACCEPTED') {
// Publish the comment status change via the subscription.
pubsub.publish('commentAccepted', comment);
} else if (status === 'REJECTED') {
// Publish the comment status change via the subscription.
pubsub.publish('commentRejected', comment);
} else if (status === 'NONE') {
pubsub.publish('commentReset', comment);
}
},
addTag: async (_, {tag}, {mutators: {Tag}}) => {
+3
View File
@@ -11,6 +11,9 @@ const Subscription = {
commentRejected(comment) {
return comment;
},
commentReset(comment) {
return comment;
},
commentFlagged(comment) {
return comment;
},
+11
View File
@@ -2,6 +2,7 @@ const {
SUBSCRIBE_COMMENT_ACCEPTED,
SUBSCRIBE_COMMENT_REJECTED,
SUBSCRIBE_COMMENT_FLAGGED,
SUBSCRIBE_COMMENT_RESET,
SUBSCRIBE_ALL_COMMENT_EDITED,
SUBSCRIBE_ALL_COMMENT_ADDED,
SUBSCRIBE_ALL_USER_SUSPENDED,
@@ -93,6 +94,16 @@ const setupFunctions = plugins.get('server', 'setupFunctions').reduce((acc, {plu
}
},
}),
commentReset: (options, args) => ({
commentReset: {
filter: (comment, context) => {
if (!context.user || !context.user.can(SUBSCRIBE_COMMENT_RESET)) {
return false;
}
return !args.asset_id || comment.asset_id === args.asset_id;
}
},
}),
userSuspended: (options, args) => ({
userSuspended: {
filter: (user, context) => {
+4
View File
@@ -1376,6 +1376,10 @@ type Subscription {
# Requires the `ADMIN` or `MODERATOR` role.
commentRejected(asset_id: ID): Comment
# Get an update whenever the status of a comment has been reset.
# Requires the `ADMIN` or `MODERATOR` role.
commentReset(asset_id: ID): Comment
# Get an update whenever a user has been suspended.
# `user_id` must match id of current user except for
# users with the `ADMIN` or `MODERATOR` role.
+2
View File
@@ -17,6 +17,7 @@ en:
characters_remaining: "characters remaining"
comment:
anon: "Anonymous"
undo_reject: "Undo"
ban_user: "Ban User"
comment: "Post a comment"
edited: Edited
@@ -263,6 +264,7 @@ en:
notify_accepted: '{0} accepted comment "{1}"'
notify_rejected: '{0} rejected comment "{1}"'
notify_flagged: '{0} flagged comment "{1}"'
notify_reset: '{0} reset status of comment "{1}"'
approve: "Approve"
approved: "Approved"
ban_user: "Ban"
+1
View File
@@ -36,6 +36,7 @@ module.exports = {
SUBSCRIBE_COMMENT_ACCEPTED: 'SUBSCRIBE_COMMENT_ACCEPTED',
SUBSCRIBE_COMMENT_REJECTED: 'SUBSCRIBE_COMMENT_REJECTED',
SUBSCRIBE_COMMENT_FLAGGED: 'SUBSCRIBE_COMMENT_FLAGGED',
SUBSCRIBE_COMMENT_RESET: 'SUBSCRIBE_COMMENT_RESET',
SUBSCRIBE_ALL_COMMENT_ADDED: 'SUBSCRIBE_ALL_COMMENT_ADDED',
SUBSCRIBE_ALL_COMMENT_EDITED: 'SUBSCRIBE_ALL_COMMENT_EDITED',
SUBSCRIBE_ALL_USER_SUSPENDED: 'SUBSCRIBE_ALL_USER_SUSPENDED',
+2
View File
@@ -9,6 +9,8 @@ module.exports = (user, perm) => {
return check(user, ['ADMIN', 'MODERATOR']);
case types.SUBSCRIBE_COMMENT_REJECTED:
return check(user, ['ADMIN', 'MODERATOR']);
case types.SUBSCRIBE_COMMENT_RESET:
return check(user, ['ADMIN', 'MODERATOR']);
case types.SUBSCRIBE_ALL_COMMENT_EDITED:
return check(user, ['ADMIN', 'MODERATOR']);
case types.SUBSCRIBE_ALL_COMMENT_ADDED:
@@ -33,9 +33,9 @@ const BanUserDialog = ({showBanDialog, closeBanDialog, banUser}) => (
);
BanUserDialog.propTypes = {
showBanDialog: PropTypes.func.isRequired,
showBanDialog: PropTypes.bool.isRequired,
closeBanDialog: PropTypes.func.isRequired,
banUser: PropTypes.func.isRequired,
};
export default BanUserDialog;
export default BanUserDialog;