FEATURE: do not suggest users on vacation (#395)

This commit is contained in:
Andrei Prigorshnev 2022-12-14 12:42:17 +04:00 committed by GitHub
parent feca27b6bd
commit 31d1a798f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 17 deletions

View File

@ -6,22 +6,7 @@ module DiscourseAssign
before_action :ensure_logged_in, :ensure_assign_allowed before_action :ensure_logged_in, :ensure_assign_allowed
def suggestions def suggestions
users = [current_user] users = [current_user, *recent_assignees]
users +=
User
.where("users.id <> ?", current_user.id)
.joins(<<~SQL)
JOIN(
SELECT assigned_to_id user_id, MAX(created_at) last_assigned
FROM assignments
WHERE assignments.assigned_to_type = 'User'
GROUP BY assigned_to_id
HAVING COUNT(*) < #{SiteSetting.max_assigned_topics}
) as X ON X.user_id = users.id
SQL
.assign_allowed
.order("X.last_assigned DESC")
.limit(6)
render json: { render json: {
assign_allowed_on_groups: assign_allowed_on_groups:
@ -279,5 +264,30 @@ module DiscourseAssign
def user_menu_limit def user_menu_limit
UsersController::USER_MENU_LIST_LIMIT UsersController::USER_MENU_LIST_LIMIT
end end
def recent_assignees
User
.where("users.id <> ?", current_user.id)
.joins(<<~SQL)
JOIN(
SELECT assigned_to_id user_id, MAX(created_at) last_assigned
FROM assignments
WHERE assignments.assigned_to_type = 'User'
GROUP BY assigned_to_id
HAVING COUNT(*) < #{SiteSetting.max_assigned_topics}
) as X ON X.user_id = users.id
SQL
.joins(<<~SQL)
LEFT JOIN(
SELECT DISTINCT ON (user_id) name, user_id
FROM user_custom_fields
WHERE name = '#{DiscourseCalendar::HOLIDAY_CUSTOM_FIELD}'
) AS ucf on ucf.user_id = users.id
SQL
.where("ucf.name is NULL")
.assign_allowed
.order("X.last_assigned DESC")
.limit(6)
end
end end
end end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
module DiscourseAssign
module DiscourseCalendar
HOLIDAY_CUSTOM_FIELD ||= 'on_holiday'
end
end

View File

@ -17,6 +17,7 @@ register_asset "stylesheets/mobile/assigns.scss", :mobile
load File.expand_path("../lib/discourse_assign/engine.rb", __FILE__) load File.expand_path("../lib/discourse_assign/engine.rb", __FILE__)
load File.expand_path("../lib/discourse_assign/helpers.rb", __FILE__) load File.expand_path("../lib/discourse_assign/helpers.rb", __FILE__)
load File.expand_path("../lib/validators/assign_statuses_validator.rb", __FILE__) load File.expand_path("../lib/validators/assign_statuses_validator.rb", __FILE__)
load File.expand_path("../lib/discourse_calendar.rb", __FILE__)
Discourse::Application.routes.append do Discourse::Application.routes.append do
mount ::DiscourseAssign::Engine, at: "/assign" mount ::DiscourseAssign::Engine, at: "/assign"

View File

@ -94,11 +94,39 @@ RSpec.describe DiscourseAssign::AssignController do
describe "#suggestions" do describe "#suggestions" do
before do before do
SiteSetting.max_assigned_topics = 1
sign_in(user) sign_in(user)
end end
it "suggests the current user + the last 6 previously assigned users" do
assignees = 10.times.map { |_| assign_user_to_post.username }
get "/assign/suggestions.json"
suggestions = response.parsed_body["suggestions"].map { |u| u["username"] }
expect(suggestions).to contain_exactly(user.username, *assignees[4..9])
end
it "doesn't suggest users on holiday" do
user_on_vacation = assign_user_to_post
user_on_vacation.upsert_custom_fields(DiscourseAssign::DiscourseCalendar::HOLIDAY_CUSTOM_FIELD => "t")
get "/assign/suggestions.json"
suggestions = response.parsed_body["suggestions"].map { |u| u["username"] }
expect(suggestions).to_not include(user_on_vacation.username)
end
it "suggests the current user even if they're on holiday" do
user.upsert_custom_fields(DiscourseAssign::DiscourseCalendar::HOLIDAY_CUSTOM_FIELD => "t")
get "/assign/suggestions.json"
suggestions = response.parsed_body["suggestions"].map { |u| u["username"] }
expect(suggestions).to include(user.username)
end
it "excludes other users from the suggestions when they already reached the max assigns limit" do it "excludes other users from the suggestions when they already reached the max assigns limit" do
SiteSetting.max_assigned_topics = 1
another_admin = Fabricate(:admin, groups: [default_allowed_group]) another_admin = Fabricate(:admin, groups: [default_allowed_group])
Assigner.new(post.topic, user).assign(another_admin) Assigner.new(post.topic, user).assign(another_admin)
@ -107,6 +135,13 @@ RSpec.describe DiscourseAssign::AssignController do
expect(suggestions).to contain_exactly(user.username) expect(suggestions).to contain_exactly(user.username)
end end
def assign_user_to_post
assignee = Fabricate(:user, groups: [default_allowed_group])
post = Fabricate(:post)
Assigner.new(post.topic, user).assign(assignee)
assignee
end
end end
describe "#assign" do describe "#assign" do