diff --git a/app/controllers/spree/admin/invoices_controller.rb b/app/controllers/spree/admin/invoices_controller.rb index 701652e031..91d637affd 100644 --- a/app/controllers/spree/admin/invoices_controller.rb +++ b/app/controllers/spree/admin/invoices_controller.rb @@ -15,6 +15,8 @@ module Spree invoice_pdf = filepath(invoice_id) send_file(invoice_pdf, type: 'application/pdf', disposition: :inline) + rescue ActionController::MissingFile + render "errors/not_found", status: :not_found, formats: :html end def generate diff --git a/app/reflexes/admin/orders_reflex.rb b/app/reflexes/admin/orders_reflex.rb index c37508785f..bc952506c2 100644 --- a/app/reflexes/admin/orders_reflex.rb +++ b/app/reflexes/admin/orders_reflex.rb @@ -37,9 +37,12 @@ module Admin return if notify_if_abn_related_issue(visible_orders) + file_id = "#{Time.zone.now.to_i}-#{SecureRandom.hex(2)}" + cable_ready.append( selector: "#orders-index", - html: render(partial: "spree/admin/orders/bulk/invoice_modal") + html: render(partial: "spree/admin/orders/bulk/invoice_modal", + locals: { invoice_url: "/admin/orders/invoices/#{file_id}" }) ).broadcast # Preserve order of bulk_ids. @@ -49,7 +52,7 @@ module Admin BulkInvoiceJob.perform_later( visible_order_ids, - "tmp/invoices/#{Time.zone.now.to_i}-#{SecureRandom.hex(2)}.pdf", + "tmp/invoices/#{file_id}.pdf", channel: SessionChannel.for_request(request), current_user_id: current_user.id ) diff --git a/app/views/spree/admin/orders/bulk/_invoice_link.html.haml b/app/views/spree/admin/orders/bulk/_invoice_link.html.haml index dbc5c455d5..8ae3c0294a 100644 --- a/app/views/spree/admin/orders/bulk/_invoice_link.html.haml +++ b/app/views/spree/admin/orders/bulk/_invoice_link.html.haml @@ -3,5 +3,5 @@ %br -%a.button.primary{ target: '_blank', href: invoice_url } +%a.button.primary{ target: '_blank', href: invoice_url, 'data-file-loading-target': "link"} = t('js.admin.orders.index.view_file') diff --git a/app/views/spree/admin/orders/bulk/_invoice_modal.html.haml b/app/views/spree/admin/orders/bulk/_invoice_modal.html.haml index 53f7982f25..50ec9f75df 100644 --- a/app/views/spree/admin/orders/bulk/_invoice_modal.html.haml +++ b/app/views/spree/admin/orders/bulk/_invoice_modal.html.haml @@ -1,4 +1,4 @@ -%div{ id: "bulk_invoices_modal", "data-controller": "modal", "data-modal-instant-value": true, "data-action": "keyup@document->modal#closeIfEscapeKey" } +%div{ id: "bulk_invoices_modal", "data-controller": "modal file-loading", "data-modal-instant-value": true, "data-action": "keyup@document->modal#closeIfEscapeKey" } .reveal-modal-bg.fade{ "data-modal-target": "background", "data-action": "click->modal#remove" } .reveal-modal.fade.tiny.modal-component{ "data-modal-target": "modal" } %div.fullwidth.align-center @@ -7,9 +7,11 @@ %br %br .modal-content - .modal-loading + .modal-loading{ 'data-file-loading-target': "loading" } %img.spinner{ src: image_path("/spinning-circles.svg") } %br %br %p= t('js.admin.orders.index.please_wait') %br + %div.hidden{ 'data-file-loading-target': "loaded" } + = render partial: "spree/admin/orders/bulk/invoice_link", locals: { invoice_url: } diff --git a/app/webpacker/controllers/file_loading_controller.js b/app/webpacker/controllers/file_loading_controller.js new file mode 100644 index 0000000000..b77cca4d1d --- /dev/null +++ b/app/webpacker/controllers/file_loading_controller.js @@ -0,0 +1,38 @@ +import { Controller } from "stimulus"; +const NOTIFICATION_TIME = 5000; // 5 seconds +const HIDE_CLASS = "hidden"; + +export default class extends Controller { + static targets = ["loading", "loaded", "link"]; + + connect() { + this.setTimeout(); + } + + disconnect() { + this.clearTimeout(); + } + + checkFile() { + if (!this.loadedTarget.classList.contains(HIDE_CLASS)) { + // If link already loaded successfully, we don't need to check anymore. + return; + } + + const response = fetch(this.linkTarget.href).then((response) => { + if (response.status == 200) { + this.loadingTarget.classList.add(HIDE_CLASS); + this.loadedTarget.classList.remove(HIDE_CLASS); + } else { + this.setTimeout(); + } + }); + } + + setTimeout(){ + this.timeout = setTimeout(this.checkFile.bind(this), NOTIFICATION_TIME); + } + clearTimeout(){ + clearTimeout(this.timeout); + } +}