From 98a29785a7d5f81621d844d6e92509d92f6c1a57 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 17 May 2024 16:11:28 +1000 Subject: [PATCH 1/2] Load large on-screen reports on demand Sending large reports via Cable Ready is unreliable. The events are dropped at an unknown point and the report is never displayed to the user. Instead we just send a link to the report via Cable Ready and offer a button to load the report on screen. This has the UX benefit of warning the user about the size as well. Weaker devices can struggle rendering big HTML documents. --- app/jobs/report_job.rb | 9 +++++++- app/views/admin/reports/_display.html.haml | 5 +++++ config/locales/en.yml | 3 +++ spec/system/admin/reports_spec.rb | 24 ++++++++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 app/views/admin/reports/_display.html.haml 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..b87ab0345d --- /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 (await fetch(element.href))).text() })(this); return false;" diff --git a/config/locales/en.yml b/config/locales/en.yml index e4be4f6843..1f840a585a 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) From c8e134cef55686696ff9140e90b839525ddc6668 Mon Sep 17 00:00:00 2001 From: Maikel Date: Tue, 25 Jun 2024 11:50:01 +1000 Subject: [PATCH 2/2] Remove redundant `wait` loading report content Co-authored-by: Gaetan Craig-Riou <40413322+rioug@users.noreply.github.com> --- app/views/admin/reports/_display.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/reports/_display.html.haml b/app/views/admin/reports/_display.html.haml index b87ab0345d..777710540c 100644 --- a/app/views/admin/reports/_display.html.haml +++ b/app/views/admin/reports/_display.html.haml @@ -2,4 +2,4 @@ %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 (await fetch(element.href))).text() })(this); return false;" + onclick: "(async function (element) { element.outerHTML = await (await fetch(element.href)).text() })(this); return false;"