Listen for changes on added fields

Finally, we can add new variants!

Requires updated stimulus-rails-nested-form
This commit is contained in:
David Cook
2024-02-08 17:14:25 +11:00
parent 0662708247
commit 915a5ce66b
6 changed files with 175 additions and 6 deletions

View File

@@ -46,7 +46,8 @@
%th.align-right= t('admin.products_page.columns.actions')
- products.each_with_index do |product, product_index|
= form.fields_for("products", product, index: product_index) do |product_form|
%tbody.relaxed{ 'data-record-id': product_form.object.id, 'data-controller': "nested-form" }
%tbody.relaxed{ data: { 'record-id': product_form.object.id, controller: "nested-form",
action: 'nested-form:add->bulk-form#registerElements' } }
%tr
= render partial: 'product_row', locals: { product:, f: product_form }

View File

@@ -24,6 +24,15 @@ export default class BulkFormController extends Controller {
window.removeEventListener("beforeunload", this.preventLeavingBulkForm);
}
// Register any new elements (may be called by another controller after dynamically adding fields)
registerElements() {
const registeredElements = Object.values(this.recordElements).flat();
// Select only elements that haven't been registered yet
const newElements = Array.from(this.form.elements).filter(n => !registeredElements.includes(n));
this.#registerElements(newElements);
}
toggleChanged(e) {
const element = e.target;
element.classList.toggle("changed", this.#isChanged(element));

View File

@@ -34,7 +34,7 @@
"shortcut-buttons-flatpickr": "^0.4.0",
"stimulus": "^3.2.2",
"stimulus-flatpickr": "^1.4.0",
"stimulus-rails-nested-form": "https://github.com/dacook/stimulus-rails-nested-form.git#dist",
"stimulus-rails-nested-form": "https://github.com/openfoodfoundation/stimulus-rails-nested-form.git#dist",
"stimulus_reflex": "3.5.0-rc3",
"tom-select": "^2.3.1",
"trix": "^2.0.10",

View File

@@ -181,6 +181,48 @@ describe("BulkFormController", () => {
});
});
describe("Adding new fields", () => {
beforeEach(() => {
document.body.innerHTML = `
<form id="form" data-controller="bulk-form" data-action="custom-event->bulk-form#registerElements",
<div data-record-id="1">
<input id="input1a" type="text" value="initial1a">
<template id="template">
<input id="input1b" type="text" value="initial1b">
</template>
</div>
<div data-record-id="2">
<input id="input2" type="text" value="initial2">
</div>
<input type="submit">
</form>
`;
});
describe("registerElements", () => {
beforeEach(() => {
// Add new field after controller has initialised
input1a.insertAdjacentHTML("afterend", template.innerHTML);
// Trigger bulk-form#registerElements
form.dispatchEvent(new Event("custom-event"));
});
it("onInput", () => {
input1b.value = 'updated1b';
input1b.dispatchEvent(new Event("input"));
// Expect only updated field to show changed
expect(input1b.classList).toContain('changed');
expect(input2.classList).not.toContain('changed');
// Change back to original value
input1b.value = 'initial1b';
input1b.dispatchEvent(new Event("input"));
expect(input1b.classList).not.toContain('changed');
});
})
});
// unable to test disconnect at this stage
// describe("disconnect()", () => {
// it("resets other elements", () => {

View File

