diff --git a/CHANGELOG.md b/CHANGELOG.md index 9262551021..8a820b59f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ For more detailed explanation, please refer to this video : https://www.youtube. ### Enhancements - Added enum to the funding status attribute of plan model to make the dropdown of 'funding status' being translatable +- Allow users to download both single phase and in PDF, TEXT and DOCX format. CSV file can only download single phase instead of all phases. ### Bug Fixes diff --git a/app/controllers/plan_exports_controller.rb b/app/controllers/plan_exports_controller.rb index f89458508f..a000a53588 100644 --- a/app/controllers/plan_exports_controller.rb +++ b/app/controllers/plan_exports_controller.rb @@ -36,12 +36,18 @@ def show @hash = @plan.as_pdf(current_user, @show_coversheet) @formatting = export_params[:formatting] || @plan.settings(:export).formatting - @selected_phase = if params.key?(:phase_id) - @plan.phases.find(params[:phase_id]) - else - @plan.phases.order('phases.updated_at DESC') + if params.key?(:phase_id) && params[:phase_id].length.positive? + # order phases by phase number asc + @hash[:phases] = @hash[:phases].sort_by { |phase| phase[:number] } + if params[:phase_id] == 'All' + @hash[:all_phases] = true + else + @selected_phase = @plan.phases.find(params[:phase_id]) + end + else + @selected_phase = @plan.phases.order('phases.updated_at DESC') .detect { |p| p.visibility_allowed?(@plan) } - end + end # Added contributors to coverage of plans. # Users will see both roles and contributor names if the role is filled @@ -102,7 +108,7 @@ def show_pdf date: l(@plan.updated_at.to_date, format: :readable)), font_size: 8, spacing: (Integer(@formatting[:margin][:bottom]) / 2) - 4, - right: '[page] of [topage]', + right: _('[page] of [topage]'), encoding: 'utf8' } end diff --git a/app/controllers/plans_controller.rb b/app/controllers/plans_controller.rb index 84b0af25c7..421514001a 100644 --- a/app/controllers/plans_controller.rb +++ b/app/controllers/plans_controller.rb @@ -376,6 +376,7 @@ def download @plan = Plan.find(params[:id]) authorize @plan @phase_options = @plan.phases.order(:number).pluck(:title, :id) + @phase_options.insert(0, ['All phases', 'All']) if @phase_options.length > 1 @export_settings = @plan.settings(:export) render 'download' end diff --git a/app/javascript/src/plans/download.js b/app/javascript/src/plans/download.js index e772b83221..6e1440f04c 100644 --- a/app/javascript/src/plans/download.js +++ b/app/javascript/src/plans/download.js @@ -21,5 +21,15 @@ $(() => { } else { $('#download-settings').show(); } - }); + + if (frmt === 'csv') { + $('#phase_id').find('option[value="All"').hide(); + $('#phase_id option:eq(1)').attr('selected', 'selected'); + $('#phase_id').val($('#phase_id option:eq(1)').val()); + } else if (frmt === 'pdf' || frmt === 'html' || frmt === 'docx' || frmt === 'text') { + $('#phase_id').find('option[value="All"').show(); + $('#phase_id').val($('#phase_id option:first').val()); + $('#phase_id option:first').attr('selected', 'selected'); + } + }).trigger('change'); }); diff --git a/app/views/shared/export/_plan.erb b/app/views/shared/export/_plan.erb index dac27560f2..aae3b9b705 100644 --- a/app/views/shared/export/_plan.erb +++ b/app/views/shared/export/_plan.erb @@ -18,7 +18,7 @@ <% @hash[:phases].each do |phase| %> <%# Only render selected phase %> - <% if phase[:title] == @selected_phase.title %> + <% if @hash[:all_phases] || (@selected_phase.present? && phase[:title] == @selected_phase.title) %> <%# Page break before each phase %>

<%= download_plan_page_title(@plan, phase, @hash) %>

