Promote job powders to top of Log Material dropdown

Powders already assigned to this job's coats appear under a 'This Job'
section header, then a divider, then 'All Inventory' — so the most
relevant choices are always one click away.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 21:49:46 -04:00
parent 79c8c7e6a4
commit f380c152ca
3 changed files with 47 additions and 18 deletions
@@ -4,6 +4,7 @@
*/
(function () {
let _items = [];
let _jobPowderIds = new Set();
let _modal = null;
// ── Combobox state ────────────────────────────────────────────────────────
@@ -35,6 +36,23 @@
}
}
function lmMakeRow(it) {
const label = it.name + (it.unitOfMeasure ? ' (' + it.unitOfMeasure + ')' : '');
const mfr = it.manufacturer
? `<span class="text-muted ms-1" style="font-size:.78rem;">${escLm(it.manufacturer)}</span>`
: '';
return `<div class="lm-item-opt" style="padding:.35rem .75rem;font-size:.875rem;cursor:pointer;"
data-id="${it.id}"
data-qty="${it.quantityOnHand}"
data-uom="${escLm(it.unitOfMeasure || '')}"
data-label="${escLm(label)}"
onmousedown="event.preventDefault(); lmComboSelect(this)"
onmouseenter="this.style.background='#f0f4ff'"
onmouseleave="this.classList.contains('lm-active') ? null : this.style.background=''">
${escLm(label)}${mfr}
</div>`;
}
function lmComboRender(query) {
const dd = document.getElementById('lmItemDropdown');
if (!dd) return;
@@ -47,20 +65,21 @@
dd.innerHTML = '<div class="px-3 py-2 text-muted small">No items match.</div>';
return;
}
dd.innerHTML = filtered.map(it => {
const label = it.name + (it.unitOfMeasure ? ' (' + it.unitOfMeasure + ')' : '');
const mfr = it.manufacturer ? `<span class="text-muted ms-1" style="font-size:.78rem;">${escLm(it.manufacturer)}</span>` : '';
return `<div class="lm-item-opt" style="padding:.35rem .75rem;font-size:.875rem;cursor:pointer;"
data-id="${it.id}"
data-qty="${it.quantityOnHand}"
data-uom="${escLm(it.unitOfMeasure || '')}"
data-label="${escLm(label)}"
onmousedown="event.preventDefault(); lmComboSelect(this)"
onmouseenter="this.style.background='#f0f4ff'"
onmouseleave="this.classList.contains('lm-active') ? null : this.style.background=''">
${escLm(label)}${mfr}
</div>`;
}).join('');
const jobItems = filtered.filter(it => _jobPowderIds.has(it.id));
const otherItems = filtered.filter(it => !_jobPowderIds.has(it.id));
let html = '';
if (jobItems.length > 0) {
html += '<div class="px-3 py-1 text-muted" style="font-size:.72rem;letter-spacing:.04em;text-transform:uppercase;background:#f8f9fa;border-bottom:1px solid #dee2e6;">This Job</div>';
html += jobItems.map(lmMakeRow).join('');
if (otherItems.length > 0) {
html += '<div style="height:1px;background:#dee2e6;margin:.25rem 0;"></div>';
html += '<div class="px-3 py-1 text-muted" style="font-size:.72rem;letter-spacing:.04em;text-transform:uppercase;background:#f8f9fa;border-bottom:1px solid #dee2e6;">All Inventory</div>';
}
}
html += otherItems.map(lmMakeRow).join('');
dd.innerHTML = html;
}
function lmComboShow() {
@@ -245,6 +264,7 @@
if (!cfg) return;
_items = cfg.inventoryItems || [];
_jobPowderIds = new Set(cfg.jobPowderIds || []);
_modal = new bootstrap.Modal(document.getElementById('logMaterialModal'));
document.getElementById('lmQuantity').addEventListener('input', lmOnQtyInput);