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