Skip to content

Commit 86a024c

Browse files
committed
5446 replace js/jquery solution with stimulus controller
1 parent 35e51cc commit 86a024c

File tree

4 files changed

+132
-150
lines changed

4 files changed

+132
-150
lines changed

app/javascript/application.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import 'bootstrap'
3131
import 'controllers'
3232

3333
import 'utils/barcode_items'
34-
import 'utils/audit_duplicates'
3534
import 'utils/barcode_scan'
3635
import 'utils/distributions_and_transfers'
3736
import 'utils/donations'
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { Controller } from "@hotwired/stimulus"
2+
3+
export default class extends Controller {
4+
connect() {
5+
this.boundHandleSubmit = this.handleSubmit.bind(this)
6+
this.element.addEventListener("submit", this.boundHandleSubmit)
7+
}
8+
9+
handleSubmit(event) {
10+
const submitter = event.submitter
11+
12+
if (!submitter?.name) return
13+
if (!submitter.name.includes('save_progress') &&
14+
!submitter.name.includes('confirm_audit')) {
15+
return
16+
}
17+
18+
event.preventDefault()
19+
20+
const duplicates = this.findDuplicates()
21+
22+
if (duplicates.length > 0) {
23+
this.showModal(duplicates, submitter.name)
24+
} else {
25+
this.submitForm(submitter.name)
26+
}
27+
}
28+
29+
findDuplicates() {
30+
const itemCounts = {}
31+
const itemData = {}
32+
33+
this.element.querySelectorAll('select[name*="[item_id]"]').forEach(select => {
34+
const itemId = select.value
35+
const itemText = select.options[select.selectedIndex]?.text
36+
const section = select.closest('.line_item_section')
37+
const quantityInput = section?.querySelector('input[name*="[quantity]"]')
38+
const quantity = parseInt(quantityInput?.value) || 0
39+
const barcodeValue = section?.querySelector('.__barcode_item_lookup')?.value || ''
40+
41+
if (!itemId || itemText === "Choose an item" || quantity === 0) return
42+
43+
itemCounts[itemId] = (itemCounts[itemId] || 0) + 1
44+
if (!itemData[itemId]) {
45+
itemData[itemId] = { name: itemText, entries: [] }
46+
}
47+
itemData[itemId].entries.push({ quantity, section, barcode: barcodeValue })
48+
})
49+
50+
return Object.keys(itemCounts)
51+
.filter(id => itemCounts[id] > 1)
52+
.map(id => itemData[id])
53+
}
54+
55+
showModal(duplicates, buttonName) {
56+
const itemRows = duplicates.map(item => {
57+
const entries = item.entries
58+
const total = entries.reduce((sum, entry) => sum + entry.quantity, 0)
59+
const rows = entries.map(entry => {
60+
const barcodeLine = entry.barcode ? `<div class="duplicate-barcode">Barcode: ${entry.barcode}</div>` : ''
61+
return `<div class="duplicate-entry">❐ ${item.name} : ${entry.quantity}${barcodeLine}</div>`
62+
}).join('')
63+
return `<div class="duplicate-container">${rows}<div class="duplicate-merged">→ Merged Result: ${item.name} : ${total}</div></div>`
64+
}).join('')
65+
66+
const modalHtml = `
67+
<div class="modal fade" id="duplicateItemsModal" tabindex="-1">
68+
<div class="modal-dialog modal-dialog-scrollable">
69+
<div class="modal-content">
70+
<div class="modal-header">
71+
<h5 class="modal-title">Multiple Item Entries Detected</h5>
72+
<button type="button" class="close" data-bs-dismiss="modal">
73+
<span>&times;</span>
74+
</button>
75+
</div>
76+
<div class="modal-body">
77+
<p><strong>The following items have multiple entries:</strong></p>
78+
<div class="duplicate-items-list">${itemRows}</div>
79+
</div>
80+
<div class="modal-footer duplicate-modal-footer">
81+
<p class="duplicate-modal-text">
82+
Choose <strong>Merge Items</strong> to combine quantities and continue, or <strong>Make Changes</strong> to go back and edit.
83+
</p>
84+
<div class="duplicate-modal-buttons">
85+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Make Changes</button>
86+
<button type="button" class="btn btn-success" id="confirmMerge">Merge Items</button>
87+
</div>
88+
</div>
89+
</div>
90+
</div>
91+
</div>
92+
`
93+
94+
document.getElementById('duplicateItemsModal')?.remove()
95+
document.body.insertAdjacentHTML('beforeend', modalHtml)
96+
97+
const modal = new bootstrap.Modal(document.getElementById('duplicateItemsModal'))
98+
modal.show()
99+
100+
document.getElementById('confirmMerge').addEventListener('click', () => {
101+
this.mergeAndSubmit(duplicates, buttonName)
102+
})
103+
}
104+
105+
mergeAndSubmit(duplicates, buttonName) {
106+
duplicates.forEach(item => {
107+
const total = item.entries.reduce((sum, e) => sum + e.quantity, 0)
108+
item.entries[0].section.querySelector('input[name*="[quantity]"]').value = total
109+
item.entries.slice(1).forEach(e => e.section.remove())
110+
})
111+
112+
document.getElementById('duplicateItemsModal')?.remove()
113+
document.querySelector('.modal-backdrop')?.remove()
114+
document.body.classList.remove('modal-open')
115+
document.body.style.removeProperty('overflow')
116+
117+
this.submitForm(buttonName)
118+
}
119+
120+
submitForm(buttonName) {
121+
this.element.removeEventListener('submit', this.boundHandleSubmit)
122+
123+
const input = document.createElement('input')
124+
input.type = 'hidden'
125+
input.name = buttonName
126+
input.value = '1'
127+
this.element.appendChild(input)
128+
129+
this.element.submit()
130+
}
131+
}

app/javascript/utils/audit_duplicates.js

Lines changed: 0 additions & 148 deletions
This file was deleted.

app/views/audits/_form.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<div class="box-header with-border">
1414
</div>
1515
<div class="box-body">
16-
<%= simple_form_for @audit, data: { controller: "form-input" }, html: {class: "storage-location-required"} do |f| %>
16+
<%= simple_form_for @audit, data: { controller: "form-input audit-duplicates" }, html: {class: "storage-location-required"} do |f| %>
1717
<%= render partial: "storage_locations/source", object: f, locals: { label: "Storage location", error: "What storage location are you auditing?", include_omitted_items: true } %>
1818
<fieldset style="margin-bottom: 2rem;">
1919
<legend>Items in this audit</legend>

0 commit comments

Comments
 (0)