Feature #7774 » paste_9959.diff
| app/controllers/groups_controller.rb | ||
|---|---|---|
| 106 | 106 |
end |
| 107 | 107 |
end |
| 108 | 108 |
|
| 109 |
def add_users
|
|
| 109 |
def add_principals
|
|
| 110 | 110 |
@group = Group.find(params[:id]) |
| 111 |
users = User.find_all_by_id(params[:user_ids])
|
|
| 112 |
@group.users << users if request.post?
|
|
| 111 |
principals = Principal.find_all_by_id(params[:user_ids]) - @group.parent_groups
|
|
| 112 |
@group.principals << principals if request.post?
|
|
| 113 | 113 |
respond_to do |format| |
| 114 | 114 |
format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
|
| 115 | 115 |
format.js {
|
| 116 | 116 |
render(:update) {|page|
|
| 117 | 117 |
page.replace_html "tab-content-users", :partial => 'groups/users' |
| 118 |
users.each {|user| page.visual_effect(:highlight, "user-#{user.id}") }
|
|
| 118 |
principals.each {|principal| page.visual_effect(:highlight, "user-#{principal.id}") }
|
|
| 119 | 119 |
} |
| 120 | 120 |
} |
| 121 | 121 |
end |
| 122 | 122 |
end |
| 123 | 123 |
|
| 124 |
def remove_user
|
|
| 124 |
def remove_principal
|
|
| 125 | 125 |
@group = Group.find(params[:id]) |
| 126 |
@group.users.delete(User.find(params[:user_id])) if request.post?
|
|
| 126 |
@group.principals.delete(Principal.find(params[:user_id])) if request.post?
|
|
| 127 | 127 |
respond_to do |format| |
| 128 | 128 |
format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
|
| 129 | 129 |
format.js { render(:update) {|page| page.replace_html "tab-content-users", :partial => 'groups/users'} }
|
| 130 | 130 |
end |
| 131 | 131 |
end |
| 132 | 132 |
|
| 133 |
def autocomplete_for_user
|
|
| 133 |
def autocomplete_for_principal
|
|
| 134 | 134 |
@group = Group.find(params[:id]) |
| 135 |
@users = User.active.not_in_group(@group).like(params[:q]).all(:limit => 100)
|
|
| 135 |
@principals = Principal.active.not_in_group(@group).like(params[:q]).all(:limit => 100) - @group.parent_groups
|
|
| 136 | 136 |
render :layout => false |
| 137 | 137 |
end |
| 138 | 138 |
|
| app/models/group.rb | ||
|---|---|---|
| 16 | 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 17 | 17 | |
| 18 | 18 |
class Group < Principal |
| 19 |
has_and_belongs_to_many :users, :after_add => :user_added,
|
|
| 20 |
:after_remove => :user_removed
|
|
| 19 |
has_and_belongs_to_many :principals, :after_add => :principal_added,
|
|
| 20 |
:after_remove => :principal_removed
|
|
| 21 | 21 |
|
| 22 | 22 |
acts_as_customizable |
| 23 | 23 |
|
| 24 | 24 |
validates_presence_of :lastname |
| 25 | 25 |
validates_uniqueness_of :lastname, :case_sensitive => false |
| 26 | 26 |
validates_length_of :lastname, :maximum => 30 |
| 27 |
|
|
| 27 | ||
| 28 |
named_scope :direct_parents, lambda {|group|
|
|
| 29 |
group_id = group.is_a?(Group) ? group.id : group.to_i |
|
| 30 |
{ :conditions => ["#{Group.table_name}.id IN (SELECT gp.group_id FROM #{table_name_prefix}groups_principals#{table_name_suffix} gp WHERE gp.principal_id = ?)", group_id] }
|
|
| 31 |
} |
|
| 32 | ||
| 28 | 33 |
def to_s |
| 29 | 34 |
lastname.to_s |
| 30 | 35 |
end |
| 31 | 36 |
|
| 32 |
def user_added(user)
|
|
| 37 |
def principal_added(user)
|
|
| 33 | 38 |
members.each do |member| |
| 34 | 39 |
next if member.project.nil? |
| 35 | 40 |
user_member = Member.find_by_project_id_and_user_id(member.project_id, user.id) || Member.new(:project_id => member.project_id, :user_id => user.id) |
| ... | ... | |
| 40 | 45 |
end |
| 41 | 46 |
end |
| 42 | 47 |
|
| 43 |
def user_removed(user)
|
|
| 48 |
def principal_removed(user)
|
|
| 44 | 49 |
members.each do |member| |
| 45 | 50 |
MemberRole.find(:all, :include => :member, |
| 46 | 51 |
:conditions => ["#{Member.table_name}.user_id = ? AND #{MemberRole.table_name}.inherited_from IN (?)", user.id, member.member_role_ids]).each(&:destroy)
|
| 47 | 52 |
end |
| 48 | 53 |
end |
| 54 | ||
| 55 |
def parent_groups |
|
| 56 |
direct_parents = Group.direct_parents(self).all |
|
| 57 |
parent_groups = direct_parents |
|
| 58 |
direct_parents.each do |direct_parent| |
|
| 59 |
parent_groups += direct_parent.parent_groups |
|
| 60 |
end |
|
| 61 |
return parent_groups |
|
| 62 |
end |
|
| 49 | 63 |
end |
| app/models/member_role.rb | ||
|---|---|---|
| 44 | 44 |
|
| 45 | 45 |
def add_role_to_group_users |
| 46 | 46 |
if member.principal.is_a?(Group) |
| 47 |
member.principal.users.each do |user|
|
|
| 48 |
user_member = Member.find_by_project_id_and_user_id(member.project_id, user.id) || Member.new(:project_id => member.project_id, :user_id => user.id)
|
|
| 47 |
member.principal.principals.each do |principal|
|
|
| 48 |
user_member = Member.find_by_project_id_and_user_id(member.project_id, principal.id) || Member.new(:project_id => member.project_id, :user_id => principal.id)
|
|
| 49 | 49 |
user_member.member_roles << MemberRole.new(:role => role, :inherited_from => id) |
| 50 | 50 |
user_member.save! |
| 51 | 51 |
end |
| app/models/principal.rb | ||
|---|---|---|
| 21 | 21 |
has_many :members, :foreign_key => 'user_id', :dependent => :destroy |
| 22 | 22 |
has_many :memberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :project, :roles ], :conditions => "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}", :order => "#{Project.table_name}.name"
|
| 23 | 23 |
has_many :projects, :through => :memberships |
| 24 |
has_and_belongs_to_many :groups, :after_add => Proc.new {|principal, group| group.principal_added(principal)},
|
|
| 25 |
:after_remove => Proc.new {|principal, group| group.principal_removed(principal)}
|
|
| 24 | 26 | |
| 25 | 27 |
# Groups and active users |
| 26 | 28 |
named_scope :active, :conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status = 1)"
|
| ... | ... | |
| 46 | 48 |
principal.class.name <=> self.class.name |
| 47 | 49 |
end |
| 48 | 50 |
end |
| 51 | ||
| 52 |
named_scope :in_group, lambda {|group|
|
|
| 53 |
group_id = group.is_a?(Group) ? group.id : group.to_i |
|
| 54 |
{ :conditions => ["#{Principal.table_name}.id IN (SELECT gu.principal_id FROM #{table_name_prefix}groups_principals#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id] }
|
|
| 55 |
} |
|
| 56 |
named_scope :not_in_group, lambda {|group|
|
|
| 57 |
group_id = group.is_a?(Group) ? group.id : group.to_i |
|
| 58 |
{ :conditions => ["#{Principal.table_name}.id NOT IN (SELECT gu.principal_id FROM #{table_name_prefix}groups_principals#{table_name_suffix} gu WHERE gu.group_id = ?) AND #{Principal.table_name}.id <> ?", group_id, group_id] }
|
|
| 59 |
} |
|
| 49 | 60 |
|
| 50 | 61 |
protected |
| 51 | 62 |
|
| app/models/user.rb | ||
|---|---|---|
| 43 | 43 |
['none', :label_user_mail_option_none] |
| 44 | 44 |
] |
| 45 | 45 | |
| 46 |
has_and_belongs_to_many :groups, :after_add => Proc.new {|user, group| group.user_added(user)},
|
|
| 47 |
:after_remove => Proc.new {|user, group| group.user_removed(user)}
|
|
| 48 | 46 |
has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify |
| 49 | 47 |
has_many :changesets, :dependent => :nullify |
| 50 | 48 |
has_one :preference, :dependent => :destroy, :class_name => 'UserPreference' |
| ... | ... | |
| 76 | 74 | |
| 77 | 75 |
before_destroy :remove_references_before_destroy |
| 78 | 76 |
|
| 79 |
named_scope :in_group, lambda {|group|
|
|
| 80 |
group_id = group.is_a?(Group) ? group.id : group.to_i |
|
| 81 |
{ :conditions => ["#{User.table_name}.id IN (SELECT gu.user_id FROM #{table_name_prefix}groups_users#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id] }
|
|
| 82 |
} |
|
| 83 |
named_scope :not_in_group, lambda {|group|
|
|
| 84 |
group_id = group.is_a?(Group) ? group.id : group.to_i |
|
| 85 |
{ :conditions => ["#{User.table_name}.id NOT IN (SELECT gu.user_id FROM #{table_name_prefix}groups_users#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id] }
|
|
| 86 |
} |
|
| 87 |
|
|
| 88 | 77 |
def before_create |
| 89 | 78 |
self.mail_notification = Setting.default_notification_option if self.mail_notification.blank? |
| 90 | 79 |
true |
| app/views/groups/_users.html.erb | ||
|---|---|---|
| 1 | 1 |
<div class="splitcontentleft"> |
| 2 |
<% if @group.users.any? %>
|
|
| 2 |
<% if @group.principals.any? %>
|
|
| 3 | 3 |
<table class="list users"> |
| 4 | 4 |
<thead><tr> |
| 5 |
<th><%= l(:label_user) %></th> |
|
| 5 |
<th><%= l(:label_user) %> / <%= l(:label_group) %></th>
|
|
| 6 | 6 |
<th style="width:15%"></th> |
| 7 | 7 |
</tr></thead> |
| 8 | 8 |
<tbody> |
| 9 |
<% @group.users.sort.each do |user| %>
|
|
| 9 |
<% @group.principals.sort.each do |user| %>
|
|
| 10 | 10 |
<tr id="user-<%= user.id %>" class="<%= cycle 'odd', 'even' %>"> |
| 11 | 11 |
<td class="user"><%= link_to_user user %></td> |
| 12 | 12 |
<td class="buttons"> |
| 13 |
<%= link_to_remote l(:button_delete), { :url => { :controller => 'groups', :action => 'remove_user', :id => @group, :user_id => user },
|
|
| 13 |
<%= link_to_remote l(:button_delete), { :url => { :controller => 'groups', :action => 'remove_principal', :id => @group, :user_id => user },
|
|
| 14 | 14 |
:method => :post }, |
| 15 | 15 |
:class => 'icon icon-del' %> |
| 16 | 16 |
</td> |
| ... | ... | |
| 24 | 24 |
</div> |
| 25 | 25 | |
| 26 | 26 |
<div class="splitcontentright"> |
| 27 |
<% users = User.active.not_in_group(@group).all(:limit => 100) %>
|
|
| 28 |
<% if users.any? %>
|
|
| 29 |
<% remote_form_for(:group, @group, :url => {:controller => 'groups', :action => 'add_users', :id => @group}, :method => :post) do |f| %>
|
|
| 27 |
<% principals = Principal.active.not_in_group(@group).all(:limit => 100) - @group.parent_groups %>
|
|
| 28 |
<% if principals.any? %>
|
|
| 29 |
<% remote_form_for(:group, @group, :url => {:controller => 'groups', :action => 'add_principals', :id => @group}, :method => :post) do |f| %>
|
|
| 30 | 30 |
<fieldset><legend><%=l(:label_user_new)%></legend> |
| 31 | 31 |
|
| 32 |
<p><%= label_tag "user_search", l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
|
|
| 32 |
<p><%= label_tag "user_search", l(:label_principal_search) %><%= text_field_tag 'user_search', nil %></p>
|
|
| 33 | 33 |
<%= observe_field(:user_search, |
| 34 | 34 |
:frequency => 0.5, |
| 35 |
:update => :users,
|
|
| 36 |
:url => { :controller => 'groups', :action => 'autocomplete_for_user', :id => @group },
|
|
| 35 |
:update => :principals,
|
|
| 36 |
:url => { :controller => 'groups', :action => 'autocomplete_for_principal', :id => @group },
|
|
| 37 | 37 |
:with => 'q') |
| 38 | 38 |
%> |
| 39 | 39 |
|
| 40 |
<div id="users">
|
|
| 41 |
<%= principals_check_box_tags 'user_ids[]', users %>
|
|
| 40 |
<div id="principals">
|
|
| 41 |
<%= principals_check_box_tags 'user_ids[]', principals %>
|
|
| 42 | 42 |
</div> |
| 43 | 43 |
|
| 44 | 44 |
<p><%= submit_tag l(:button_add) %></p> |
| app/views/groups/autocomplete_for_principal.html.erb | ||
|---|---|---|
| 1 |
<%= principals_check_box_tags 'user_ids[]', @principals %> |
|
| app/views/groups/autocomplete_for_user.html.erb | ||
|---|---|---|
| 1 |
<%= principals_check_box_tags 'user_ids[]', @users %> |
|
| app/views/groups/index.html.erb | ||
|---|---|---|
| 15 | 15 |
<% @groups.each do |group| %> |
| 16 | 16 |
<tr class="<%= cycle 'odd', 'even' %>"> |
| 17 | 17 |
<td><%= link_to h(group), :action => 'edit', :id => group %></td> |
| 18 |
<td align="center"><%= group.users.size %></td>
|
|
| 18 |
<td align="center"><%= group.principals.size %></td>
|
|
| 19 | 19 |
<td class="buttons"><%= link_to l(:button_delete), group, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %></td> |
| 20 | 20 |
</tr> |
| 21 | 21 |
<% end %> |
| app/views/groups/show.html.erb | ||
|---|---|---|
| 1 | 1 |
<h2><%= link_to l(:label_group_plural), groups_path %> » <%=h @group %></h2> |
| 2 | 2 | |
| 3 | 3 |
<ul> |
| 4 |
<% @group.users.each do |user| %>
|
|
| 5 |
<li><%=h user %></li>
|
|
| 4 |
<% @group.principals.each do |principal| %>
|
|
| 5 |
<li><%=h principal %></li>
|
|
| 6 | 6 |
<% end %> |
| 7 | 7 |
</ul> |
| db/migrate/20110428091629_refactor_group_users_as_principals.rb | ||
|---|---|---|
| 1 |
class RefactorGroupUsersAsPrincipals < ActiveRecord::Migration |
|
| 2 |
def self.up |
|
| 3 |
rename_table :groups_users, :groups_principals |
|
| 4 |
change_table :groups_principals do |t| |
|
| 5 |
t.rename :user_id, :principal_id |
|
| 6 |
end |
|
| 7 |
end |
|
| 8 | ||
| 9 |
def self.down |
|
| 10 |
rename_table :groups_principals, :groups_users |
|
| 11 |
change_table :groups_principals do |t| |
|
| 12 |
t.rename :principal_id, :user_id |
|
| 13 |
end |
|
| 14 |
end |
|
| 15 |
end |
|