diff --git a/app/webpacker/controllers/bulk_form_controller.js b/app/webpacker/controllers/bulk_form_controller.js index d5a70a9105..3c98a5ce65 100644 --- a/app/webpacker/controllers/bulk_form_controller.js +++ b/app/webpacker/controllers/bulk_form_controller.js @@ -30,6 +30,7 @@ export default class BulkFormController extends Controller { disconnect() { // Make sure to clean up anything that happened outside this.#disableOtherElements(false); + window.removeEventListener("beforeunload", this.preventLeavingBulkForm); } toggleModified(e) { @@ -58,6 +59,21 @@ export default class BulkFormController extends Controller { if (key) { this.modifiedSummaryTarget.textContent = I18n.t(key, { count: modifiedRecordCount }); } + + // Prevent accidental data loss + if (formModified) { + window.addEventListener("beforeunload", this.preventLeavingBulkForm); + } else { + window.removeEventListener("beforeunload", this.preventLeavingBulkForm); + } + } + + preventLeavingBulkForm(e) { + // Cancel the event + e.preventDefault(); + // Chrome requires returnValue to be set. Other browsers may display this if provided, but let's + // not create a new translation key, and keep the behaviour consistent. + e.returnValue = ""; } // private diff --git a/spec/javascripts/stimulus/bulk_form_controller_test.js b/spec/javascripts/stimulus/bulk_form_controller_test.js index ce1d0bda0d..8375f51eb0 100644 --- a/spec/javascripts/stimulus/bulk_form_controller_test.js +++ b/spec/javascripts/stimulus/bulk_form_controller_test.js @@ -148,6 +148,7 @@ describe("BulkFormController", () => { // expect(disable1.classList).not.toContain('disabled-section'); // expect(disable2.classList).not.toContain('disabled-section'); + // //TODO: expect window to have no beforeunload event listener // }); // }); }); diff --git a/spec/system/admin/products_v3/products_spec.rb b/spec/system/admin/products_v3/products_spec.rb index 80f2bc19f0..598395645b 100644 --- a/spec/system/admin/products_v3/products_spec.rb +++ b/spec/system/admin/products_v3/products_spec.rb @@ -211,6 +211,14 @@ describe 'As an admin, I can see the new product page' do fill_in "Name", with: "Pommes" end + # Expect to be alerted when attempting to navigate away. Cancel. + dismiss_confirm do + click_link "Dashboard" + end + within row_containing_name("Apples") do + expect(page).to have_field "Name", with: "Pommes" # Changed value wasn't lost + end + # Meanwhile, the SKU was updated product_a.update! sku: "APL-10"