Project

General

Profile

« Previous | Next » 

Revision 2635

Ability to add multiple project members in a single action (#1556).

View differences:

trunk/app/controllers/members_controller.rb
21 21
  before_filter :authorize
22 22

  
23 23
  def new
24
    @project.members << Member.new(params[:member]) if request.post?
24
    members = []
25
    if params[:member] && request.post?
26
      attrs = params[:member].dup
27
      if (user_ids = attrs.delete(:user_ids))
28
        user_ids.each do |user_id|
29
          members << Member.new(attrs.merge(:user_id => user_id))
30
        end
31
      else
32
        members << Member.new(attrs)
33
      end
34
      @project.members << members
35
    end
25 36
    respond_to do |format|
26 37
      format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
27
      format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'projects/settings/members'} }
38
      format.js { 
39
        render(:update) {|page| 
40
          page.replace_html "tab-content-members", :partial => 'projects/settings/members'
41
          members.each {|member| page.visual_effect(:highlight, "member-#{member.id}") }
42
        }
43
      }
28 44
    end
29 45
  end
30 46
  
trunk/app/views/projects/settings/_members.rhtml
3 3
<% users = User.active.find(:all).sort - @project.users %>
4 4
<% # members sorted by role position
5 5
   members = @project.members.find(:all, :include => [:role, :user]).sort %>
6
   
6

  
7
<div class="splitcontentleft">
7 8
<% if members.any? %>
8 9
<table class="list">
9 10
	<thead>
......
15 16
	<tbody>
16 17
	<% members.each do |member| %>
17 18
	<% next if member.new_record? %>
18
	<tr class="<%= cycle 'odd', 'even' %>">
19
	<tr id="member-<%= member.id %>" class="<%= cycle 'odd', 'even' %>">
19 20
	<td><%= member.name %></td>
20 21
    <td align="center">
21 22
    <% if authorize_for('members', 'edit') %>
......
39 40
<% else %>
40 41
<p class="nodata"><%= l(:label_no_data) %></p>
41 42
<% end %>
43
</div>
42 44

  
43
<% if authorize_for('members', 'new') && !users.empty? %>
45
<div class="splitcontentright">
46
<% if !users.empty? %>
44 47
  <% remote_form_for(:member, @member, :url => {:controller => 'members', :action => 'new', :id => @project}, :method => :post) do |f| %>
45
    <p><label for="member_user_id"><%=l(:label_member_new)%></label><br />
46
    <%= f.select :user_id, users.collect{|user| [user.name, user.id]} %>
47
    <%= l(:label_role) %>: <%= f.select :role_id, roles.collect{|role| [role.name, role.id]}, :selected => nil %>
48
    <fieldset><legend><%=l(:label_member_new)%></legend>
49
		<div>
50
		<% users.each do |user| -%>
51
		<label><%= check_box_tag 'member[user_ids][]', user.id, false %> <%= user %></label>
52
		<% end -%>
53
		</div>
54
    <p><%= l(:label_role) %>: <%= f.select :role_id, roles.collect{|role| [role.name, role.id]}, :selected => nil %>
48 55
    <%= submit_tag l(:button_add) %></p>
56
		</fieldset>
49 57
  <% end %>
50 58
<% end %>
59
</div>
trunk/public/stylesheets/application.css
324 324

  
325 325
a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
326 326

  
327
/* Project members tab */
328
div#tab-content-members .splitcontentleft { width: 64% }
329
div#tab-content-members .splitcontentright { width: 34% }
330
div#tab-content-members fieldset { margin-top: -8px; padding-top:0.6em; margin-bottom: 1em; }
331
div#tab-content-members fieldset legend { font-weight: bold; }
332
div#tab-content-members fieldset label { display: block; }
333
div#tab-content-members fieldset div { max-height: 400px; overflow:auto; }
334

  
335
* html div#tab-content-members fieldset div { height: 450px; }
336

  
327 337
/***** Flash & error messages ****/
328 338
#errorExplanation, div.flash, .nodata, .warning {
329 339
    padding: 4px 4px 4px 30px;
trunk/test/fixtures/users.yml
112 112
  mail_notification: false
113 113
  login: someone
114 114
  type: User
115
users_008: 
116
  id: 8
117
  created_on: 2006-07-19 19:33:19 +02:00
118
  status: 1
119
  last_login_on: 
120
  language: 'it'
121
  hashed_password: 1
122
  updated_on: 2006-07-19 19:33:19 +02:00
123
  admin: false
124
  mail: [email protected]
125
  lastname: Misc
126
  firstname: User
127
  auth_source_id: 
128
  mail_notification: false
129
  login: miscuser8
130
  type: User
131
users_009: 
132
  id: 9
133
  created_on: 2006-07-19 19:33:19 +02:00
134
  status: 1
135
  last_login_on: 
136
  language: 'it'
137
  hashed_password: 1
138
  updated_on: 2006-07-19 19:33:19 +02:00
139
  admin: false
140
  mail: [email protected]
141
  lastname: Misc
142
  firstname: User
143
  auth_source_id: 
144
  mail_notification: false
145
  login: miscuser9
146
  type: User
115 147

  
116 148
  
trunk/test/functional/members_controller_test.rb
40 40
    )
41 41
  end
42 42
  
43
  def test_new
43
  def test_create
44 44
    assert_difference 'Member.count' do
45 45
      post :new, :id => 1, :member => {:role_id => 1, :user_id => 7}
46 46
    end
......
48 48
    assert User.find(7).member_of?(Project.find(1))
49 49
  end
50 50
  
51
  def test_create_multiple
52
    assert_difference 'Member.count', 3 do
53
      post :new, :id => 1, :member => {:role_id => 1, :user_ids => [7, 8, 9]}
54
    end
55
    assert_redirected_to '/projects/ecookbook/settings/members'
56
    assert User.find(7).member_of?(Project.find(1))
57
  end
58
  
51 59
  def test_edit
52 60
    assert_no_difference 'Member.count' do
53 61
      post :edit, :id => 2, :member => {:role_id => 1, :user_id => 3}

Also available in: Unified diff