diff --git a/app/jobs/report_job.rb b/app/jobs/report_job.rb index c72cb98b2e..a372dd26e2 100644 --- a/app/jobs/report_job.rb +++ b/app/jobs/report_job.rb @@ -53,7 +53,14 @@ class ReportJob < ApplicationJob end def actioncable_content(format, blob) - return blob.result if format.to_sym == :html + if format.to_sym == :html + return blob.result if blob.byte_size < 10**6 # 1 MB + + return render( + partial: "admin/reports/display", + locals: { file_url: blob.expiring_service_url } + ) + end render(partial: "admin/reports/download", locals: { file_url: blob.expiring_service_url }) end diff --git a/app/views/admin/reports/_display.html.haml b/app/views/admin/reports/_display.html.haml new file mode 100644 index 0000000000..777710540c --- /dev/null +++ b/app/views/admin/reports/_display.html.haml @@ -0,0 +1,5 @@ +.download + %p.notice= t ".report_is_big" + %p= link_to t(".display_anyway"), file_url, target: "_blank", + class: "button icon icon-file", + onclick: "(async function (element) { element.outerHTML = await (await fetch(element.href)).text() })(this); return false;" diff --git a/config/locales/en.yml b/config/locales/en.yml index 2c4e737c0f..f8059b4487 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1670,6 +1670,9 @@ en: pack_by_customer: Pack By Customer pack_by_supplier: Pack By Supplier pack_by_product: Pack By Product + display: + report_is_big: "This report is big and may slow down your device." + display_anyway: "Display anyway" download: button: "Download Report" show: diff --git a/spec/system/admin/reports_spec.rb b/spec/system/admin/reports_spec.rb index a8de146328..ba860cf264 100644 --- a/spec/system/admin/reports_spec.rb +++ b/spec/system/admin/reports_spec.rb @@ -55,6 +55,30 @@ RSpec.describe ' expect(page).to have_content "Müller" end + it "requires confirmation to display big reports" do + # Mock data is much faster and accurate than creating many orders: + allow_any_instance_of(Reporting::Reports::Customers::Base) + .to receive(:columns).and_return( + { + first_name: proc { |_| "Little Bobby Tables " * (10**5) }, # 2 MB + } + ) + + # We still need an order for the report to render a row: + create(:completed_order_with_totals) + + login_as_admin + visit admin_report_path(report_type: :customers) + run_report + + expect(page).to have_content "This report is big" + expect(page).not_to have_content "Little Bobby Tables" + + click_on "Display anyway" + expect(page).to have_content "FIRST NAME" + expect(page).to have_content "Little Bobby Tables" + end + it "displays a friendly timeout message and offers download" do login_as_admin visit admin_report_path(report_type: :customers)