Skip to content
Snippets Groups Projects
Commit cf35d19c authored by Javier Castro's avatar Javier Castro
Browse files

Show participants on issues, including mentions, and notify email to all participants

parent a324960d
No related branches found
No related tags found
2 merge requests!4399fixed nav bar for empty repos (fixes #4375),!3898Notify email to mentioned users; show participants ala github on issuables
Loading
Loading
@@ -106,3 +106,7 @@ input.check_all_issues {
#update_status {
width: 100px;
}
.participants {
margin-bottom: 10px;
}
Loading
Loading
@@ -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
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -6,6 +6,7 @@
#
module Issuable
extend ActiveSupport::Concern
include Mentionable
 
included do
belongs_to :project
Loading
Loading
@@ -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
# == 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
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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)
 
Loading
Loading
Loading
Loading
@@ -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"
Loading
Loading
@@ -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)
Loading
Loading
@@ -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)
Loading
Loading
@@ -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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment