added "assign by staff mention" feature

when enabled if staff mentions other staff topic is auto-assigned
This commit is contained in:
Sam Saffron 2017-02-19 21:37:39 -05:00
parent 1c00569200
commit cb481b35f8
3 changed files with 102 additions and 38 deletions

View File

@ -2,6 +2,7 @@ en:
site_settings: site_settings:
assigns_public: "Allow general public to see topic assignments" assigns_public: "Allow general public to see topic assignments"
assigns_user_url_path: "Path to link all user links for assigned (use: {username} to subtitue username)" assigns_user_url_path: "Path to link all user links for assigned (use: {username} to subtitue username)"
assigns_by_staff_mention: "If a staff member mentions another staff member, topic is automatically assigned"
discourse_assign: discourse_assign:
assigned_to: "Topic assigned to @%{username}" assigned_to: "Topic assigned to @%{username}"
unassigned: "Topic was unassigned" unassigned: "Topic was unassigned"

View File

@ -1,4 +1,5 @@
plugins: plugins:
assigns_by_staff_mention: false
assigns_public: false assigns_public: false
assigns_user_url_path: assigns_user_url_path:
client: true client: true

138
plugin.rb
View File

@ -14,6 +14,92 @@ after_initialize do
end end
end end
class ::TopicAssigner
def self.auto_assign(post)
return unless SiteSetting.assigns_by_staff_mention
if post.user && post.user.staff? && post.topic.custom_fields["assigned_to_id"].nil?
if is_last_staff_post?(post) && user = mentioned_staff(post)
assigner = new(post.topic, post.user)
assigner.assign(user, silent: true)
end
end
end
def self.is_last_staff_post?(post)
Post.exec_sql("SELECT 1 FROM posts p
JOIN users u ON u.id = p.user_id AND (moderator OR admin)
WHERE p.deleted_at IS NULL AND p.topic_id = :topic_id
having max(post_number) = :post_number
",
topic_id: post.topic_id,
post_number: post.post_number
).to_a.length == 1
end
def self.mentioned_staff(post)
mentions = post.raw_mentions
if mentions.present?
User.where('moderator OR admin')
.where('username_lower IN (?)', mentions.map(&:downcase))
.first
end
end
def initialize(topic, user)
@assigned_by = user
@topic = topic
end
def assign(assign_to, silent: false)
@topic.custom_fields["assigned_to_id"] = assign_to.id
@topic.custom_fields["assigned_by_id"] = @assigned_by.id
@topic.save!
first_post = @topic.posts.find_by(post_number: 1)
first_post.publish_change_to_clients!(:revised,
{ reload_topic: true })
UserAction.log_action!(action_type: UserAction::ASSIGNED,
user_id: assign_to.id,
acting_user_id: @assigned_by.id,
target_post_id: first_post.id,
target_topic_id: @topic.id)
post_type = SiteSetting.assigns_public ? Post.types[:small_action] : Post.types[:whisper]
unless silent
@topic.add_moderator_post(@assigned_by,
I18n.t('discourse_assign.assigned_to',
username: assign_to.username),
{ bump: false,
post_type: post_type,
action_code: "assigned"})
unless @assigned_by.id == assign_to.id
Notification.create!(notification_type: Notification.types[:custom],
user_id: assign_to.id,
topic_id: @topic.id,
post_number: 1,
data: {
message: 'discourse_assign.assign_notification',
display_username: @assigned_by.username,
topic_title: @topic.title
}.to_json
)
end
end
end
def unassign()
end
end
class ::DiscourseAssign::AssignController < Admin::AdminController class ::DiscourseAssign::AssignController < Admin::AdminController
before_filter :ensure_logged_in before_filter :ensure_logged_in
@ -65,44 +151,11 @@ after_initialize do
raise Discourse::NotFound unless assign_to raise Discourse::NotFound unless assign_to
assigner = TopicAssigner.new(topic, current_user)
# perhaps?
#Scheduler::Defer.later "assign topic" do #Scheduler::Defer.later "assign topic" do
assigner.assign(assign_to)
topic.custom_fields["assigned_to_id"] = assign_to.id
topic.custom_fields["assigned_by_id"] = current_user.id
topic.save!
topic.posts.first.publish_change_to_clients!(:revised, { reload_topic: true })
UserAction.log_action!(action_type: UserAction::ASSIGNED,
user_id: assign_to.id,
acting_user_id: current_user.id,
target_post_id: topic.posts.find_by(post_number: 1).id,
target_topic_id: topic.id)
post_type = SiteSetting.assigns_public ? Post.types[:small_action] : Post.types[:whisper]
topic.add_moderator_post(current_user,
I18n.t('discourse_assign.assigned_to',
username: assign_to.username),
{ bump: false,
post_type: post_type,
action_code: "assigned"})
unless current_user.id == assign_to.id
Notification.create!(notification_type: Notification.types[:custom],
user_id: assign_to.id,
topic_id: topic.id,
post_number: 1,
data: {
message: 'discourse_assign.assign_notification',
display_username: current_user.username,
topic_title: topic.title
}.to_json
)
end
render json: success_json render json: success_json
end end
@ -220,6 +273,15 @@ after_initialize do
Discourse::Application.routes.append do Discourse::Application.routes.append do
mount ::DiscourseAssign::Engine, at: "/assign" mount ::DiscourseAssign::Engine, at: "/assign"
end end
end
on(:post_created) do |post|
::TopicAssigner.auto_assign(post)
end
on(:post_edited) do |post, topic_changed|
::TopicAssigner.auto_assign(post)
end
end end
end