summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier Castro <javiercastro@nexion.com.ar>2013-05-09 20:37:47 -0300
committerJavier Castro <javiercastro@nexion.com.ar>2013-06-24 11:55:44 -0300
commitcf35d19c2ef6afd04b7339e5425f2f4a015e6acf (patch)
tree43c794093165a85a726b177207337db980a5af5a
parenta324960d92d4c2436064329137857686d90100b5 (diff)
downloadgitlab-ce-cf35d19c2ef6afd04b7339e5425f2f4a015e6acf.tar.gz
Show participants on issues, including mentions, and notify email to all participants
-rw-r--r--app/assets/stylesheets/sections/issues.scss4
-rw-r--r--app/helpers/projects_helper.rb6
-rw-r--r--app/models/concerns/issuable.rb15
-rw-r--r--app/models/concerns/mentionable.rb37
-rw-r--r--app/models/note.rb2
-rw-r--r--app/services/notification_service.rb15
-rw-r--r--app/views/issues/show.html.haml5
-rw-r--r--spec/services/notification_service_spec.rb5
8 files changed, 81 insertions, 8 deletions
diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss
index 5a1b476fe25..ed7902fec3a 100644
--- a/app/assets/stylesheets/sections/issues.scss
+++ b/app/assets/stylesheets/sections/issues.scss
@@ -106,3 +106,7 @@ input.check_all_issues {
#update_status {
width: 100px;
}
+
+.participants {
+ margin-bottom: 10px;
+}
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 878b0913769..39290ec05bb 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -17,7 +17,7 @@ module ProjectsHelper
end
def link_to_member(project, author, opts = {})
- default_opts = { avatar: true }
+ default_opts = { avatar: true, name: true, size: 16 }
opts = default_opts.merge(opts)
return "(deleted)" unless author
@@ -25,10 +25,10 @@ module ProjectsHelper
author_html = ""
# Build avatar image tag
- author_html << image_tag(gravatar_icon(author.try(:email)), width: 16, class: "avatar avatar-inline s16") if opts[:avatar]
+ author_html << image_tag(gravatar_icon(author.try(:email), opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}") if opts[:avatar]
# Build name span tag
- author_html << content_tag(:span, sanitize(author.name), class: 'author')
+ author_html << content_tag(:span, sanitize(author.name), class: 'author') if opts[:name]
author_html = author_html.html_safe
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 11e3d8eed19..38440859064 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -6,6 +6,7 @@
#
module Issuable
extend ActiveSupport::Concern
+ include Mentionable
included do
belongs_to :project
@@ -97,4 +98,18 @@ module Issuable
def votes_count
upvotes + downvotes
end
+
+ # Return all users participating on the discussion
+ def participants
+ users = []
+ users << author
+ users << assignee if is_assigned?
+ mentions = []
+ mentions << self.mentioned_users
+ notes.each do |note|
+ users << note.author
+ mentions << note.mentioned_users
+ end
+ users.concat(mentions.reduce([], :|)).uniq
+ end
end
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb
new file mode 100644
index 00000000000..f22070f8504
--- /dev/null
+++ b/app/models/concerns/mentionable.rb
@@ -0,0 +1,37 @@
+# == Mentionable concern
+#
+# Contains common functionality shared between Issues and Notes
+#
+# Used by Issue, Note
+#
+module Mentionable
+ extend ActiveSupport::Concern
+
+ def mentioned_users
+ users = []
+ return users if mentionable_text.blank?
+ has_project = self.respond_to? :project
+ matches = mentionable_text.scan(/@[a-zA-Z][a-zA-Z0-9_\-\.]*/)
+ matches.each do |match|
+ identifier = match.delete "@"
+ if has_project
+ id = project.users_projects.joins(:user).where(users: { username: identifier }).pluck(:user_id).first
+ else
+ id = User.where(username: identifier).pluck(:id).first
+ end
+ users << User.find(id) unless id.blank?
+ end
+ users.uniq
+ end
+
+ def mentionable_text
+ if self.class == Issue
+ description
+ elsif self.class == Note
+ note
+ else
+ nil
+ end
+ end
+
+end
diff --git a/app/models/note.rb b/app/models/note.rb
index 9a3481faaaa..56a8749e47d 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -19,6 +19,8 @@ require 'carrierwave/orm/activerecord'
require 'file_size_validator'
class Note < ActiveRecord::Base
+ include Mentionable
+
attr_accessible :note, :noteable, :noteable_id, :noteable_type, :project_id,
:attachment, :line_code, :commit_id
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 379d2c54629..b0243481b35 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -110,9 +110,11 @@ class NotificationService
else
opts.merge!(noteable_id: note.noteable_id)
target = note.noteable
- recipients = []
- recipients << target.assignee if target.respond_to?(:assignee)
- recipients << target.author if target.respond_to?(:author)
+ if target.respond_to?(:participants)
+ recipients = target.participants
+ else
+ recipients = []
+ end
end
# Get users who left comment in thread
@@ -181,7 +183,12 @@ class NotificationService
end
def new_resource_email(target, method)
- recipients = reject_muted_users([target.assignee], target.project)
+ if target.respond_to?(:participants)
+ recipients = target.participants
+ else
+ recipients = []
+ end
+ recipients = reject_muted_users(recipients, target.project)
recipients = recipients.concat(project_watchers(target.project)).uniq
recipients.delete(target.author)
diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml
index 2e204b8240d..891a01f14c9 100644
--- a/app/views/issues/show.html.haml
+++ b/app/views/issues/show.html.haml
@@ -65,4 +65,9 @@
- else
= link_to 'Close Issue', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue"
+.participants
+ %cite.cgray #{@issue.participants.count} participants
+ - @issue.participants.each do |participant|
+ = link_to_member(@project, participant, name: false, size: 24)
+
.voting_notes#notes= render "notes/notes_with_form"
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 21e4202f4ee..76501482303 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -19,7 +19,7 @@ describe NotificationService do
describe 'Notes' do
context 'issue note' do
let(:issue) { create(:issue, assignee: create(:user)) }
- let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id) }
+ let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@mention referenced') }
before do
build_team(note.project)
@@ -30,6 +30,7 @@ describe NotificationService do
should_email(@u_watcher.id)
should_email(note.noteable.author_id)
should_email(note.noteable.assignee_id)
+ should_email(@u_mentioned.id)
should_not_email(note.author_id)
should_not_email(@u_participating.id)
should_not_email(@u_disabled.id)
@@ -235,9 +236,11 @@ describe NotificationService do
@u_watcher = create(:user, notification_level: Notification::N_WATCH)
@u_participating = create(:user, notification_level: Notification::N_PARTICIPATING)
@u_disabled = create(:user, notification_level: Notification::N_DISABLED)
+ @u_mentioned = create(:user, username: 'mention', notification_level: Notification::N_WATCH)
project.team << [@u_watcher, :master]
project.team << [@u_participating, :master]
project.team << [@u_disabled, :master]
+ project.team << [@u_mentioned, :master]
end
end