From 0d5e1a8307e2792acc1179223e1d756a7c3a1d9c Mon Sep 17 00:00:00 2001 From: Marius BALTEANU Date: Tue, 10 Sep 2019 09:41:59 +0300 Subject: [PATCH] Demo for acts_as_mentionable --- app/controllers/auto_completes_controller.rb | 23 +++++ app/models/issue.rb | 2 + app/models/journal.rb | 1 + app/models/mailer.rb | 23 ++++- app/models/wiki_content.rb | 3 + app/views/documents/_form.html.erb | 3 +- app/views/issues/_edit.html.erb | 3 +- app/views/issues/_form.html.erb | 3 +- app/views/issues/bulk_edit.html.erb | 3 +- app/views/journals/_notes_form.html.erb | 3 +- app/views/mailer/issue_add.html.erb | 3 + app/views/mailer/issue_edit.html.erb | 3 + app/views/mailer/user_mentioned.html.erb | 0 app/views/mailer/user_mentioned.text.erb | 0 app/views/messages/_form.html.erb | 3 +- app/views/news/_form.html.erb | 3 +- app/views/news/show.html.erb | 3 +- app/views/wiki/edit.html.erb | 3 +- config/routes.rb | 1 + lib/redmine.rb | 1 + lib/redmine/acts/mentionable.rb | 94 +++++++++++++++++++ public/javascripts/application.js | 51 +++++++--- .../auto_completes_controller_test.rb | 57 +++++++++-- 23 files changed, 254 insertions(+), 35 deletions(-) create mode 100644 app/views/mailer/user_mentioned.html.erb create mode 100644 app/views/mailer/user_mentioned.text.erb create mode 100644 lib/redmine/acts/mentionable.rb diff --git a/app/controllers/auto_completes_controller.rb b/app/controllers/auto_completes_controller.rb index c0a0c242a..a0ad3626f 100644 --- a/app/controllers/auto_completes_controller.rb +++ b/app/controllers/auto_completes_controller.rb @@ -42,6 +42,19 @@ class AutoCompletesController < ApplicationController render :json => format_issues_json(issues) end + def users + users = [] + q = (params[:q] || params[:term]).to_s.strip + scope = nil + if params[:q].blank? && @project.present? + scope = @project.users + else + scope = User.all.limit(10) + end + users = scope.active.visible.sorted.like(params[:q]).to_a + render :json => format_users_json(users) + end + private def find_project @@ -61,4 +74,14 @@ class AutoCompletesController < ApplicationController } } end + + def format_users_json(users) + users.map {|user| { + 'firstname' => user.firstname, + 'lastname' => user.lastname, + 'name' => user.name, + 'login' => user.login + } + } + end end diff --git a/app/models/issue.rb b/app/models/issue.rb index 487b1b552..fad34ddc8 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -54,6 +54,8 @@ class Issue < ActiveRecord::Base acts_as_activity_provider :scope => preload(:project, :author, :tracker, :status), :author_key => :author_id + acts_as_mentionable :attributes => ['description'] + DONE_RATIO_OPTIONS = %w(issue_field issue_status) attr_reader :transition_warning diff --git a/app/models/journal.rb b/app/models/journal.rb index e60605161..fb6ba46bd 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -42,6 +42,7 @@ class Journal < ActiveRecord::Base joins("LEFT OUTER JOIN #{JournalDetail.table_name} ON #{JournalDetail.table_name}.journal_id = #{Journal.table_name}.id"). where("#{Journal.table_name}.journalized_type = 'Issue' AND" + " (#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')").distinct + acts_as_mentionable :attributes => ['notes'] before_create :split_private_notes after_create_commit :send_notification diff --git a/app/models/mailer.rb b/app/models/mailer.rb index 590199ed8..20c817450 100644 --- a/app/models/mailer.rb +++ b/app/models/mailer.rb @@ -68,7 +68,7 @@ class Mailer < ActionMailer::Base end # Builds a mail for notifying user about a new issue - def issue_add(user, issue) + def issue_add(user, issue, reason = nil) redmine_headers 'Project' => issue.project.identifier, 'Issue-Tracker' => issue.tracker.name, 'Issue-Id' => issue.id, @@ -79,6 +79,7 @@ class Mailer < ActionMailer::Base @author = issue.author @issue = issue @user = user + @reason = reason @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue) subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]" subject += " (#{issue.status.name})" if Setting.show_status_changes_in_mail_subject? @@ -93,13 +94,19 @@ class Mailer < ActionMailer::Base # Mailer.deliver_issue_add(issue) def self.deliver_issue_add(issue) users = issue.notified_users | issue.notified_watchers + users.each do |user| issue_add(user, issue).deliver_later end + + mentions = issue.notified_mentions + users.each do |user| + issue_add(user, issue, 'mentioned').deliver_later + end end # Builds a mail for notifying user about an issue update - def issue_edit(user, journal) + def issue_edit(user, journal, reason = nil) issue = journal.journalized redmine_headers 'Project' => issue.project.identifier, 'Issue-Tracker' => issue.tracker.name, @@ -115,6 +122,7 @@ class Mailer < ActionMailer::Base @issue = issue @user = user @journal = journal + @reason = reason @journal_details = journal.visible_details @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}") @@ -128,12 +136,18 @@ class Mailer < ActionMailer::Base # Mailer.deliver_issue_edit(journal) def self.deliver_issue_edit(journal) users = journal.notified_users | journal.notified_watchers + users.select! do |user| journal.notes? || journal.visible_details(user).any? end users.each do |user| issue_edit(user, journal).deliver_later end + + notified_mentions = journal.journalized.notified_mentions | journal.notified_mentions + notified_mentions.each do |user| + issue_edit(user, journal, 'mentioned').deliver_later + end end # Builds a mail to user about a new document. @@ -220,7 +234,7 @@ class Mailer < ActionMailer::Base # Example: # Mailer.deliver_news_added(news) def self.deliver_news_added(news) - users = news.notified_users | news.notified_watchers_for_added_news + users = news.notified_users | news.notified_watchers_for_added_news | news.notified_mentions users.each do |user| news_added(user, news).deliver_later end @@ -301,7 +315,7 @@ class Mailer < ActionMailer::Base # Example: # Mailer.deliver_wiki_content_added(wiki_content) def self.deliver_wiki_content_added(wiki_content) - users = wiki_content.notified_users | wiki_content.page.wiki.notified_watchers + users = wiki_content.notified_users | wiki_content.page.wiki.notified_watchers | wiki_content.notified_mentions users.each do |user| wiki_content_added(user, wiki_content).deliver_later end @@ -333,6 +347,7 @@ class Mailer < ActionMailer::Base users = wiki_content.notified_users users |= wiki_content.page.notified_watchers users |= wiki_content.page.wiki.notified_watchers + users |= wiki_content.notified_mentions users.each do |user| wiki_content_updated(user, wiki_content).deliver_later diff --git a/app/models/wiki_content.rb b/app/models/wiki_content.rb index e64affff9..b826209ff 100644 --- a/app/models/wiki_content.rb +++ b/app/models/wiki_content.rb @@ -24,6 +24,9 @@ class WikiContent < ActiveRecord::Base belongs_to :page, :class_name => 'WikiPage' belongs_to :author, :class_name => 'User' has_many :versions, :class_name => 'WikiContentVersion', :dependent => :delete_all + + acts_as_mentionable :attributes => ['text'] + validates_presence_of :text validates_length_of :comments, :maximum => 1024, :allow_nil => true diff --git a/app/views/documents/_form.html.erb b/app/views/documents/_form.html.erb index b8b8c8404..29064f469 100644 --- a/app/views/documents/_form.html.erb +++ b/app/views/documents/_form.html.erb @@ -6,7 +6,8 @@

