/* ─── BOM Detail Expansion ─── */ function renderBomDetails(b) { let html = '
'; if (b.cutTemplate) { const ct = b.cutTemplate; const displayName = ct.dxfFilePath?.split(/[/\\]/).pop() || ''; html += `
${icons.laser} Cut Template
File${esc(displayName)}
Thickness${fmtThickness(ct.thickness)}
K-Factor${ct.kFactor != null ? ct.kFactor : '\u2014'}
Bend Radius${ct.defaultBendRadius != null ? ct.defaultBendRadius.toFixed(4) + '"' : '\u2014'}
`; if (ct.contentHash) { html += `
${icons.download} Download DXF ${esc(displayName)}
`; } } if (b.formProgram) { const fp = b.formProgram; html += `
${icons.bend} Form Program
Program${esc(fp.programName)}
Thickness${fmtThickness(fp.thickness)}
Material${esc(fp.materialType)}
K-Factor${fp.kFactor != null ? fp.kFactor : '\u2014'}
Bends${fp.bendCount}
Upper Tools${esc(fp.upperToolNames) || '\u2014'}
Lower Tools${esc(fp.lowerToolNames) || '\u2014'}
${fp.setupNotes ? `
Setup Notes${esc(fp.setupNotes)}
` : ''}`; } html += '
'; return html; } function toggleEquipGroup(id) { const group = document.getElementById(id); const icon = document.getElementById(id + '-icon'); if (!group) return; group.classList.toggle('collapsed'); if (icon) icon.classList.toggle('open', !group.classList.contains('collapsed')); } function toggleBomRow(id) { const row = document.getElementById(id); const icon = document.getElementById(id + '-icon'); if (!row) return; const visible = row.style.display !== 'none'; row.style.display = visible ? 'none' : ''; if (icon) icon.classList.toggle('open', !visible); } /* ─── Cut List Modal ─── */ function showCutListModal(bomItems) { const cutItems = bomItems.filter(b => b.cutTemplate); if (cutItems.length === 0) { showToast('No cut templates found'); return; } const rows = cutItems.map(b => { const ct = b.cutTemplate; const name = ct.cutTemplateName || ct.dxfFilePath?.split(/[/\\]/).pop()?.replace(/\.dxf$/i, '') || b.partName || ''; const qty = b.qty ?? ''; return { name, qty }; }); const tableRows = rows.map((r, i) => ` ${esc(r.name)} ${r.qty} `).join(''); // Remove existing modal if any const existing = document.getElementById('cut-list-modal'); if (existing) existing.remove(); const modal = document.createElement('div'); modal.id = 'cut-list-modal'; modal.className = 'modal-overlay'; modal.innerHTML = ` `; document.body.appendChild(modal); // Store data for copy modal._cutData = rows; // Close on backdrop click modal.addEventListener('click', e => { if (e.target === modal) closeCutListModal(); }); // Close on Escape modal._keyHandler = e => { if (e.key === 'Escape') closeCutListModal(); }; document.addEventListener('keydown', modal._keyHandler); } function closeCutListModal() { const modal = document.getElementById('cut-list-modal'); if (!modal) return; document.removeEventListener('keydown', modal._keyHandler); modal.remove(); } function copyCutList() { const modal = document.getElementById('cut-list-modal'); if (!modal || !modal._cutData) return; const text = modal._cutData.map(r => `${r.name}\t${r.qty}`).join('\n'); navigator.clipboard.writeText(text).then(() => { const btn = document.getElementById('copy-cut-list-btn'); if (btn) { btn.innerHTML = `${icons.check} Copied!`; btn.classList.remove('btn-cyan'); btn.classList.add('btn-green'); setTimeout(() => { btn.innerHTML = `${icons.clipboard} Copy`; btn.classList.remove('btn-green'); btn.classList.add('btn-cyan'); }, 2000); } }); } function showToast(msg) { const t = document.createElement('div'); t.className = 'toast'; t.textContent = msg; document.body.appendChild(t); setTimeout(() => t.remove(), 2500); }