##// END OF EJS Templates
Adds pagination to users list when adding project or group members (#9549)....
Jean-Philippe Lang -
r10970:1257f1960ff6
parent child
Show More
@@ -0,0 +1,1
1 $('#users').html('<%= escape_javascript(render_principals_for_new_group_users(@group)) %>');
@@ -0,0 +1,1
1 $('#principals_for_new_member').html('<%= escape_javascript(render_principals_for_new_members(@project)) %>');
@@ -109,8 +109,9 class GroupsController < ApplicationController
109 end
109 end
110
110
111 def autocomplete_for_user
111 def autocomplete_for_user
112 @users = User.active.not_in_group(@group).like(params[:q]).all(:limit => 100)
112 respond_to do |format|
113 render :layout => false
113 format.js
114 end
114 end
115 end
115
116
116 def edit_membership
117 def edit_membership
@@ -112,8 +112,9 class MembersController < ApplicationController
112 end
112 end
113
113
114 def autocomplete
114 def autocomplete
115 @principals = Principal.active.not_member_of(@project).like(params[:q]).all(:limit => 100)
115 respond_to do |format|
116 render :layout => false
116 format.js
117 end
117 end
118 end
118
119
119 private
120 private
@@ -43,6 +43,7 class ProjectsController < ApplicationController
43 helper :repositories
43 helper :repositories
44 include RepositoriesHelper
44 include RepositoriesHelper
45 include ProjectsHelper
45 include ProjectsHelper
46 helper :members
46
47
47 # Lists visible projects
48 # Lists visible projects
48 def index
49 def index
@@ -24,4 +24,19 module GroupsHelper
24 {:name => 'memberships', :partial => 'groups/memberships', :label => :label_project_plural}
24 {:name => 'memberships', :partial => 'groups/memberships', :label => :label_project_plural}
25 ]
25 ]
26 end
26 end
27
28 def render_principals_for_new_group_users(group)
29 scope = User.active.not_in_group(group).like(params[:q])
30 principal_count = scope.count
31 principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page']
32 principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
33
34 s = content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'principals')
35
36 links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|
37 link_to text, autocomplete_for_user_group_path(group, parameters.merge(:q => params[:q], :format => 'js')), :remote => true
38 }
39
40 s + content_tag('p', links, :class => 'pagination')
41 end
27 end
42 end
@@ -18,4 +18,18
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 module MembersHelper
20 module MembersHelper
21 def render_principals_for_new_members(project)
22 scope = Principal.active.not_member_of(project).like(params[:q]).order('type, login, lastname ASC')
23 principal_count = scope.count
24 principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page']
25 principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
26
27 s = content_tag('div', principals_check_box_tags('membership[user_ids][]', principals), :id => 'principals')
28
29 links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|
30 link_to text, autocomplete_project_memberships_path(project, parameters.merge(:q => params[:q], :format => 'js')), :remote => true
31 }
32
33 s + content_tag('p', links, :class => 'pagination')
34 end
21 end
35 end
@@ -22,22 +22,18
22 </div>
22 </div>
23
23
24 <div class="splitcontentright">
24 <div class="splitcontentright">
25 <% users = User.active.not_in_group(@group).all(:limit => 100) %>
26 <% if users.any? %>
27 <%= form_for(@group, :remote => true, :url => group_users_path(@group),
25 <%= form_for(@group, :remote => true, :url => group_users_path(@group),
28 :html => {:method => :post}) do |f| %>
26 :html => {:method => :post}) do |f| %>
29 <fieldset><legend><%=l(:label_user_new)%></legend>
27 <fieldset><legend><%=l(:label_user_new)%></legend>
30
28
31 <p><%= label_tag "user_search", l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
29 <p><%= label_tag "user_search", l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
32 <%= javascript_tag "observeSearchfield('user_search', 'users', '#{ escape_javascript autocomplete_for_user_group_path(@group) }')" %>
30 <%= javascript_tag "observeSearchfield('user_search', null, '#{ escape_javascript autocomplete_for_user_group_path(@group) }')" %>
33
31
34 <div id="users">
32 <div id="users">
35 <%= principals_check_box_tags 'user_ids[]', users %>
33 <%= render_principals_for_new_group_users(@group) %>
36 </div>
34 </div>
37
35
38 <p><%= submit_tag l(:button_add) %></p>
36 <p><%= submit_tag l(:button_add) %></p>
39 </fieldset>
37 </fieldset>
40 <% end %>
38 <% end %>
41 <% end %>
42
43 </div>
39 </div>
@@ -51,18 +51,16
51 <% end %>
51 <% end %>
52 </div>
52 </div>
53
53
54 <% principals = Principal.active.not_member_of(@project).all(:limit => 100, :order => 'type, login, lastname ASC') %>
55
56 <div class="splitcontentright">
54 <div class="splitcontentright">
57 <% if roles.any? && principals.any? %>
55 <% if roles.any? %>
58 <%= form_for(@member, {:as => :membership, :url => project_memberships_path(@project), :remote => true, :method => :post}) do |f| %>
56 <%= form_for(@member, {:as => :membership, :url => project_memberships_path(@project), :remote => true, :method => :post}) do |f| %>
59 <fieldset><legend><%=l(:label_member_new)%></legend>
57 <fieldset><legend><%=l(:label_member_new)%></legend>
60
58
61 <p><%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %></p>
59 <p><%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %></p>
62 <%= javascript_tag "observeSearchfield('principal_search', 'principals', '#{ escape_javascript autocomplete_project_memberships_path(@project) }')" %>
60 <%= javascript_tag "observeSearchfield('principal_search', null, '#{ escape_javascript autocomplete_project_memberships_path(@project, :format => 'js') }')" %>
63
61
64 <div id="principals">
62 <div id="principals_for_new_member">
65 <%= principals_check_box_tags 'membership[user_ids][]', principals %>
63 <%= render_principals_for_new_members(@project) %>
66 </div>
64 </div>
67
65
68 <p><%= l(:label_role_plural) %>:
66 <p><%= l(:label_role_plural) %>:
@@ -481,7 +481,7 function observeSearchfield(fieldId, targetId, url) {
481 url: url,
481 url: url,
482 type: 'get',
482 type: 'get',
483 data: {q: $this.val()},
483 data: {q: $this.val()},
484 success: function(data){ $('#'+targetId).html(data); },
484 success: function(data){ if(targetId) $('#'+targetId).html(data); },
485 beforeSend: function(){ $this.addClass('ajax-loading'); },
485 beforeSend: function(){ $this.addClass('ajax-loading'); },
486 complete: function(){ $this.removeClass('ajax-loading'); }
486 complete: function(){ $this.removeClass('ajax-loading'); }
487 });
487 });
@@ -562,7 +562,7 div#tab-content-members .splitcontentright, div#tab-content-memberships .splitco
562 div#tab-content-members fieldset, div#tab-content-memberships fieldset, div#tab-content-users fieldset { padding:1em; margin-bottom: 1em; }
562 div#tab-content-members fieldset, div#tab-content-memberships fieldset, div#tab-content-users fieldset { padding:1em; margin-bottom: 1em; }
563 div#tab-content-members fieldset legend, div#tab-content-memberships fieldset legend, div#tab-content-users fieldset legend { font-weight: bold; }
563 div#tab-content-members fieldset legend, div#tab-content-memberships fieldset legend, div#tab-content-users fieldset legend { font-weight: bold; }
564 div#tab-content-members fieldset label, div#tab-content-memberships fieldset label, div#tab-content-users fieldset label { display: block; }
564 div#tab-content-members fieldset label, div#tab-content-memberships fieldset label, div#tab-content-users fieldset label { display: block; }
565 div#tab-content-members fieldset div, div#tab-content-users fieldset div { max-height: 400px; overflow:auto; }
565 div#tab-content-members #principals, div#tab-content-users #principals { max-height: 400px; overflow:auto; }
566
566
567 #users_for_watcher {height: 200px; overflow:auto;}
567 #users_for_watcher {height: 200px; overflow:auto;}
568 #users_for_watcher label {display: block;}
568 #users_for_watcher label {display: block;}
@@ -195,11 +195,8 class GroupsControllerTest < ActionController::TestCase
195 end
195 end
196
196
197 def test_autocomplete_for_user
197 def test_autocomplete_for_user
198 get :autocomplete_for_user, :id => 10, :q => 'mis'
198 get :autocomplete_for_user, :id => 10, :q => 'smi', :format => 'js'
199 assert_response :success
199 assert_response :success
200 users = assigns(:users)
200 assert_include 'John Smith', response.body
201 assert_not_nil users
202 assert users.any?
203 assert !users.include?(Group.find(10).users.first)
204 end
201 end
205 end
202 end
@@ -104,11 +104,8 class MembersControllerTest < ActionController::TestCase
104 end
104 end
105
105
106 def test_autocomplete
106 def test_autocomplete
107 get :autocomplete, :project_id => 1, :q => 'mis'
107 get :autocomplete, :project_id => 1, :q => 'mis', :format => 'js'
108 assert_response :success
108 assert_response :success
109 assert_template 'autocomplete'
109 assert_include 'User Misc', response.body
110
111 assert_tag :label, :content => /User Misc/,
112 :child => { :tag => 'input', :attributes => { :name => 'membership[user_ids][]', :value => '8' } }
113 end
110 end
114 end
111 end
@@ -48,6 +48,10 class RoutingGroupsTest < ActionController::IntegrationTest
48 { :controller => 'groups', :action => 'autocomplete_for_user', :id => '1' }
48 { :controller => 'groups', :action => 'autocomplete_for_user', :id => '1' }
49 )
49 )
50 assert_routing(
50 assert_routing(
51 { :method => 'get', :path => "/groups/1/autocomplete_for_user.js" },
52 { :controller => 'groups', :action => 'autocomplete_for_user', :id => '1', :format => 'js' }
53 )
54 assert_routing(
51 { :method => 'get', :path => "/groups/1" },
55 { :method => 'get', :path => "/groups/1" },
52 { :controller => 'groups', :action => 'show', :id => '1' }
56 { :controller => 'groups', :action => 'show', :id => '1' }
53 )
57 )
@@ -55,5 +55,9 class RoutingMembersTest < ActionController::IntegrationTest
55 { :method => 'get', :path => "/projects/5234/memberships/autocomplete" },
55 { :method => 'get', :path => "/projects/5234/memberships/autocomplete" },
56 { :controller => 'members', :action => 'autocomplete', :project_id => '5234' }
56 { :controller => 'members', :action => 'autocomplete', :project_id => '5234' }
57 )
57 )
58 assert_routing(
59 { :method => 'get', :path => "/projects/5234/memberships/autocomplete.js" },
60 { :controller => 'members', :action => 'autocomplete', :project_id => '5234', :format => 'js' }
61 )
58 end
62 end
59 end
63 end
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now