Skip to content

Commit 25493d8

Browse files
Add confirmation step on kit creation (fixes #5566)
1 parent aecd7fc commit 25493d8

2 files changed

Lines changed: 134 additions & 7 deletions

File tree

app/javascript/controllers/duplicate_items_controller.js

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,96 @@ export default class extends Controller {
2323
if (!this.itemSubmitButtonTargets.includes(submitter)) return
2424

2525
event.preventDefault()
26-
26+
27+
this.showConfirmationModal(submitter.name)
28+
}
29+
30+
checkForDuplicatesAndSubmit(buttonName) {
2731
const duplicates = this.findDuplicates()
28-
32+
2933
if (duplicates.length > 0) {
30-
this.showModal(duplicates, submitter.name)
34+
this.showDuplicatesModal(duplicates, buttonName)
3135
} else {
32-
this.submitForm(submitter.name)
36+
this.submitForm(buttonName)
3337
}
3438
}
3539

40+
collectLineItems() {
41+
const items = []
42+
43+
this.element.querySelectorAll('select[name*="[item_id]"]').forEach(select => {
44+
const itemId = select.value
45+
const itemText = select.options[select.selectedIndex]?.text
46+
const section = select.closest('.line_item_section')
47+
const quantityInput = section?.querySelector('input[name*="[quantity]"]')
48+
const quantity = parseInt(quantityInput?.value) || 0
49+
50+
if (!itemId || itemText === "Choose an item" || quantity === 0) return
51+
52+
items.push({ name: itemText, quantity })
53+
})
54+
55+
return items
56+
}
57+
58+
showConfirmationModal(buttonName) {
59+
const name = this.element.querySelector('#kit_name')?.value || ''
60+
const value = parseFloat(this.element.querySelector('#kit_value_in_dollars')?.value || 0).toFixed(2)
61+
const items = this.collectLineItems()
62+
63+
const itemRows = items.map(item =>
64+
`<tr><td>${item.name}</td><td>${item.quantity}</td></tr>`
65+
).join('')
66+
67+
const modalHtml = `
68+
<div class="modal fade" id="kitConfirmationModal" tabindex="-1">
69+
<div class="modal-dialog modal-lg">
70+
<div class="modal-content">
71+
<div class="modal-header">
72+
<h5 class="modal-title">Kit Creation Confirmation</h5>
73+
<button type="button" class="close" data-bs-dismiss="modal">
74+
<span>&times;</span>
75+
</button>
76+
</div>
77+
<div class="modal-body">
78+
<p class="lead">You are about to create a kit named
79+
<span class="fw-bolder fst-italic" data-testid="kit-confirmation-name">${name}</span>
80+
with value
81+
<span class="fw-bolder fst-italic" data-testid="kit-confirmation-value">$${value}</span>
82+
</p>
83+
<table class="table">
84+
<thead>
85+
<tr>
86+
<th>Item Name</th>
87+
<th>Quantity</th>
88+
</tr>
89+
</thead>
90+
<tbody>${itemRows}</tbody>
91+
</table>
92+
<p>Please confirm that this is the correct composition of the kit. Note: You will
93+
<span class="text-danger fw-bold">not</span> be able to edit the items contained in the kit.</p>
94+
</div>
95+
<div class="modal-footer">
96+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No, I need to make changes</button>
97+
<button type="button" class="btn btn-success" id="kitConfirmationYes">Yes, it's correct</button>
98+
</div>
99+
</div>
100+
</div>
101+
</div>
102+
`
103+
104+
document.getElementById('kitConfirmationModal')?.remove()
105+
document.body.insertAdjacentHTML('beforeend', modalHtml)
106+
107+
const modal = new bootstrap.Modal(document.getElementById('kitConfirmationModal'))
108+
modal.show()
109+
110+
document.getElementById('kitConfirmationYes').addEventListener('click', () => {
111+
modal.hide()
112+
this.checkForDuplicatesAndSubmit(buttonName)
113+
})
114+
}
115+
36116
findDuplicates() {
37117
const itemCounts = {}
38118
const itemData = {}
@@ -59,7 +139,7 @@ export default class extends Controller {
59139
.map(id => itemData[id])
60140
}
61141

62-
showModal(duplicates, buttonName) {
142+
showDuplicatesModal(duplicates, buttonName) {
63143
const itemRows = duplicates.map(item => {
64144
const entries = item.entries
65145
const total = entries.reduce((sum, entry) => sum + entry.quantity, 0)

spec/system/kit_system_spec.rb

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,48 @@
4747

4848
click_button "Save"
4949

50+
expect(page).to have_css("#kitConfirmationModal", visible: true)
51+
within "#kitConfirmationModal" do
52+
expect(page).to have_content("Kit Creation Confirmation")
53+
expect(find(:element, "data-testid": "kit-confirmation-name")).to have_text(kit_traits[:name])
54+
expect(find(:element, "data-testid": "kit-confirmation-value")).to have_text("$10.10")
55+
expect(page).to have_content(item.name)
56+
expect(page).to have_content(quantity_per_kit.to_s)
57+
expect(page).to have_css(".text-danger", text: "not")
58+
click_button "Yes, it's correct"
59+
end
60+
5061
expect(page.find(".alert")).to have_content "Kit created successfully"
5162
expect(page).to have_content(kit_traits[:name])
5263
expect(page).to have_content("#{quantity_per_kit} #{item.name}")
5364
end
5465

66+
it "returns to the form with values intact when declining the confirmation" do
67+
visit new_kit_path
68+
kit_traits = attributes_for(:kit)
69+
70+
fill_in "Name", with: kit_traits[:name]
71+
find(:css, '#kit_value_in_dollars').set('10.10')
72+
73+
item = Item.last
74+
quantity_per_kit = 5
75+
select item.name, from: "kit_item_line_items_attributes_0_item_id"
76+
find(:css, '#kit_item_line_items_attributes_0_quantity').set(quantity_per_kit)
77+
78+
click_button "Save"
79+
80+
expect(page).to have_css("#kitConfirmationModal", visible: true)
81+
within "#kitConfirmationModal" do
82+
click_button "No, I need to make changes"
83+
end
84+
85+
expect(page).to have_no_css("#kitConfirmationModal", visible: true)
86+
expect(page).to have_current_path(new_kit_path)
87+
expect(page).to have_no_content("Kit created successfully")
88+
expect(page).to have_field("Name", with: kit_traits[:name])
89+
expect(page).to have_field("kit_item_line_items_attributes_0_quantity", with: quantity_per_kit.to_s)
90+
end
91+
5592
it "can add items correctly" do
5693
visit new_kit_path
5794
new_barcode = "1234567890"
@@ -221,6 +258,11 @@
221258

222259
click_button "Save"
223260

261+
expect(page).to have_css("#kitConfirmationModal", visible: true)
262+
within "#kitConfirmationModal" do
263+
click_button "Yes, it's correct"
264+
end
265+
224266
expect(page.find(".alert")).to have_content "Name can't be blank"
225267
expect(page).to have_content(kit_traits[:quantity])
226268
expect(page).to have_content(item.name)
@@ -253,10 +295,15 @@
253295
fill_in quantity_input[:id], with: "15"
254296
end
255297

256-
# Try to save - should trigger duplicate detection modal
298+
# Try to save - the confirmation preview appears first
257299
click_button "Save"
258300

259-
# JavaScript modal should appear
301+
expect(page).to have_css("#kitConfirmationModal", visible: true)
302+
within "#kitConfirmationModal" do
303+
click_button "Yes, it's correct"
304+
end
305+
306+
# Confirming then triggers duplicate detection
260307
expect(page).to have_css("#duplicateItemsModal", visible: true)
261308
expect(page).to have_content("Multiple Item Entries Detected")
262309
expect(page).to have_content("Merge Items")

0 commit comments

Comments
 (0)