diff --git a/app/assets/javascripts/discourse/app/controllers/review-index.js b/app/assets/javascripts/discourse/app/controllers/review-index.js index 7ea2523e87e..e1e003870dc 100644 --- a/app/assets/javascripts/discourse/app/controllers/review-index.js +++ b/app/assets/javascripts/discourse/app/controllers/review-index.js @@ -11,6 +11,7 @@ export default Controller.extend({ "category_id", "topic_id", "username", + "reviewed_by", "from_date", "to_date", "sort_order", @@ -24,6 +25,7 @@ export default Controller.extend({ topic_id: null, filtersExpanded: false, username: "", + reviewed_by: "", from_date: null, to_date: null, sort_order: null, @@ -147,6 +149,7 @@ export default Controller.extend({ status: this.filterStatus, category_id: this.filterCategoryId, username: this.filterUsername, + reviewed_by: this.filterReviewedBy, from_date: isPresent(this.filterFromDate) ? this.filterFromDate.toISOString(true).split("T")[0] : null, diff --git a/app/assets/javascripts/discourse/app/routes/review-index.js b/app/assets/javascripts/discourse/app/routes/review-index.js index 13d10724f2e..b4d15e68e1e 100644 --- a/app/assets/javascripts/discourse/app/routes/review-index.js +++ b/app/assets/javascripts/discourse/app/routes/review-index.js @@ -32,6 +32,7 @@ export default DiscourseRoute.extend({ filterPriority: meta.priority, reviewableTypes: meta.reviewable_types, filterUsername: meta.username, + filterReviewedBy: meta.reviewed_by, filterFromDate: isPresent(meta.from_date) ? moment(meta.from_date) : null, filterToDate: isPresent(meta.to_date) ? moment(meta.to_date) : null, filterSortOrder: meta.sort_order, diff --git a/app/assets/javascripts/discourse/app/templates/review-index.hbs b/app/assets/javascripts/discourse/app/templates/review-index.hbs index c5a0fad8891..322ba824c21 100644 --- a/app/assets/javascripts/discourse/app/templates/review-index.hbs +++ b/app/assets/javascripts/discourse/app/templates/review-index.hbs @@ -58,6 +58,17 @@ }} +
+ {{i18n "review.filtered_reviewed_by"}} + {{user-selector + excludeCurrentUser=false + usernames=filterReviewedBy + fullWidthWrap=true + single=true + class="user-selector" + canReceiveUpdates=true}} +
+
{{i18n "review.filtered_user"}} {{user-selector diff --git a/app/controllers/reviewables_controller.rb b/app/controllers/reviewables_controller.rb index 65de25b429f..874a678c32a 100644 --- a/app/controllers/reviewables_controller.rb +++ b/app/controllers/reviewables_controller.rb @@ -30,7 +30,7 @@ class ReviewablesController < ApplicationController additional_filters: additional_filters.reject { |_, v| v.blank? } } - %i[priority username from_date to_date type sort_order].each do |filter_key| + %i[priority username reviewed_by from_date to_date type sort_order].each do |filter_key| filters[filter_key] = params[filter_key] end diff --git a/app/models/reviewable.rb b/app/models/reviewable.rb index c26efaedb4b..6adcb6ae422 100644 --- a/app/models/reviewable.rb +++ b/app/models/reviewable.rb @@ -437,6 +437,7 @@ class Reviewable < ActiveRecord::Base offset: nil, priority: nil, username: nil, + reviewed_by: nil, sort_order: nil, from_date: nil, to_date: nil, @@ -470,6 +471,21 @@ class Reviewable < ActiveRecord::Base result = result.where("reviewables.created_at >= ?", from_date) if from_date result = result.where("reviewables.created_at <= ?", to_date) if to_date + if reviewed_by + reviewed_by_id = User.find_by_username(reviewed_by)&.id + return [] if reviewed_by_id.nil? + + result = result.joins(<<~SQL + INNER JOIN( + SELECT reviewable_id + FROM reviewable_histories + WHERE reviewable_history_type = #{ReviewableHistory.types[:transitioned]} AND + status <> #{Reviewable.statuses[:pending]} AND created_by_id = #{reviewed_by_id} + ) AS rh ON rh.reviewable_id = reviewables.id + SQL + ) + end + if min_score > 0 && status == :pending result = result.where("reviewables.score >= ? OR reviewables.force_review", min_score) elsif min_score > 0 diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 7a81c069845..b1fcd40bc91 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -457,6 +457,7 @@ en: topic: "Topic:" filtered_topic: "You have filtered to reviewable content in a single topic." filtered_user: "User" + filtered_reviewed_by: "Reviewed By" show_all_topics: "show all topics" deleted_post: "(post deleted)" deleted_user: "(user deleted)" diff --git a/spec/models/reviewable_spec.rb b/spec/models/reviewable_spec.rb index e5246ef05dd..2572da5e906 100644 --- a/spec/models/reviewable_spec.rb +++ b/spec/models/reviewable_spec.rb @@ -149,6 +149,18 @@ RSpec.describe Reviewable, type: :model do expect(reviewables).not_to include(qp) end + it 'can filter by who reviewed the flag' do + reviewable = Fabricate(:reviewable_flagged_post) + admin = Fabricate(:admin) + reviewable.perform(admin, :ignore) + + reviewables = Reviewable.list_for( + user, status: :all, reviewed_by: admin.username + ) + + expect(reviewables).to contain_exactly(reviewable) + end + it 'Does not filter by status when status parameter is set to all' do rejected_reviewable = Fabricate(:reviewable, target: post, status: Reviewable.statuses[:rejected]) reviewables = Reviewable.list_for(user, status: :all)