Commit 8d1bd66e7f55683c6ec4a3d451188089d104e022
Committed by
Antonio Terceiro
1 parent
b61c5145
Exists in
master
and in
29 other branches
ActionItem1127: allowing enterprises to add members
* added loading image * added drag and drop * turned unassociate to AJAX * adding members via ajax * added the user finding via ajax
Showing
12 changed files
with
256 additions
and
23 deletions
Show diff stats
app/controllers/my_profile/profile_members_controller.rb
1 | class ProfileMembersController < MyProfileController | 1 | class ProfileMembersController < MyProfileController |
2 | protect 'manage_memberships', :profile | 2 | protect 'manage_memberships', :profile |
3 | + no_design_blocks | ||
3 | 4 | ||
4 | def index | 5 | def index |
5 | @members = profile.members | 6 | @members = profile.members |
@@ -43,7 +44,7 @@ class ProfileMembersController < MyProfileController | @@ -43,7 +44,7 @@ class ProfileMembersController < MyProfileController | ||
43 | else | 44 | else |
44 | flash[:notice] = 'Failed to unassociate member' | 45 | flash[:notice] = 'Failed to unassociate member' |
45 | end | 46 | end |
46 | - redirect_to :aciton => 'index' | 47 | + render :layout => false |
47 | end | 48 | end |
48 | 49 | ||
49 | def unassociate | 50 | def unassociate |
@@ -56,7 +57,23 @@ class ProfileMembersController < MyProfileController | @@ -56,7 +57,23 @@ class ProfileMembersController < MyProfileController | ||
56 | flash[:notice] = 'Failed to unassociate member' | 57 | flash[:notice] = 'Failed to unassociate member' |
57 | end | 58 | end |
58 | end | 59 | end |
59 | - redirect_to :action => 'index' | 60 | + render :layout => false |
61 | + end | ||
62 | + | ||
63 | + def add_members | ||
64 | + end | ||
65 | + | ||
66 | + def add_member | ||
67 | + if profile.enterprise? | ||
68 | + member = Person.find_by_identifier(params[:id]) | ||
69 | + member.define_roles(Profile::Roles.all_roles(environment), profile) | ||
70 | + end | ||
71 | + render :layout => false | ||
72 | + end | ||
73 | + | ||
74 | + def find_users | ||
75 | + @users_found = Person.find_by_contents(params[:query]) | ||
76 | + render :layout => false | ||
60 | end | 77 | end |
61 | 78 | ||
62 | end | 79 | end |
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +<h3><%= _('Current Members') %></h3> | ||
2 | + | ||
3 | +<table> | ||
4 | + <tr> | ||
5 | + <th><%= _('Member') %></th> | ||
6 | + <th><%= _('Actions') %></th> | ||
7 | + </tr> | ||
8 | + <% profile.members.each do |m| %> | ||
9 | + <tr> | ||
10 | + <td><%= link_to_profile m.short_name, m.identifier, :title => m.name %> </td> | ||
11 | + <td> | ||
12 | + <div class="members-buttons-cell"> | ||
13 | + <%= button_without_text :edit, _('Edit'), :action => 'change_role', :id => m %> | ||
14 | + <%= button_to_remote_without_text :remove, _('Remove'), | ||
15 | + :update => 'members-list', | ||
16 | + :loading => '$("members-list").addClassName("loading")', | ||
17 | + :success => "$('tr-#{m.identifier}').show()", | ||
18 | + :complete => '$("members-list").removeClassName("loading")', | ||
19 | + :url => {:action => 'unassociate', :id => m} %> | ||
20 | + </div> | ||
21 | + </td> | ||
22 | + </tr> | ||
23 | + <% end %> | ||
24 | +</table> |
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +<h2><%= _('Add members to %s') % profile.name %></h2> | ||
2 | + | ||
3 | +<% form_remote_tag :url => {:action => 'find_users', :profile => profile.identifier}, :update => 'users-list', :loading => '$("users-list").addClassName("loading")', :complete => '$("users-list").removeClassName("loading")' do %> | ||
4 | + <%= text_field_tag('query') %> | ||
5 | + <%= submit_tag(_('Search')) %> | ||
6 | +<% end %> | ||
7 | + | ||
8 | +<%= observe_field('query', :url => {:action => 'find_users', :profile => profile.identifier}, :update => 'users-list', :frequency => 1, :with => 'query', :condition => '$("query").value.length > 2', :loading => '$("users-list").addClassName("loading")', :complete => '$("users-list").removeClassName("loading")') %> | ||
9 | + | ||
10 | +<div id="users-list"> | ||
11 | + <%= render :partial => 'find_users' %> | ||
12 | +</div> | ||
13 | + | ||
14 | +<div id="members-list" class="add-members"> | ||
15 | + <%= render :partial => 'members_list' %> | ||
16 | +</div> | ||
17 | +<%= drop_receiving_element('members-list', | ||
18 | + :url => {:action => 'add_member', :profile => profile.identifier}, | ||
19 | + :before => '$("tr-" + element.id).hide()', | ||
20 | + :loading => '$("members-list").addClassName("loading")', | ||
21 | + :update => 'members-list', | ||
22 | + :success => '$("tr-" + element.id).hide(); $(element.id).show();', | ||
23 | + :complete => '$("members-list").removeClassName("loading")') %> | ||
24 | + | ||
25 | +<br style="clear:both" /> |
@@ -0,0 +1,28 @@ | @@ -0,0 +1,28 @@ | ||
1 | +<h3> <%= _('Users') %> </h3> | ||
2 | +<table> | ||
3 | + <tr><th><%= _('Name') %></th><th></th></tr> | ||
4 | + <% @users_found.each do |user| %> | ||
5 | + <tr id="tr-<%= user.identifier %>"<%= profile.members.include?(user) ? 'style="display:none"' : '' %>> | ||
6 | + <td> | ||
7 | + <div id="<%= user.identifier %>" class="draggable-user"> | ||
8 | + <%= image_tag('/images/grip-clue.png') %> | ||
9 | + <%= profile_image(user, :icon) %> | ||
10 | + <%= [link_to_profile(user.short_name + " (#{user.identifier})", user.identifier, :title => user.name), | ||
11 | + (user.sex ? gettext(user.sex.capitalize) : _('Sex not informed')), | ||
12 | + user.location.empty? ? nil : user.location ].compact.join(' — ') %> | ||
13 | + </div> | ||
14 | + <%= draggable_element(user.identifier, :revert => true) %> | ||
15 | + </td> | ||
16 | + <td> | ||
17 | + <%= button_to_remote_without_text(:add, _('Add member'), | ||
18 | + { :loading => '$("members-list").addClassName("loading")', | ||
19 | + :update => 'members-list', | ||
20 | + :url => {:action => 'add_member', :profile => profile.identifier, :id => user.identifier}, | ||
21 | + :success => "$('tr-#{user.identifier}').hide()", | ||
22 | + :complete => '$("members-list").removeClassName("loading")'}) %> | ||
23 | + | ||
24 | + | ||
25 | + </td> | ||
26 | + </tr> | ||
27 | + <% end if @users_found %> | ||
28 | +</table> |
app/views/profile_members/index.rhtml
1 | -<h2> <%= _('Listing Members') %> </h2> | ||
2 | - | ||
3 | -<%= link_to _('Affiliate yourself'), :action => 'add_role', :person => current_user.person, :role => @member_role if @member_role %> | ||
4 | - | ||
5 | -<table> | ||
6 | - <tr> | ||
7 | - <th><%= _('Member') %></th> | ||
8 | - <th><%= _('Actions') %></th> | ||
9 | - </tr> | ||
10 | - <% @members.each do |m| %> | ||
11 | - <tr> | ||
12 | - <td><%= m.name %> </td> | ||
13 | - <td> | ||
14 | - <%= button_without_text :edit, _('Edit'), :action => 'change_role', :id => m %> | ||
15 | - <%= button_without_text :delete, _('Remove'), :action => 'unassociate', :id => m %> | ||
16 | - </td> | ||
17 | - </tr> | ||
18 | - <% end %> | ||
19 | -</table> | 1 | +<div id="members-list"> |
2 | + <%= render :partial => 'members_list' %> | ||
3 | +</div> | ||
20 | 4 | ||
21 | <% button_bar do %> | 5 | <% button_bar do %> |
22 | <%= button :back, _('Back'), :controller => 'profile_editor' %> | 6 | <%= button :back, _('Back'), :controller => 'profile_editor' %> |
7 | + <%= button :add, _('Add members'), :action => 'add_members' if profile.enterprise? %> | ||
23 | <% end %> | 8 | <% end %> |
public/designs/icons/tango/style.css
@@ -17,6 +17,7 @@ | @@ -17,6 +17,7 @@ | ||
17 | .icon-back { background-image: url(Tango/16x16/actions/back.png) } | 17 | .icon-back { background-image: url(Tango/16x16/actions/back.png) } |
18 | .icon-next { background-image: url(Tango/16x16/actions/go-next.png) } | 18 | .icon-next { background-image: url(Tango/16x16/actions/go-next.png) } |
19 | .icon-add { background-image: url(Tango/16x16/actions/add.png) } | 19 | .icon-add { background-image: url(Tango/16x16/actions/add.png) } |
20 | +.icon-remove { background-image: url(Tango/16x16/actions/gtk-remove.png) } | ||
20 | .icon-more { background-image: url(Tango/16x16/actions/add.png) } | 21 | .icon-more { background-image: url(Tango/16x16/actions/add.png) } |
21 | .icon-up { background-image: url(Tango/16x16/actions/go-up.png) } | 22 | .icon-up { background-image: url(Tango/16x16/actions/go-up.png) } |
22 | .icon-down { background-image: url(Tango/16x16/actions/go-down.png) } | 23 | .icon-down { background-image: url(Tango/16x16/actions/go-down.png) } |
159 Bytes
@@ -0,0 +1,54 @@ | @@ -0,0 +1,54 @@ | ||
1 | +.no-boxes { | ||
2 | + margin: 30px | ||
3 | +} | ||
4 | + | ||
5 | +#users-list { | ||
6 | + float: left; | ||
7 | + width: 60%; | ||
8 | +} | ||
9 | + | ||
10 | +.msie6 #users-list { | ||
11 | + position: relative; | ||
12 | +} | ||
13 | + | ||
14 | +#users-list a.icon-add{ | ||
15 | + float: right; | ||
16 | +} | ||
17 | + | ||
18 | +.msie #users-list a.icon-add{ | ||
19 | + display: block; | ||
20 | +} | ||
21 | + | ||
22 | +.draggable-user { | ||
23 | + xwidth: 170px; | ||
24 | + cursor: move; | ||
25 | +} | ||
26 | + | ||
27 | +#members-list.add-members { | ||
28 | + float: right; | ||
29 | + width: 30%; | ||
30 | + text-align: center; | ||
31 | +} | ||
32 | + | ||
33 | +.members-buttons-cell { | ||
34 | + width: 60px; | ||
35 | +} | ||
36 | + | ||
37 | +.msie .members-buttons-cell a { | ||
38 | + position: relative; | ||
39 | + display: block; | ||
40 | + float: left; | ||
41 | +} | ||
42 | + | ||
43 | +.msie6 .button-bar a { | ||
44 | + position: relative; | ||
45 | +} | ||
46 | + | ||
47 | +.loading { | ||
48 | + cursor: progress; | ||
49 | + background: transparent url(../images/loading.gif) no-repeat scroll center 50px; | ||
50 | +} | ||
51 | + | ||
52 | +table { | ||
53 | + text-align: left; | ||
54 | +} |
test/functional/profile_members_controller_test.rb
@@ -90,8 +90,8 @@ class ProfileMembersControllerTest < Test::Unit::TestCase | @@ -90,8 +90,8 @@ class ProfileMembersControllerTest < Test::Unit::TestCase | ||
90 | login_as :admin_user | 90 | login_as :admin_user |
91 | get :unassociate, :profile => com.identifier, :id => member | 91 | get :unassociate, :profile => com.identifier, :id => member |
92 | 92 | ||
93 | - assert_response :redirect | ||
94 | - assert_redirected_to :action => 'index' | 93 | + assert_response :success |
94 | + assert_equal nil, @response.layout | ||
95 | member.reload | 95 | member.reload |
96 | com.reload | 96 | com.reload |
97 | assert_not_includes com.members, member | 97 | assert_not_includes com.members, member |
@@ -112,4 +112,100 @@ class ProfileMembersControllerTest < Test::Unit::TestCase | @@ -112,4 +112,100 @@ class ProfileMembersControllerTest < Test::Unit::TestCase | ||
112 | assert_not_includes assigns(:roles), role | 112 | assert_not_includes assigns(:roles), role |
113 | end | 113 | end |
114 | 114 | ||
115 | + should 'enterprises have a add members button' do | ||
116 | + ent = Enterprise.create!(:name => 'Test Ent', :identifier => 'test_ent') | ||
117 | + u = create_user_with_permission('test_user', 'manage_memberships', ent) | ||
118 | + login_as :test_user | ||
119 | + | ||
120 | + get :index, :profile => ent.identifier | ||
121 | + assert_tag :tag => 'a', :attributes => {:href => /add_members/} | ||
122 | + end | ||
123 | + | ||
124 | + should 'not display add members button for communities' do | ||
125 | + com = Community.create!(:name => 'Test Com', :identifier => 'test_com') | ||
126 | + u = create_user_with_permission('test_user', 'manage_memberships', com) | ||
127 | + login_as :test_user | ||
128 | + | ||
129 | + get :index, :profile => com.identifier | ||
130 | + assert_no_tag :tag => 'a', :attributes => {:href => /add_members/} | ||
131 | + end | ||
132 | + | ||
133 | + should 'have a add_members page' do | ||
134 | + ent = Enterprise.create!(:name => 'Test Ent', :identifier => 'test_ent') | ||
135 | + u = create_user_with_permission('test_user', 'manage_memberships', ent) | ||
136 | + login_as :test_user | ||
137 | + | ||
138 | + assert_nothing_raised do | ||
139 | + get :add_members, :profile => ent.identifier | ||
140 | + end | ||
141 | + | ||
142 | + end | ||
143 | + | ||
144 | + should 'list current members when adding new members' do | ||
145 | + ent = Enterprise.create!(:name => 'Test Ent', :identifier => 'test_ent') | ||
146 | + p = create_user_with_permission('test_user', 'manage_memberships', ent) | ||
147 | + login_as :test_user | ||
148 | + | ||
149 | + get :add_members, :profile => ent.identifier | ||
150 | + ent.reload | ||
151 | + assert_includes ent.members, p | ||
152 | + end | ||
153 | + | ||
154 | + should 'add member to profile' do | ||
155 | + ent = Enterprise.create!(:name => 'Test Ent', :identifier => 'test_ent') | ||
156 | + p = create_user_with_permission('test_user', 'manage_memberships', ent) | ||
157 | + login_as :test_user | ||
158 | + | ||
159 | + u = create_user('member_wannabe').person | ||
160 | + post :add_member, :profile => ent.identifier, :id => u.identifier | ||
161 | + ent.reload | ||
162 | + | ||
163 | + assert_includes ent.members, p | ||
164 | + assert_includes ent.members, u | ||
165 | + end | ||
166 | + | ||
167 | + should 'add member with all roles' do | ||
168 | + ent = Enterprise.create!(:name => 'Test Ent', :identifier => 'test_ent') | ||
169 | + p = create_user_with_permission('test_user', 'manage_memberships', ent) | ||
170 | + login_as :test_user | ||
171 | + | ||
172 | + u = create_user('member_wannabe').person | ||
173 | + post :add_member, :profile => ent.identifier, :id => u.identifier | ||
174 | + | ||
175 | + assert_equivalent Profile::Roles.all_roles(ent.environment).compact, u.role_assignments.find_all_by_resource_id(ent.id).map(&:role).compact | ||
176 | + end | ||
177 | + | ||
178 | + should 'not add member to community' do | ||
179 | + com = Community.create!(:name => 'Test Com', :identifier => 'test_com') | ||
180 | + p = create_user_with_permission('test_user', 'manage_memberships', com) | ||
181 | + login_as :test_user | ||
182 | + | ||
183 | + u = create_user('member_wannabe').person | ||
184 | + post :add_member, :profile => com.identifier, :id => u.identifier | ||
185 | + com.reload | ||
186 | + | ||
187 | + assert_not_includes com.members, u | ||
188 | + end | ||
189 | + | ||
190 | + should 'find users' do | ||
191 | + ent = Enterprise.create!(:name => 'Test Ent', :identifier => 'test_ent') | ||
192 | + user = create_user('test_user').person | ||
193 | + u = create_user_with_permission('ent_user', 'manage_memberships', ent) | ||
194 | + login_as :ent_user | ||
195 | + | ||
196 | + get :find_users, :profile => ent.identifier, :query => 'test*' | ||
197 | + | ||
198 | + assert_includes assigns(:users_found), user | ||
199 | + end | ||
200 | + | ||
201 | + should 'not appear add button for member in add members page' do | ||
202 | + ent = Enterprise.create!(:name => 'Test Ent', :identifier => 'test_ent') | ||
203 | + p = create_user_with_permission('test_user', 'manage_memberships', ent) | ||
204 | + login_as :test_user | ||
205 | + | ||
206 | + get :find_users, :profile => ent.identifier, :query => 'test*' | ||
207 | + | ||
208 | + assert_tag :tag => 'tr', :attributes => {:id => 'tr-test_user', :style => 'display:none'} | ||
209 | + end | ||
210 | + | ||
115 | end | 211 | end |