diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 79077017c..2daa49577 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -66,11 +66,13 @@ class IssuesController < ApplicationController } format.csv { @issues = @query.issues(:limit => Setting.issues_export_limit.to_i) - send_data(query_to_csv(@issues, @query, params[:csv]), :type => 'text/csv; header=present', :filename => 'issues.csv') + send_data(query_to_csv(@issues, @query, params[:csv]), + :type => 'text/csv; header=present', + :filename => "#{exported_query_filename(@query, 'issues')}.csv") } format.pdf { @issues = @query.issues(:limit => Setting.issues_export_limit.to_i) - send_file_headers! :type => 'application/pdf', :filename => 'issues.pdf' + send_file_headers! :type => 'application/pdf', :filename => "#{exported_query_filename(@query, 'issues')}.pdf" } end else diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb index 257660adf..b770eff43 100644 --- a/app/controllers/timelog_controller.rb +++ b/app/controllers/timelog_controller.rb @@ -68,7 +68,7 @@ class TimelogController < ApplicationController format.csv { # Export all entries @entries = scope.to_a - send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv') + send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => "#{exported_query_filename(@query, 'timelog')}.csv") } end end diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index e08dd3003..c2ccb3ccb 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -287,6 +287,14 @@ module QueriesHelper end end + def exported_query_filename(query, default_name) + query_name = params[:query_name].presence || query.name + query_name = default_name if query_name == '_' || query_name.blank? + + # Convert file names using the same rules as Wiki titles + filename_for_content_disposition(Wiki.titleize(query_name).downcase) + end + # Retrieve query from session or build a new query def retrieve_query(klass=IssueQuery, use_session=true, options={}) session_key = klass.name.underscore.to_sym diff --git a/app/views/issues/index.html.erb b/app/views/issues/index.html.erb index 18ec61849..1d87da2d6 100644 --- a/app/views/issues/index.html.erb +++ b/app/views/issues/index.html.erb @@ -42,6 +42,7 @@

<%= l(:label_export_options, :export_format => 'CSV') %>

<%= form_tag(_project_issues_path(@project, :format => 'csv'), :method => :get, :id => 'csv-export-form') do %> <%= query_as_hidden_field_tags(@query) %> + <%= hidden_field_tag('query_name', @query.name) %>


diff --git a/app/views/timelog/index.html.erb b/app/views/timelog/index.html.erb index 0ce69cadd..73f1c63d6 100644 --- a/app/views/timelog/index.html.erb +++ b/app/views/timelog/index.html.erb @@ -30,6 +30,7 @@

<%= l(:label_export_options, :export_format => 'CSV') %>

<%= form_tag(_time_entries_path(@project, nil, :format => 'csv'), :method => :get, :id => 'csv-export-form') do %> <%= query_as_hidden_field_tags @query %> + <%= hidden_field_tag('query_name', @query.name) %>


diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index 2945e8a0a..c3ac2d1af 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -670,6 +670,19 @@ class IssuesControllerTest < Redmine::ControllerTest assert_equal Setting.issue_list_default_columns.size + 2, lines[0].split(',').size end + + def test_index_csv_filename_without_query_name_param + get :index, :params => {:format => 'csv'} + assert_response :success + assert_match /issues.csv/, @response.headers['Content-Disposition'] + end + + def test_index_csv_filename_with_query_name_param + get :index, :params => {:query_name => 'My Query Name', :format => 'csv'} + assert_response :success + assert_match /my_query_name\.csv/, @response.headers['Content-Disposition'] + end + def test_index_csv_with_project get :index, :params => { :project_id => 1, @@ -935,6 +948,20 @@ class IssuesControllerTest < Redmine::ControllerTest assert_equal 'application/pdf', @response.content_type end + def test_index_pdf_filename_without_query + get :index, :params => {:format => 'pdf'} + assert_response :success + assert_match /issues.pdf/, @response.headers['Content-Disposition'] + end + + def test_index_pdf_filename_with_query + query = IssueQuery.create!(:name => 'My Query Name', :visibility => IssueQuery::VISIBILITY_PUBLIC) + get :index, :params => {:query_id => query.id, :format => 'pdf'} + + assert_response :success + assert_match /my_query_name\.pdf/, @response.headers['Content-Disposition'] + end + def test_index_atom get :index, :params => { :project_id => 'ecookbook', diff --git a/test/functional/timelog_controller_test.rb b/test/functional/timelog_controller_test.rb index 152912bd9..3f17aa736 100644 --- a/test/functional/timelog_controller_test.rb +++ b/test/functional/timelog_controller_test.rb @@ -1362,6 +1362,18 @@ class TimelogControllerTest < Redmine::ControllerTest end end + def test_index_csv_filename_query_name_param + get :index, :params => {:format => 'csv'} + assert_response :success + assert_match /timelog.csv/, @response.headers['Content-Disposition'] + end + + def test_index_csv_filename_with_query_name_param + get :index, :params => {:query_name => 'My Query Name', :format => 'csv'} + assert_response :success + assert_match /my_query_name\.csv/, @response.headers['Content-Disposition'] + end + def test_index_csv_should_fill_issue_column_with_tracker_id_and_subject issue = Issue.find(1) entry = TimeEntry.generate!(:issue => issue, :comments => "Issue column content test")