diff --git a/app/views/admin/products_v3/_table.html.haml b/app/views/admin/products_v3/_table.html.haml index 7e94f84c32..4d31694077 100644 --- a/app/views/admin/products_v3/_table.html.haml +++ b/app/views/admin/products_v3/_table.html.haml @@ -1,6 +1,6 @@ = form_with url: bulk_update_admin_products_v3_index_path, method: :patch, id: "products-form", html: {'data-reflex-serialize-form': true, 'data-reflex': 'submit->products#bulk_update', - 'data-controller': "bulk-form"} do |form| + 'data-controller': "bulk-form", 'data-bulk-form-disable-selector-value': "#sort,#filters"} do |form| %fieldset.form-actions.hidden{ 'data-bulk-form-target': "actions" } .container .status.ten.columns diff --git a/app/webpacker/controllers/bulk_form_controller.js b/app/webpacker/controllers/bulk_form_controller.js index d008ad7485..d5a70a9105 100644 --- a/app/webpacker/controllers/bulk_form_controller.js +++ b/app/webpacker/controllers/bulk_form_controller.js @@ -3,6 +3,9 @@ import { Controller } from "stimulus"; // Manages "modified" state for a form with multiple records export default class BulkFormController extends Controller { static targets = ["actions", "modifiedSummary"]; + static values = { + disableSelector: String, + }; recordElements = {}; connect() { @@ -24,6 +27,11 @@ export default class BulkFormController extends Controller { } } + disconnect() { + // Make sure to clean up anything that happened outside + this.#disableOtherElements(false); + } + toggleModified(e) { const element = e.target; const modified = element.value != element.defaultValue; @@ -39,8 +47,11 @@ export default class BulkFormController extends Controller { return element.value != element.defaultValue; }); }).length; + const formModified = modifiedRecordCount > 0; - this.actionsTarget.classList.toggle("hidden", modifiedRecordCount == 0); + // Show actions + this.actionsTarget.classList.toggle("hidden", !formModified); + this.#disableOtherElements(formModified); // like filters and sorting // Display number of records modified const key = this.modifiedSummaryTarget && this.modifiedSummaryTarget.dataset.translationKey; @@ -48,4 +59,16 @@ export default class BulkFormController extends Controller { this.modifiedSummaryTarget.textContent = I18n.t(key, { count: modifiedRecordCount }); } } + + // private + + #disableOtherElements(disable) { + this.disableElements ||= document.querySelectorAll(this.disableSelectorValue); + + if (this.disableElements) { + this.disableElements.forEach((element) => { + element.classList.toggle("disabled-section", disable); + }); + } + } } diff --git a/app/webpacker/css/admin/products_v3.scss b/app/webpacker/css/admin/products_v3.scss index fb8cb82300..434c20fce3 100644 --- a/app/webpacker/css/admin/products_v3.scss +++ b/app/webpacker/css/admin/products_v3.scss @@ -22,9 +22,10 @@ // Form actions floats over other controls when active .form-actions { position: absolute; - top: 1em; + top: -1em; left: 0; right: 0; + z-index: 1; // Ensure tom-select and .disabled-section are covered } // Hopefully these rules will be moved to component(s). @@ -234,4 +235,22 @@ } } } + + // Blurred and non-clickable + $disabled-blur: 1.5px; + .disabled-section { + position: relative; + + &::after { + content: ""; + position: absolute; + backdrop-filter: blur($disabled-blur); + // Stretch outside for a soft blur edge: + left: -$disabled-blur; + top: -$disabled-blur; + bottom: -$disabled-blur; + right: -$disabled-blur; + z-index: 1; // Ensure tom-select is covered + } + } } diff --git a/spec/javascripts/stimulus/bulk_form_controller_test.js b/spec/javascripts/stimulus/bulk_form_controller_test.js index a5ef778926..ce1d0bda0d 100644 --- a/spec/javascripts/stimulus/bulk_form_controller_test.js +++ b/spec/javascripts/stimulus/bulk_form_controller_test.js @@ -28,7 +28,9 @@ describe("BulkFormController", () => { beforeEach(() => { document.body.innerHTML = ` -