##// END OF EJS Templates
Adds a scope for sorting groups....
Jean-Philippe Lang -
r9764:1c825df54929
parent child
Show More
@@ -1,158 +1,158
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class GroupsController < ApplicationController
18 class GroupsController < ApplicationController
19 layout 'admin'
19 layout 'admin'
20
20
21 before_filter :require_admin
21 before_filter :require_admin
22 before_filter :find_group, :except => [:index, :new, :create]
22 before_filter :find_group, :except => [:index, :new, :create]
23 accept_api_auth :index, :show, :create, :update, :destroy, :add_users, :remove_user
23 accept_api_auth :index, :show, :create, :update, :destroy, :add_users, :remove_user
24
24
25 helper :custom_fields
25 helper :custom_fields
26
26
27 def index
27 def index
28 @groups = Group.find(:all, :order => 'lastname')
28 @groups = Group.sorted.all
29
29
30 respond_to do |format|
30 respond_to do |format|
31 format.html
31 format.html
32 format.api
32 format.api
33 end
33 end
34 end
34 end
35
35
36 def show
36 def show
37 respond_to do |format|
37 respond_to do |format|
38 format.html
38 format.html
39 format.api
39 format.api
40 end
40 end
41 end
41 end
42
42
43 def new
43 def new
44 @group = Group.new
44 @group = Group.new
45 end
45 end
46
46
47 def create
47 def create
48 @group = Group.new
48 @group = Group.new
49 @group.safe_attributes = params[:group]
49 @group.safe_attributes = params[:group]
50
50
51 respond_to do |format|
51 respond_to do |format|
52 if @group.save
52 if @group.save
53 format.html {
53 format.html {
54 flash[:notice] = l(:notice_successful_create)
54 flash[:notice] = l(:notice_successful_create)
55 redirect_to(params[:continue] ? new_group_path : groups_path)
55 redirect_to(params[:continue] ? new_group_path : groups_path)
56 }
56 }
57 format.api { render :action => 'show', :status => :created, :location => group_url(@group) }
57 format.api { render :action => 'show', :status => :created, :location => group_url(@group) }
58 else
58 else
59 format.html { render :action => "new" }
59 format.html { render :action => "new" }
60 format.api { render_validation_errors(@group) }
60 format.api { render_validation_errors(@group) }
61 end
61 end
62 end
62 end
63 end
63 end
64
64
65 def edit
65 def edit
66 end
66 end
67
67
68 def update
68 def update
69 @group.safe_attributes = params[:group]
69 @group.safe_attributes = params[:group]
70
70
71 respond_to do |format|
71 respond_to do |format|
72 if @group.save
72 if @group.save
73 flash[:notice] = l(:notice_successful_update)
73 flash[:notice] = l(:notice_successful_update)
74 format.html { redirect_to(groups_path) }
74 format.html { redirect_to(groups_path) }
75 format.api { head :ok }
75 format.api { head :ok }
76 else
76 else
77 format.html { render :action => "edit" }
77 format.html { render :action => "edit" }
78 format.api { render_validation_errors(@group) }
78 format.api { render_validation_errors(@group) }
79 end
79 end
80 end
80 end
81 end
81 end
82
82
83 def destroy
83 def destroy
84 @group.destroy
84 @group.destroy
85
85
86 respond_to do |format|
86 respond_to do |format|
87 format.html { redirect_to(groups_url) }
87 format.html { redirect_to(groups_url) }
88 format.api { head :ok }
88 format.api { head :ok }
89 end
89 end
90 end
90 end
91
91
92 def add_users
92 def add_users
93 users = User.find_all_by_id(params[:user_id] || params[:user_ids])
93 users = User.find_all_by_id(params[:user_id] || params[:user_ids])
94 @group.users << users if request.post?
94 @group.users << users if request.post?
95 respond_to do |format|
95 respond_to do |format|
96 format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
96 format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
97 format.js {
97 format.js {
98 render(:update) {|page|
98 render(:update) {|page|
99 page.replace_html "tab-content-users", :partial => 'groups/users'
99 page.replace_html "tab-content-users", :partial => 'groups/users'
100 users.each {|user| page.visual_effect(:highlight, "user-#{user.id}") }
100 users.each {|user| page.visual_effect(:highlight, "user-#{user.id}") }
101 }
101 }
102 }
102 }
103 format.api { head :ok }
103 format.api { head :ok }
104 end
104 end
105 end
105 end
106
106
107 def remove_user
107 def remove_user
108 @group.users.delete(User.find(params[:user_id])) if request.delete?
108 @group.users.delete(User.find(params[:user_id])) if request.delete?
109 respond_to do |format|
109 respond_to do |format|
110 format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
110 format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
111 format.js { render(:update) {|page| page.replace_html "tab-content-users", :partial => 'groups/users'} }
111 format.js { render(:update) {|page| page.replace_html "tab-content-users", :partial => 'groups/users'} }
112 format.api { head :ok }
112 format.api { head :ok }
113 end
113 end
114 end
114 end
115
115
116 def autocomplete_for_user
116 def autocomplete_for_user
117 @users = User.active.not_in_group(@group).like(params[:q]).all(:limit => 100)
117 @users = User.active.not_in_group(@group).like(params[:q]).all(:limit => 100)
118 render :layout => false
118 render :layout => false
119 end
119 end
120
120
121 def edit_membership
121 def edit_membership
122 @membership = Member.edit_membership(params[:membership_id], params[:membership], @group)
122 @membership = Member.edit_membership(params[:membership_id], params[:membership], @group)
123 @membership.save if request.post?
123 @membership.save if request.post?
124 respond_to do |format|
124 respond_to do |format|
125 if @membership.valid?
125 if @membership.valid?
126 format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'memberships' }
126 format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'memberships' }
127 format.js {
127 format.js {
128 render(:update) {|page|
128 render(:update) {|page|
129 page.replace_html "tab-content-memberships", :partial => 'groups/memberships'
129 page.replace_html "tab-content-memberships", :partial => 'groups/memberships'
130 page.visual_effect(:highlight, "member-#{@membership.id}")
130 page.visual_effect(:highlight, "member-#{@membership.id}")
131 }
131 }
132 }
132 }
133 else
133 else
134 format.js {
134 format.js {
135 render(:update) {|page|
135 render(:update) {|page|
136 page.alert(l(:notice_failed_to_save_members, :errors => @membership.errors.full_messages.join(', ')))
136 page.alert(l(:notice_failed_to_save_members, :errors => @membership.errors.full_messages.join(', ')))
137 }
137 }
138 }
138 }
139 end
139 end
140 end
140 end
141 end
141 end
142
142
143 def destroy_membership
143 def destroy_membership
144 Member.find(params[:membership_id]).destroy if request.post?
144 Member.find(params[:membership_id]).destroy if request.post?
145 respond_to do |format|
145 respond_to do |format|
146 format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'memberships' }
146 format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'memberships' }
147 format.js { render(:update) {|page| page.replace_html "tab-content-memberships", :partial => 'groups/memberships'} }
147 format.js { render(:update) {|page| page.replace_html "tab-content-memberships", :partial => 'groups/memberships'} }
148 end
148 end
149 end
149 end
150
150
151 private
151 private
152
152
153 def find_group
153 def find_group
154 @group = Group.find(params[:id])
154 @group = Group.find(params[:id])
155 rescue ActiveRecord::RecordNotFound
155 rescue ActiveRecord::RecordNotFound
156 render_404
156 render_404
157 end
157 end
158 end
158 end
@@ -1,84 +1,86
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Group < Principal
18 class Group < Principal
19 include Redmine::SafeAttributes
19 include Redmine::SafeAttributes
20
20
21 has_and_belongs_to_many :users, :after_add => :user_added,
21 has_and_belongs_to_many :users, :after_add => :user_added,
22 :after_remove => :user_removed
22 :after_remove => :user_removed
23
23
24 acts_as_customizable
24 acts_as_customizable
25
25
26 validates_presence_of :lastname
26 validates_presence_of :lastname
27 validates_uniqueness_of :lastname, :case_sensitive => false
27 validates_uniqueness_of :lastname, :case_sensitive => false
28 validates_length_of :lastname, :maximum => 30
28 validates_length_of :lastname, :maximum => 30
29
29
30 before_destroy :remove_references_before_destroy
30 before_destroy :remove_references_before_destroy
31
31
32 scope :sorted, order("#{table_name}.lastname ASC")
33
32 safe_attributes 'name',
34 safe_attributes 'name',
33 'user_ids',
35 'user_ids',
34 'custom_field_values',
36 'custom_field_values',
35 'custom_fields',
37 'custom_fields',
36 :if => lambda {|group, user| user.admin?}
38 :if => lambda {|group, user| user.admin?}
37
39
38 def to_s
40 def to_s
39 lastname.to_s
41 lastname.to_s
40 end
42 end
41
43
42 def name
44 def name
43 lastname
45 lastname
44 end
46 end
45
47
46 def name=(arg)
48 def name=(arg)
47 self.lastname = arg
49 self.lastname = arg
48 end
50 end
49
51
50 def user_added(user)
52 def user_added(user)
51 members.each do |member|
53 members.each do |member|
52 next if member.project.nil?
54 next if member.project.nil?
53 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)
55 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)
54 member.member_roles.each do |member_role|
56 member.member_roles.each do |member_role|
55 user_member.member_roles << MemberRole.new(:role => member_role.role, :inherited_from => member_role.id)
57 user_member.member_roles << MemberRole.new(:role => member_role.role, :inherited_from => member_role.id)
56 end
58 end
57 user_member.save!
59 user_member.save!
58 end
60 end
59 end
61 end
60
62
61 def user_removed(user)
63 def user_removed(user)
62 members.each do |member|
64 members.each do |member|
63 MemberRole.find(:all, :include => :member,
65 MemberRole.find(:all, :include => :member,
64 :conditions => ["#{Member.table_name}.user_id = ? AND #{MemberRole.table_name}.inherited_from IN (?)", user.id, member.member_role_ids]).each(&:destroy)
66 :conditions => ["#{Member.table_name}.user_id = ? AND #{MemberRole.table_name}.inherited_from IN (?)", user.id, member.member_role_ids]).each(&:destroy)
65 end
67 end
66 end
68 end
67
69
68 def self.human_attribute_name(attribute_key_name, *args)
70 def self.human_attribute_name(attribute_key_name, *args)
69 attr_name = attribute_key_name.to_s
71 attr_name = attribute_key_name.to_s
70 if attr_name == 'lastname'
72 if attr_name == 'lastname'
71 attr_name = "name"
73 attr_name = "name"
72 end
74 end
73 super(attr_name, *args)
75 super(attr_name, *args)
74 end
76 end
75
77
76 private
78 private
77
79
78 # Removes references that are not handled by associations
80 # Removes references that are not handled by associations
79 def remove_references_before_destroy
81 def remove_references_before_destroy
80 return if self.id.nil?
82 return if self.id.nil?
81
83
82 Issue.update_all 'assigned_to_id = NULL', ['assigned_to_id = ?', id]
84 Issue.update_all 'assigned_to_id = NULL', ['assigned_to_id = ?', id]
83 end
85 end
84 end
86 end
General Comments 0
You need to be logged in to leave comments. Login now