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 | 1 | class ProfileMembersController < MyProfileController |
2 | 2 | protect 'manage_memberships', :profile |
3 | + no_design_blocks | |
3 | 4 | |
4 | 5 | def index |
5 | 6 | @members = profile.members |
... | ... | @@ -43,7 +44,7 @@ class ProfileMembersController < MyProfileController |
43 | 44 | else |
44 | 45 | flash[:notice] = 'Failed to unassociate member' |
45 | 46 | end |
46 | - redirect_to :aciton => 'index' | |
47 | + render :layout => false | |
47 | 48 | end |
48 | 49 | |
49 | 50 | def unassociate |
... | ... | @@ -56,7 +57,23 @@ class ProfileMembersController < MyProfileController |
56 | 57 | flash[:notice] = 'Failed to unassociate member' |
57 | 58 | end |
58 | 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 | 77 | end |
61 | 78 | |
62 | 79 | end | ... | ... |
... | ... | @@ -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 @@ |
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 @@ |
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 | 5 | <% button_bar do %> |
22 | 6 | <%= button :back, _('Back'), :controller => 'profile_editor' %> |
7 | + <%= button :add, _('Add members'), :action => 'add_members' if profile.enterprise? %> | |
23 | 8 | <% end %> | ... | ... |
public/designs/icons/tango/style.css
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 | .icon-back { background-image: url(Tango/16x16/actions/back.png) } |
18 | 18 | .icon-next { background-image: url(Tango/16x16/actions/go-next.png) } |
19 | 19 | .icon-add { background-image: url(Tango/16x16/actions/add.png) } |
20 | +.icon-remove { background-image: url(Tango/16x16/actions/gtk-remove.png) } | |
20 | 21 | .icon-more { background-image: url(Tango/16x16/actions/add.png) } |
21 | 22 | .icon-up { background-image: url(Tango/16x16/actions/go-up.png) } |
22 | 23 | .icon-down { background-image: url(Tango/16x16/actions/go-down.png) } | ... | ... |
159 Bytes
... | ... | @@ -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 | 90 | login_as :admin_user |
91 | 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 | 95 | member.reload |
96 | 96 | com.reload |
97 | 97 | assert_not_includes com.members, member |
... | ... | @@ -112,4 +112,100 @@ class ProfileMembersControllerTest < Test::Unit::TestCase |
112 | 112 | assert_not_includes assigns(:roles), role |
113 | 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 | 211 | end | ... | ... |