Project

General

Profile

Feature #37480 » feature-37480.patch

Mizuki ISHIKAWA, 2022-07-21 09:16

View differences:

app/controllers/members_controller.rb
27 27

  
28 28
  require_sudo_mode :create, :update, :destroy
29 29

  
30
  include MembersHelper
31

  
30 32
  def index
31 33
    scope = @project.memberships
32
    @offset, @limit = api_offset_and_limit
33
    @member_count = scope.count
34
    @member_pages = Paginator.new @member_count, @limit, params['page']
35
    @offset ||= @member_pages.offset
36
    @members = scope.includes(:principal, :roles).order(:id).limit(@limit).offset(@offset).to_a
34
    @members = scope.includes(:principal, :roles).order(:id)
37 35

  
38 36
    respond_to do |format|
39 37
      format.html {head 406}
40
      format.api
38
      format.api do
39
        @offset, @limit = api_offset_and_limit
40
        @member_count = scope.count
41
        @member_pages = Paginator.new @member_count, @limit, params['page']
42
        @offset ||= @member_pages.offset
43
        @members = @members.limit(@limit).offset(@offset).to_a
44
      end
45
      format.csv do
46
        send_data(members_to_csv(@members), type: 'text/csv; header=present', filename: "#{@project.identifier}-members.csv")
47
      end
41 48
    end
42 49
  end
43 50

  
app/helpers/members_helper.rb
62 62
      content_tag('em', content.join(", "), :class => "info")
63 63
    end
64 64
  end
65

  
66
  def members_to_csv(members)
67
    Redmine::Export::CSV.generate(encoding: params[:encoding]) do |csv|
68
      # csv headers
69
      csv << ['', l(:label_role), l(:field_principal), l(:label_project)]
70

  
71
      # csv lines
72
      members.each do |member|
73
        member.roles.each do |role|
74
          csv << [
75
            member.principal.name,
76
            role.name,
77
            member.principal.is_a?(Group) ? l(:label_group) : l(:label_user),
78
            member.project.name
79
          ]
80
        end
81
      end
82
    end
83
  end
65 84
end
app/views/projects/settings/_members.html.erb
38 38
<% end %>
39 39
  </tbody>
40 40
</table>
41
<% other_formats_links do |f| %>
42
  <%= f.link_to_with_query_parameters "CSV", {}, :onclick => "showModal('csv-export-options', '330px'); return false;" %>
43
<% end %>
44
<div id="csv-export-options" style="display: none;">
45
  <h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3>
46
  <%= form_tag(project_memberships_path(project_id: @project.id, format: 'csv'), :method => :get, :id => 'csv-export-form') do %>
47
  <%= export_csv_encoding_select_tag %>
48
  <p class="buttons">
49
    <%= submit_tag l(:button_export), :name => nil, :onclick => 'hideModal(this);', :data => {:disable_with => false} %>
50
    <%= link_to_function l(:button_cancel), 'hideModal(this);' %>
51
  </p>
52
  <% end %>
53
</div>
41 54
<% else %>
42 55
<p class="nodata"><%= l(:label_no_data) %></p>
43 56
<% end %>
test/functional/members_controller_test.rb
27 27
    @request.session[:user_id] = 2
28 28
  end
29 29

  
30
  def test_index_with_csv_format_should_export_csv
31
    project = Project.find(5)
32
    get(
33
      :index,
34
      params: {
35
        project_id: project.id,
36
        format: 'csv'
37
      }
38
    )
39
    assert_response :success
40
    assert_equal 'text/csv; header=present', response.media_type
41

  
42
    lines = response.body.chomp.split("\n")
43
    # Number of lines
44
    assert_equal project.memberships.sum{|m| m.roles.count } + 1, lines.size
45
    # Header
46
    assert_equal "\"\",Role,User or Group,Project", lines.first
47
    # Details
48
    to_test = [
49
      'John Smith,Manager,User,Private child of eCookbook',
50
      'A Team,Manager,Group,Private child of eCookbook',
51
      'A Team,Developer,Group,Private child of eCookbook',
52
      'User Misc,Manager,User,Private child of eCookbook',
53
      'User Misc,Developer,User,Private child of eCookbook',
54
      'Redmine Admin,Manager,User,Private child of eCookbook'
55
    ]
56
    to_test.each do |expected|
57
      assert_includes lines, expected
58
    end
59
  end
60

  
30 61
  def test_new
31 62
    get(:new, :params => {:project_id => 1})
32 63
    assert_response :success
(2-2/2)