diff --git a/app/views/shared/export/_plan_txt.erb b/app/views/shared/export/_plan_txt.erb index 7a9c42b87f..ff8570c785 100644 --- a/app/views/shared/export/_plan_txt.erb +++ b/app/views/shared/export/_plan_txt.erb @@ -38,7 +38,7 @@ <% @hash[:phases].each do |phase| %> <%# Only render selected phase %> -<% if phase[:title] == @selected_phase.title %> +<% if @hash[:all_phases] || (@selected_phase.present? && phase[:title] == @selected_phase.title) %> <%= (@hash[:phases].length > 1 ? "#{phase[:title]}" : "") %> <% phase[:sections].each do |section| %> <% if display_section?(@hash[:customization], section, @show_custom_sections) && num_section_questions(@plan, section, phase) > 0 %> diff --git a/spec/features/plans/exports_spec.rb b/spec/features/plans/exports_spec.rb index 4feec44845..38081afb3f 100644 --- a/spec/features/plans/exports_spec.rb +++ b/spec/features/plans/exports_spec.rb @@ -78,15 +78,35 @@ expect(page).not_to have_text(new_plan.title) end + # Separate code to test all-phase-download for html since it requires operation in new window scenario 'User downloads their plan as HTML' do within("#plan_#{plan.id}") do click_button('Actions') click_link 'Download' end select('html') - new_window = window_opened_by { click_button 'Download Plan' } - within_window new_window do - expect(page.source).to have_text(plan.title) + if plan.phases.present? + new_window = window_opened_by do + _select_option('phase_id', 'All') + click_button 'Download Plan' + end + within_window new_window do + expect(page.source).to have_text(plan.title) + plan.phases.each do |phase| + expect(page.source).to have_text(phase.title) + end + end + new_window = window_opened_by do + _select_option('phase_id', plan.phases[1].id) + click_button 'Download Plan' + end + within_window new_window do + expect(page.source).to have_text(plan.title) + expect(page.source).to have_text(plan.phases[1].title) + expect(page.source).not_to have_text(plan.phases[2].title) if plan.phases.length > 2 + end + else + _regular_download('html') end end @@ -96,8 +116,12 @@ click_link 'Download' end select('pdf') - click_button 'Download Plan' - expect(page.source).to have_text(plan.title) + if plan.phases.present? + _all_phase_download + _single_phase_download + else + _regular_download('pdf') + end end scenario 'User downloads their plan as CSV' do @@ -106,8 +130,7 @@ click_link 'Download' end select('csv') - click_button 'Download Plan' - expect(page.source).to have_text(plan.title) + _regular_download('csv') end scenario 'User downloads their plan as text' do @@ -116,8 +139,12 @@ click_link 'Download' end select('text') - click_button 'Download Plan' - expect(page.source).to have_text(plan.title) + if plan.phases.present? + _all_phase_download + _single_phase_download + else + _regular_download('text') + end end scenario 'User downloads their plan as docx' do @@ -126,7 +153,53 @@ click_link 'Download' end select('docx') + if plan.phases.present? + _all_phase_download + _single_phase_download + else + _regular_download('docx') + end + end + + # =========================== + # = Helper methods = + # =========================== + + # rubocop:disable Metrics/AbcSize + # disable Rubocup metrics check to confirm both plan title and phase title on downloaded file + def _regular_download(format) + if format == 'html' + new_window = window_opened_by do + click_button 'Download Plan' + end + within_window new_window do + expect(page.source).to have_text(plan.title) + end + else + click_button 'Download Plan' + expect(page.source).to have_text(plan.title) + end + end + + def _all_phase_download + _select_option('phase_id', 'All') click_button 'Download Plan' expect(page.source).to have_text(plan.title) + plan.phases.each do |phase| # All phase titles should be included in output + expect(page.source).to have_text(phase.title) + end + end + + def _single_phase_download + _select_option('phase_id', plan.phases[1].id) + click_button 'Download Plan' + expect(page.source).to have_text(plan.title) + expect(page.source).to have_text(plan.phases[1].title) + expect(page.source).not_to have_text(plan.phases[2].title) if plan.phases.length > 2 + end + + # rubocop:enable Metrics/AbcSize + def _select_option(select_id, option_value) + find(:id, select_id).find("option[value='#{option_value}']").select_option end end