<%= f.text_area :description, :cols => 60, :rows => 15, :class => 'wiki-edit', :data => { :auto_complete => true, - :issues_url => auto_complete_issues_path(:project_id => @project, :q => '') + :issues_url => auto_complete_issues_path(:project_id => @project, :q => ''), + :users_url => auto_complete_users_path(:project_id => @project, :q => '') } %>

diff --git a/app/views/issues/_edit.html.erb b/app/views/issues/_edit.html.erb index cc2f110b7..0286435f6 100644 --- a/app/views/issues/_edit.html.erb +++ b/app/views/issues/_edit.html.erb @@ -32,7 +32,8 @@ <%= f.text_area :notes, :cols => 60, :rows => 10, :class => 'wiki-edit', :data => { :auto_complete => true, - :issues_url => auto_complete_issues_path(:project_id => @issue.project, :q => '') + :issues_url => auto_complete_issues_path(:project_id => @issue.project, :q => ''), + :users_url => auto_complete_users_path(:project_id => @issue.project, :q => '') }, :no_label => true %> <%= wikitoolbar_for 'issue_notes', preview_issue_path(:project_id => @project, :issue_id => @issue) %> diff --git a/app/views/issues/_form.html.erb b/app/views/issues/_form.html.erb index 214502b0a..cfa952f93 100644 --- a/app/views/issues/_form.html.erb +++ b/app/views/issues/_form.html.erb @@ -38,7 +38,8 @@ :rows => [[10, @issue.description.to_s.length / 50].max, 20].min, :data => { :auto_complete => true, - :issues_url => auto_complete_issues_path(:project_id => @issue.project, :q => '') + :issues_url => auto_complete_issues_path(:project_id => @issue.project, :q => ''), + :users_url => auto_complete_users_path(:project_id => @issue.project, :q => '') }, :no_label => true %> <% end %> diff --git a/app/views/issues/bulk_edit.html.erb b/app/views/issues/bulk_edit.html.erb index f5590e9bc..8e0e2a405 100644 --- a/app/views/issues/bulk_edit.html.erb +++ b/app/views/issues/bulk_edit.html.erb @@ -197,7 +197,8 @@ <%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit', :data => { :auto_complete => true, - :issues_url => auto_complete_issues_path(:project_id => @project, :q => '') + :issues_url => auto_complete_issues_path(:project_id => @project, :q => ''), + :users_url => auto_complete_users_path(:project_id => @project, :q => '') } %> <%= wikitoolbar_for 'notes' %> diff --git a/app/views/journals/_notes_form.html.erb b/app/views/journals/_notes_form.html.erb index aeb4b6a93..882120932 100644 --- a/app/views/journals/_notes_form.html.erb +++ b/app/views/journals/_notes_form.html.erb @@ -7,7 +7,8 @@ :rows => (@journal.notes.blank? ? 10 : [[10, @journal.notes.length / 50].max, 100].min), :data => { :auto_complete => true, - :issues_url => auto_complete_issues_path(:project_id => @project, :q => '') + :issues_url => auto_complete_issues_path(:project_id => @project, :q => ''), + :users_url => auto_complete_users_path(:project_id => @project, :q => '') } %> <% if @journal.safe_attribute? 'private_notes' %> diff --git a/app/views/mailer/issue_add.html.erb b/app/views/mailer/issue_add.html.erb index 7bb6115b5..312279030 100644 --- a/app/views/mailer/issue_add.html.erb +++ b/app/views/mailer/issue_add.html.erb @@ -1,3 +1,6 @@ <%= l(:text_issue_added, :id => link_to("##{@issue.id}", @issue_url), :author => h(@issue.author)).html_safe %> +<% unless @reason.nil? %> + You have been mentioned in it. +<% end %>
<%= render :partial => 'issue', :formats => [:html], :locals => { :issue => @issue, :user => @user, :issue_url => @issue_url } %> diff --git a/app/views/mailer/issue_edit.html.erb b/app/views/mailer/issue_edit.html.erb index b5bdd88ee..7b5b28fec 100644 --- a/app/views/mailer/issue_edit.html.erb +++ b/app/views/mailer/issue_edit.html.erb @@ -2,6 +2,9 @@ (<%= l(:field_private_notes) %>) <% end %> <%= l(:text_issue_updated, :id => link_to("##{@issue.id}", @issue_url), :author => h(@journal.user)).html_safe %> +<% unless @reason.nil? %> + You have been mentioned in it. +<% end %>