@@ -357,7 +357,6 @@ describe 'As an admin, I can manage products', feature: :admin_style_v3 do
fill_in "On Hand", with: "3"
expect {
pending "changes are not detected"
click_button "Save changes"
expect(page).to have_content "Changes saved"
@@ -432,7 +431,6 @@ describe 'As an admin, I can manage products', feature: :admin_style_v3 do
it "saves changes after fixing errors" do
expect {
pending "changes are not detected"
click_button "Save changes"
variant_a1.reload
@@ -459,6 +457,125 @@ describe 'As an admin, I can manage products', feature: :admin_style_v3 do
end
end
end
describe "adding variants" do
it "creates a new variant" do
click_on "New variant"
# find empty row for Apples
new_variant_row = find_field("Name", placeholder: "Apples", with: "").ancestor("tr")
expect(new_variant_row).to be_present
within new_variant_row do
fill_in "Name", with: "Large box"
fill_in "SKU", with: "APL-02"
fill_in "Unit", with: 1000
fill_in "Price", with: 10.25
click_on "On Hand" # activate popout
end
fill_in "On Hand", with: "3"
expect {
click_button "Save changes"
expect(page).to have_content "Changes saved"
product_a.reload
}.to change { product_a.variants.count }.by(1)
new_variant = product_a.variants.last
expect(new_variant.display_name).to eq "Large box"
expect(new_variant.sku).to eq "APL-02"
expect(new_variant.price).to eq 10.25
expect(new_variant.unit_value).to eq 1000
expect(new_variant.on_hand).to eq 3
within row_containing_name("Large box") do
expect(page).to have_field "Name", with: "Large box"
expect(page).to have_field "SKU", with: "APL-02"
expect(page).to have_field "Price", with: "10.25"
expect(page).to have_content "1kg"
expect(page).to have_css "button[aria-label='On Hand']", text: "3"
end
end
context "with invalid data" do
before do
click_on "New variant"
# find empty row for Apples
new_variant_row = find_field("Name", placeholder: "Apples", with: "").ancestor("tr")
expect(new_variant_row).to be_present
within new_variant_row do
fill_in "Name", with: "N" * 256 # too long
fill_in "SKU", with: "n" * 256
fill_in "Unit", with: "" # can't be blank
fill_in "Price", with: "10.25" # valid
end
end
it "shows errors for both existing and new variant fields" do
# Update existing variant with invalid data too
within row_containing_name("Medium box") do
fill_in "Name", with: "M" * 256
fill_in "SKU", with: "m" * 256
fill_in "Price", with: "10.25"
end
expect {
click_button "Save changes"
expect(page).to have_content "1 product could not be saved"
expect(page).to have_content "Please review the errors and try again"
variant_a1.reload
}.to_not change { variant_a1.display_name }
# New variant
within row_containing_name("N" * 256) do
expect(page).to have_field "Name", with: "N" * 256
expect(page).to have_field "SKU", with: "n" * 256
expect(page).to have_content "is too long"
expect(page).to have_field "Unit", with: ""
expect(page).to have_content "can't be blank"
expect(page).to have_field "Price", with: "10.25" # other updated value is retained
end
# Existing variant
within row_containing_name("M" * 256) do
expect(page).to have_field "Name", with: "M" * 256
expect(page).to have_field "SKU", with: "m" * 256
expect(page).to have_content "is too long"
end
end
it "saves changes after fixing errors" do
expect {
click_button "Save changes"
variant_a1.reload
}.to_not change { variant_a1.display_name }
within row_containing_name("N" * 256) do
fill_in "Name", with: "Nice box"
fill_in "SKU", with: "APL-02"
fill_in "Unit", with: "200"
end
expect {
click_button "Save changes"
expect(page).to have_content "Changes saved"
product_a.reload
}.to change { product_a.variants.count }.by(1)
new_variant = product_a.variants.last
expect(new_variant.display_name).to eq "Nice box"
expect(new_variant.sku).to eq "APL-02"
expect(new_variant.price).to eq 10.25
expect(new_variant.unit_value).to eq 200
end
end
end
end
describe "edit image" do

View File

@@ -8350,9 +8350,9 @@ stimulus-flatpickr@^1.4.0:
resolved "https://registry.yarnpkg.com/stimulus-flatpickr/-/stimulus-flatpickr-1.4.0.tgz#a41071a3e69cfc50b7eaaacf356fc0ab1ab0543c"
integrity sha512-rcC/c9+E+f5W2kOjaaLShtf3i+p95ACqt+oGzSAgeuZh2YeIN8gW4EWO7h0STBLzSVPl6BjIfPWP7upMPavIVQ==
"stimulus-rails-nested-form@https://github.com/dacook/stimulus-rails-nested-form.git#dist":
"stimulus-rails-nested-form@https://github.com/openfoodfoundation/stimulus-rails-nested-form.git#dist":
version "4.1.0"
resolved "https://github.com/dacook/stimulus-rails-nested-form.git#d3b82ea638a7156f1122736cf739ab1821a1817e"
resolved "https://github.com/openfoodfoundation/stimulus-rails-nested-form.git#d3b82ea638a7156f1122736cf739ab1821a1817e"
stimulus@^3.2.2:
version "3.2.2"