diff --git a/app/controllers/discourse_assign/assign_controller.rb b/app/controllers/discourse_assign/assign_controller.rb index d49260a..8e3efaa 100644 --- a/app/controllers/discourse_assign/assign_controller.rb +++ b/app/controllers/discourse_assign/assign_controller.rb @@ -48,6 +48,7 @@ module DiscourseAssign target_type = params.require(:target_type) username = params.permit(:username)['username'] group_name = params.permit(:group_name)['group_name'] + priority = (params.permit(:priority)['priority'])&.to_i assign_to = username.present? ? User.find_by(username_lower: username.downcase) : Group.where("LOWER(name) = ?", group_name.downcase).first @@ -56,7 +57,7 @@ module DiscourseAssign target = target_type.constantize.where(id: target_id).first raise Discourse::NotFound unless target - assign = Assigner.new(target, current_user).assign(assign_to) + assign = Assigner.new(target, current_user).assign(assign_to, priority: priority) if assign[:success] render json: success_json diff --git a/app/models/assignment.rb b/app/models/assignment.rb index 1563ab6..b6e3f0b 100644 --- a/app/models/assignment.rb +++ b/app/models/assignment.rb @@ -8,6 +8,13 @@ class Assignment < ActiveRecord::Base belongs_to :assigned_by_user, class_name: "User" belongs_to :target, polymorphic: true + enum priority: { + low: 4, + medium: 3, + high: 2, + urgent: 1, + }, _prefix: true + scope :joins_with_topics, -> { joins("INNER JOIN topics ON topics.id = assignments.target_id AND assignments.target_type = 'Topic' AND topics.deleted_at IS NULL") } def self.valid_type?(type) @@ -37,6 +44,7 @@ end # target_id :integer not null # target_type :string not null # active :boolean default(TRUE) +# priority :integer # # Indexes # diff --git a/lib/assigner.rb b/lib/assigner.rb index 73b9838..0801d1f 100644 --- a/lib/assigner.rb +++ b/lib/assigner.rb @@ -199,7 +199,7 @@ class ::Assigner end end - def assign(assign_to, silent: false) + def assign(assign_to, priority: nil, silent: false) type = assign_to.is_a?(User) ? "User" : "Group" forbidden_reason = forbidden_reasons(assign_to: assign_to, type: type) @@ -211,7 +211,7 @@ class ::Assigner @target.assignment&.destroy! - assignment = @target.create_assignment!(assigned_to_id: assign_to.id, assigned_to_type: type, assigned_by_user_id: @assigned_by.id, topic_id: topic.id) + assignment = @target.create_assignment!(assigned_to_id: assign_to.id, assigned_to_type: type, assigned_by_user_id: @assigned_by.id, topic_id: topic.id, priority: priority) first_post.publish_change_to_clients!(:revised, reload_topic: true) diff --git a/plugin.rb b/plugin.rb index c1bac32..98761f6 100644 --- a/plugin.rb +++ b/plugin.rb @@ -484,6 +484,14 @@ after_initialize do (SiteSetting.assigns_public || scope.can_assign?) && object.topic.indirectly_assigned_to.present? end + add_to_serializer(:topic_view, :assignment_priority, false) do + Assignment.priorities[object.topic.assignment.priority] + end + + add_to_serializer(:topic_view, :include_assignment_priority?, false) do + (SiteSetting.assigns_public || scope.can_assign?) && object.topic.assignment.present? + end + # SuggestedTopic serializer add_to_serializer(:suggested_topic, :assigned_to_user, false) do DiscourseAssign::Helpers.build_assigned_to_user(object.assigned_to, object) @@ -631,6 +639,14 @@ after_initialize do (SiteSetting.assigns_public || scope.can_assign?) && object.assignment&.assigned_to&.is_a?(Group) && object.assignment.active end + add_to_serializer(:post, :assignment_priority, false) do + Assignment.priorities[object.assignment.priority] + end + + add_to_serializer(:post, :include_assignment_priority?, false) do + (SiteSetting.assigns_public || scope.can_assign?) && object.assignment.present? + end + # CurrentUser serializer add_to_serializer(:current_user, :can_assign) do object.can_assign? diff --git a/spec/lib/assigner_spec.rb b/spec/lib/assigner_spec.rb index 4db6669..87ca08b 100644 --- a/spec/lib/assigner_spec.rb +++ b/spec/lib/assigner_spec.rb @@ -43,6 +43,12 @@ RSpec.describe Assigner do .to eq(TopicUser.notification_levels[:tracking]) end + it "can assign with priority" do + assigner.assign(moderator, priority: 2) + + expect(topic.assignment.priority_high?).to eq true + end + it 'does not update notification level if already watching' do TopicUser.change(moderator.id, topic.id, notification_level: TopicUser.notification_levels[:watching] diff --git a/spec/requests/assign_controller_spec.rb b/spec/requests/assign_controller_spec.rb index e563adb..2835269 100644 --- a/spec/requests/assign_controller_spec.rb +++ b/spec/requests/assign_controller_spec.rb @@ -116,6 +116,15 @@ RSpec.describe DiscourseAssign::AssignController do expect(post.topic.reload.assignment.assigned_to_id).to eq(user2.id) end + it 'assigns topic with priority to a user' do + put '/assign/assign.json', params: { + target_id: post.topic_id, target_type: 'Topic', username: user2.username, priority: 4 + } + + topicPriority = post.topic.reload.assignment.priority + expect(Assignment.priorities[topicPriority]).to eq(4) + end + it 'assigns topic to a group' do put '/assign/assign.json', params: { target_id: post.topic_id, target_type: 'Topic', group_name: assign_allowed_group.name diff --git a/spec/serializers/post_serializer_spec.rb b/spec/serializers/post_serializer_spec.rb index 80742fd..16378ca 100644 --- a/spec/serializers/post_serializer_spec.rb +++ b/spec/serializers/post_serializer_spec.rb @@ -29,4 +29,10 @@ RSpec.describe PostSerializer do expect(serializer.as_json[:post][:assigned_to_group].id).to eq(assign_allowed_group.id) expect(serializer.as_json[:post][:assigned_to_user]).to be nil end + + it "includes priority in serializer" do + Assigner.new(post, user).assign(user, priority: 1) + serializer = PostSerializer.new(post, scope: guardian) + expect(serializer.as_json[:post][:assignment_priority]).to eq(1) + end end diff --git a/spec/serializers/topic_view_serializer_spec.rb b/spec/serializers/topic_view_serializer_spec.rb new file mode 100644 index 0000000..14f657b --- /dev/null +++ b/spec/serializers/topic_view_serializer_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'rails_helper' +require_relative '../support/assign_allowed_group' + +RSpec.describe TopicViewSerializer do + fab!(:user) { Fabricate(:user) } + fab!(:topic) { Fabricate(:topic) } + fab!(:post) { Fabricate(:post, topic: topic) } + let(:guardian) { Guardian.new(user) } + + include_context 'A group that is allowed to assign' + + before do + SiteSetting.assign_enabled = true + add_to_assign_allowed_group(user) + end + + it "includes assigned user in serializer" do + Assigner.new(topic, user).assign(user) + serializer = TopicViewSerializer.new(TopicView.new(topic), scope: guardian) + expect(serializer.as_json[:topic_view][:assigned_to_user][:username]).to eq(user.username) + expect(serializer.as_json[:topic_view][:assigned_to_group]).to be nil + end + + it "includes assigned group in serializer" do + Assigner.new(topic, user).assign(assign_allowed_group) + serializer = TopicViewSerializer.new(TopicView.new(topic), scope: guardian) + expect(serializer.as_json[:topic_view][:assigned_to_group][:name]).to eq(assign_allowed_group.name) + expect(serializer.as_json[:topic_view][:assigned_to_user]).to be nil + end + + it "includes priority in serializer" do + Assigner.new(topic, user).assign(user, priority: 1) + serializer = TopicViewSerializer.new(TopicView.new(topic), scope: guardian) + expect(serializer.as_json[:topic_view][:assignment_priority]).to eq(1) + end +end