FEATURE: Flag count in post menu

FEATURE: Flag count in post menu

This change shows a notification number besides the flag icon in the post menu if there is reviewable content associated with the post. Additionally, if there is pending stuff to review, the icon has a red background.

We have also removed the list of links below a post with the flag status. A reviewer is meant to click the number beside the flag icon to view the flags. As a consequence of losing those links, we’ve removed the ability to undo or ignore flags below a post.

diff --git a/app/assets/javascripts/discourse/lib/transform-post.js.es6 b/app/assets/javascripts/discourse/lib/transform-post.js.es6
index 1aa662a..eccfb19 100644
--- a/app/assets/javascripts/discourse/lib/transform-post.js.es6
+++ b/app/assets/javascripts/discourse/lib/transform-post.js.es6
@@ -1,19 +1,5 @@
 import { userPath } from "discourse/lib/url";
 
-function actionDescription(action, acted, count) {
-  if (acted) {
-    if (count <= 1) {
-      return I18n.t(`post.actions.by_you.${action}`);
-    } else {
-      return I18n.t(`post.actions.by_you_and_others.${action}`, {
-        count: count - 1
-      });
-    }
-  } else {
-    return I18n.t(`post.actions.by_others.${action}`, { count });
-  }
-}
-
 const _additionalAttributes = [];
 
 export function includeAttributes(...attributes) {
@@ -62,6 +48,10 @@ export function transformBasicPost(post) {
     canRecover: post.can_recover,
     canEdit: post.can_edit,
     canFlag: !Ember.isEmpty(post.get("flagsAvailable")),
+    canReviewTopic: false,
+    reviewableId: post.reviewable_id,
+    reviewableScoreCount: post.reviewable_score_count,
+    reviewableScorePendingCount: post.reviewable_score_pending_count,
     version: post.version,
     canRecoverTopic: false,
     canDeletedTopic: false,
@@ -121,6 +111,7 @@ export default function transformPost(
   postAtts.canViewRawEmail =
     currentUser && (currentUser.id === post.user_id || currentUser.staff);
   postAtts.canReplyAsNewTopic = details.can_reply_as_new_topic;
+  postAtts.canReviewTopic = !!details.can_review_topic;
   postAtts.isWarning = topic.is_warning;
   postAtts.links = post.get("internalLinks");
   postAtts.replyDirectlyBelow =
@@ -208,22 +199,17 @@ export default function transformPost(
   if (post.actions_summary) {
     postAtts.actionsSummary = post.actions_summary
       .filter(a => {
-        return a.actionType.name_key !== "like" && a.count > 0;
+        return a.actionType.name_key !== "like" && a.acted;
       })
       .map(a => {
-        const acted = a.acted;
         const action = a.actionType.name_key;
-        const count = a.count;
 
         return {
           id: a.id,
           postId: post.id,
           action,
-          acted,
-          count,
           canUndo: a.can_undo,
-          canIgnoreFlags: a.can_defer_flags,
-          description: actionDescription(action, acted, count)
+          description: I18n.t(`post.actions.by_you.${action}`)
         };
       });
   }
diff --git a/app/assets/javascripts/discourse/models/action-summary.js.es6 b/app/assets/javascripts/discourse/models/action-summary.js.es6
index 683f340..1071f7d 100644
--- a/app/assets/javascripts/discourse/models/action-summary.js.es6
+++ b/app/assets/javascripts/discourse/models/action-summary.js.es6
@@ -33,8 +33,6 @@ export default RestModel.extend({
   act(post, opts) {
     if (!opts) opts = {};
 
-    const action = this.get("actionType.name_key");
-
     // Mark it as acted
     this.setProperties({
       acted: true,
@@ -43,13 +41,7 @@ export default RestModel.extend({
       can_undo: true
     });
 
-    if (action === "notify_moderators" || action === "notify_user") {
-      this.set("can_undo", false);
-      this.set("can_defer_flags", false);
-    }
-
     // Create our post action
-    const self = this;
     return ajax("/post_actions", {
       type: "POST",
       data: {
@@ -62,8 +54,8 @@ export default RestModel.extend({
       },
       returnXHR: true
     })
-      .then(function(data) {
-        if (!self.get("flagTopic")) {
+      .then(data => {
+        if (!this.get("flagTopic")) {
           post.updateActionsSummary(data.result);
         }
         const remaining = parseInt(
@@ -74,9 +66,9 @@ export default RestModel.extend({
         );
         return { acted: true, remaining, max };
       })
-      .catch(function(error) {
+      .catch(error => {
         popupAjaxError(error);
-        self.removeAction(post);
+        this.removeAction(post);
       });
   },
 
@@ -92,12 +84,5 @@ export default RestModel.extend({
       post.updateActionsSummary(result);
       return { acted: false };
     });
-  },
-
-  deferFlags(post) {
-    return ajax("/post_actions/defer_flags", {
-      type: "POST",
-      data: { post_action_type_id: this.get("id"), id: post.get("id") }
-    }).then(() => this.set("count", 0));
   }
 });
diff --git a/app/assets/javascripts/discourse/widgets/actions-summary.js.es6 b/app/assets/javascripts/discourse/widgets/actions-summary.js.es6
index d15a3d7..56c32a6 100644
--- a/app/assets/javascripts/discourse/widgets/actions-summary.js.es6
+++ b/app/assets/javascripts/discourse/widgets/actions-summary.js.es6
@@ -74,57 +74,11 @@ createWidget("action-link", {
   }
 });
 
-createWidget("actions-summary-item", {
-  tagName: "div.post-action",
-  buildKey: attrs => `actions-summary-item-${attrs.id}`,
-
-  defaultState() {
-    return { users: null };
-  },
-
-  template: hbs`
-    {{#if state.users}}
-      {{small-user-list users=state.users description=(concat "post.actions.people." attrs.action)}}
-    {{else}}
-      {{action-link action="whoActed" text=attrs.description}}
-    {{/if}}
-
-    {{#if attrs.canUndo}}
-      {{action-link action="undo" className="undo" text=(i18n (concat "post.actions.undo." attrs.action))}}
-    {{/if}}
-
-    {{#if attrs.canIgnoreFlags}}
-      {{action-link action="deferFlags" className="defer-flags" text=(i18n "post.actions.defer_flags" count=attrs.count)}}
-    {{/if}}
-  `,
-
-  whoActed() {
-    const attrs = this.attrs;
-    const state = this.state;
-    return this.store
-      .find("post-action-user", {
-        id: attrs.postId,
-        post_action_type_id: attrs.id
-      })
-      .then(users => {
-        state.users = users.map(avatarAtts);
-      });
-  },
-
-  undo() {
-    this.sendWidgetAction("undoPostAction", this.attrs.id);
-  },
-
-  deferFlags() {
-    this.sendWidgetAction("deferPostActionFlags", this.attrs.id);
-  }
-});
-
 export default createWidget("actions-summary", {
   tagName: "section.post-actions",
   template: hbs`
     {{#each attrs.actionsSummary as |as|}}
-      {{actions-summary-item attrs=as}}
+      <div class='post-action'>{{as.description}}</div>
       <div class='clearfix'></div>
     {{/each}}
     {{#if attrs.deleted_at}}
diff --git a/app/assets/javascripts/discourse/widgets/post-menu.js.es6 b/app/assets/javascripts/discourse/widgets/post-menu.js.es6
index bab75ab..ebb94fc 100644
--- a/app/assets/javascripts/discourse/widgets/post-menu.js.es6
+++ b/app/assets/javascripts/discourse/widgets/post-menu.js.es6
@@ -64,7 +64,8 @@ registerButton("like", attrs => {
   const button = {
     action: "like",
     icon: attrs.liked ? "d-liked" : "d-unliked",
-    className
+    className,
+    before: "like-count"
   };
 
   // If the user has already liked the post and doesn't have permission
@@ -99,7 +100,7 @@ registerButton("like-count", attrs => {
     return {
       action: "toggleWhoLiked",
       title,
-      className: `like-count highlight-action ${additionalClass}`,
+      className: `button-count like-count highlight-action ${additionalClass}`,
       contents: count,
       icon,
       iconRight: true,
@@ -108,14 +109,30 @@ registerButton("like-count", attrs => {
   }
 });
 
+registerButton("flag-count", attrs => {
+  let className = "button-count";
+  if (attrs.reviewableScorePendingCount > 0) {
+    className += " has-pending";
+  }
+  return {
+    className,
+    contents: h("span", attrs.reviewableScoreCount.toString()),
+    url: `/review/${attrs.reviewableId}`
+  };
+});
+
 registerButton("flag", attrs => {
-  if (attrs.canFlag && !attrs.hidden) {
-    return {
+  if (attrs.reviewableId || (attrs.canFlag && !attrs.hidden)) {
+    let button = {
       action: "showFlags",
       title: "post.controls.flag",
       icon: "flag",
       className: "create-flag"
     };
+    if (attrs.reviewableId) {
+      button.before = "flag-count";
+    }
+    return button;
   }
 });
 

[... diff too long, it was truncated ...]

GitHub sha: 31e10053

Are those translations used anywhere else or do we want to use them somewhere else in the UI? Otherwise it would be a good idea to remove them from the locale file.

1 Like

Good call @gschlager - Remove unused translation keys · discourse/discourse@c403569 · GitHub

2 Likes

This commit has been mentioned on Discourse Meta. There might be relevant details there:

This commit has been mentioned on Discourse Meta. There might be relevant details there:

This commit has been mentioned on Discourse Meta. There might be relevant details there:

This commit has been mentioned on Discourse Meta. There might be relevant details there:

This commit has been mentioned on Discourse Meta. There might be relevant details there:

This commit has been mentioned on Discourse Meta. There might be relevant details there: