Commit 8d1bd66e7f55683c6ec4a3d451188089d104e022
Committed by
Antonio Terceiro
1 parent
b61c5145
Exists in
master
and in
28 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 | ... | ... |