FEATURE: Add "Followed Up" button (#33)

FEATURE: Add “Followed Up” button (#33)

This button can be used by the original author, after they followed up, to remove assignment and move it back into the pending queue.

diff --git a/app/controllers/discourse_code_review/code_review_controller.rb b/app/controllers/discourse_code_review/code_review_controller.rb
index ef35c8b..975c015 100644
--- a/app/controllers/discourse_code_review/code_review_controller.rb
+++ b/app/controllers/discourse_code_review/code_review_controller.rb
@@ -95,6 +95,39 @@ module DiscourseCodeReview
       render_next_topic(topic.category_id)
     end
 
+    def followed_up
+      if !SiteSetting.code_review_allow_manual_followup
+        raise Discourse::InvalidAccess
+      end
+
+      topic = Topic.find_by(id: params[:topic_id])
+
+      tags = topic.tags.pluck(:name)
+
+      if tags.include?(SiteSetting.code_review_followup_tag)
+        tags -= [
+          SiteSetting.code_review_approved_tag,
+          SiteSetting.code_review_followup_tag
+        ]
+
+        tags << SiteSetting.code_review_pending_tag
+
+        DiscourseTagging.tag_topic_by_names(topic, Guardian.new(current_user), tags)
+
+        topic.add_moderator_post(
+          current_user,
+          nil,
+          bump: false,
+          post_type: Post.types[:small_action],
+          action_code: "followed_up"
+        )
+
+        DiscourseEvent.trigger(:unassign_topic, topic, current_user)
+      end
+
+      render json: success_json
+    end
+
     def approve
       topic = Topic.find_by(id: params[:topic_id])
 
diff --git a/assets/javascripts/discourse/initializers/init-code-review.js.es6 b/assets/javascripts/discourse/initializers/init-code-review.js.es6
index 7e4bee5..47af62c 100644
--- a/assets/javascripts/discourse/initializers/init-code-review.js.es6
+++ b/assets/javascripts/discourse/initializers/init-code-review.js.es6
@@ -85,6 +85,14 @@ function initialize(api) {
     );
   }
 
+  function allowFollowedUpButton(currentUser, topic, siteSettings) {
+    const followupTag = siteSettings.code_review_followup_tag;
+
+    const tags = topic.tags || [];
+
+    return currentUser.id === topic.user_id && tags.includes(followupTag);
+  }
+
   api.registerTopicFooterButton({
     id: "approve",
     icon: "thumbs-up",
@@ -150,6 +158,28 @@ function initialize(api) {
       );
     },
   });
+
+  api.registerTopicFooterButton({
+    id: "followed_up",
+    icon: "history",
+    priority: 240,
+    label: "code_review.followed_up.label",
+    title: "code_review.followed_up.title",
+    action() {
+      actOnCommit(this.topic, "followed_up");
+    },
+    dropdown() {
+      return this.site.mobileView;
+    },
+    classNames: ["followup"],
+    dependentKeys: ["topic.tags"],
+    displayed() {
+      return (
+        this.get("currentUser.staff") &&
+        allowFollowedUpButton(this.currentUser, this.topic, this.siteSettings)
+      );
+    },
+  });
 }
 
 export default {
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 951beeb..8a7a2f9 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -21,6 +21,9 @@ en:
       followup:
         title: "Follow up commit"
         label: "Follow Up"
+      followed_up:
+        title: "Followed up commit"
+        label: "Followed Up"
       skip:
         title: "Skip commit"
         label: "Skip"
diff --git a/plugin.rb b/plugin.rb
index c43b406..629c0c0 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -16,6 +16,7 @@ gem 'rugged', '0.28.4.1'
 enabled_site_setting :code_review_enabled
 
 register_asset 'stylesheets/code_review.scss'
+register_svg_icon 'history'
 
 require_dependency 'auth/github_authenticator'
 require_dependency 'lib/staff_constraint'
@@ -199,6 +200,7 @@ after_initialize do
     scope '/code-review' do
       post '/approve' => 'code_review#approve'
       post '/followup' => 'code_review#followup'
+      post '/followed_up' => 'code_review#followed_up'
       post '/skip' => 'code_review#skip'
       post '/webhook' => 'code_review#webhook'
       get "/redirect/:sha1" => 'code_review#redirect', constraints: { sha1: /[0-9a-fA-F]+/ }
diff --git a/spec/requests/discourse_code_review/code_review_controller_spec.rb b/spec/requests/discourse_code_review/code_review_controller_spec.rb
index 11422d8..cb6adac 100644
--- a/spec/requests/discourse_code_review/code_review_controller_spec.rb
+++ b/spec/requests/discourse_code_review/code_review_controller_spec.rb
@@ -290,6 +290,22 @@ describe DiscourseCodeReview::CodeReviewController do
       end
     end
 
+    context '.followed_up' do
+      it 'puts the topic back into pending' do
+        # If discourse-assign is present, we need to enable methods defined by the plugin.
+        SiteSetting.assign_enabled = true if defined?(TopicAssigner)
+
+        commit = create_post(raw: "this is a fake commit", user: signed_in_user, tags: ["hi", SiteSetting.code_review_followup_tag])
+
+        post '/code-review/followed_up.json', params: { topic_id: commit.topic_id }
+        expect(response.status).to eq(200)
+
+        commit.topic.reload
+
+        expect(commit.topic.tags.pluck(:name)).to include("hi", SiteSetting.code_review_pending_tag)
+      end
+    end
+
     context '.render_next_topic' do
       let(:other_user) { Fabricate(:admin) }
 

GitHub sha: 311edc33

This commit appears in #33 which was approved by eviltrout. It was merged by nbianca.