@@ -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', |
|
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? |
|
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', |
|
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 |
|
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