diff --git a/deploy/app.js b/deploy/app.js index 32dc48b..dcd29c1 100644 --- a/deploy/app.js +++ b/deploy/app.js @@ -405,32 +405,7 @@ async function loadGroups() { '
' + docsHtml + '
' + '
Загрузите недостающие базовые договоры для этих номеров.
'; } else { - card.innerHTML = '
📄 Договор №' + escHtml(g.contract_number || '?') + ' — ' + escHtml(g.counterparty || 'контрагент не определён') + '
' + - '
' + - g.documents.map(function(d) { - var typeLabel = {contract: 'договор', supplement: 'допсоглашение', specification: 'спецификация'}[d.doc_type] || d.doc_type; - return '
' + - '' + escHtml(typeLabel || '?') + ' ' + - escHtml(d.filename) + - (d.doc_date ? ' ' + escHtml(d.doc_date) + '' : '') + - '
'; - }).join('') + '
' + - '' + - ''; - // Клик на заголовок → свернуть/развернуть результаты - card.querySelector('.cmp-header').addEventListener('click', function() { - var body = document.getElementById('cmpBody_' + gi); - var arrow = document.getElementById('cmpArrow_' + gi); - if (body) { - if (body.style.display === 'none') { - body.style.display = 'block'; - if (arrow) arrow.textContent = '▾'; - } else { - body.style.display = 'none'; - if (arrow) arrow.textContent = '▸'; - } - } - }); + buildGroupCard(g, gi, card); } diffBody.appendChild(card); }); @@ -444,6 +419,59 @@ async function loadGroups() { lucide.createIcons(); } +// ── Карточка необработанной группы ────────────────────────── +function buildGroupCard(g, gi, card) { + card.innerHTML = '
' + + '📄 Договор №' + escHtml(g.contract_number || '?') + ' — ' + escHtml(g.counterparty || 'контрагент не определён') + + '
' + + '
' + + g.documents.map(function(d) { + var typeLabel = {contract: 'договор', supplement: 'допсоглашение', specification: 'спецификация'}[d.doc_type] || d.doc_type; + return '
' + + '' + escHtml(typeLabel || '?') + ' ' + + escHtml(d.filename) + + (d.doc_date ? ' ' + escHtml(d.doc_date) + '' : '') + + '
'; + }).join('') + '
' + + '' + + ''; +} + +// ── Заменить карточку на обработанную ─────────────────────── +function markGroupDone(gi, time) { + var card = document.querySelector('.cmp-body[id="cmpBody_' + gi + '"]').parentNode; + var g = window._groupsData[gi]; + card.innerHTML = '
' + + '' + + '📄 Договор №' + escHtml(g.contract_number || '?') + ' — ' + escHtml(g.counterparty || 'контрагент не определён') + + ' ✓ Готово (' + time + ')' + + '
' + + '
' + + g.documents.map(function(d) { + var typeLabel = {contract: 'договор', supplement: 'допсоглашение', specification: 'спецификация'}[d.doc_type] || d.doc_type; + return '
' + + '' + escHtml(typeLabel || '?') + ' ' + + escHtml(d.filename) + + (d.doc_date ? ' ' + escHtml(d.doc_date) + '' : '') + + '
'; + }).join('') + '
' + + '
'; + // Клик на заголовок → свернуть/развернуть + card.querySelector('.cmp-header').addEventListener('click', function() { + var body = document.getElementById('cmpBody_' + gi); + var arrow = document.getElementById('cmpArrow_' + gi); + if (body) { + if (body.style.display === 'none') { + body.style.display = 'block'; + if (arrow) arrow.textContent = '▾'; + } else { + body.style.display = 'none'; + if (arrow) arrow.textContent = '▸'; + } + } + }); +} + // Текущий активный EventSource (только один одновременно) var _activeCompareES = null; var _activeCompareTimer = null; @@ -459,22 +487,6 @@ window.runCompareForGroup = async function(gi, btn) { // Свернуть ТОЛЬКО тело текущей группы var curBody = document.getElementById('cmpBody_' + gi); if (curBody) curBody.style.display = 'none'; - var curArrow = document.getElementById('cmpArrow_' + gi); - if (curArrow) curArrow.textContent = '▸'; - // Заменить span «✓ Готово» обратно на кнопку ТОЛЬКО для текущей группы - var doneSpan = document.querySelector('.cmp-done[data-gi="' + gi + '"]'); - if (doneSpan) { - var newBtn = document.createElement('button'); - newBtn.className = 'btn btn-primary cmp-btn'; - newBtn.setAttribute('data-gi', gi); - newBtn.textContent = '▶ Сравнить эту группу'; - newBtn.style.cssText = 'margin-top:6px;font-size:12px;height:28px;'; - newBtn.addEventListener('click', function() { - var g = parseInt(this.getAttribute('data-gi')); - runCompareForGroup(g, this); - }); - doneSpan.parentNode.replaceChild(newBtn, doneSpan); - } btn.disabled = true; btn.innerHTML = ' Применяю...'; @@ -557,18 +569,10 @@ window.runCompareForGroup = async function(gi, btn) { es.close(); _activeCompareES = null; statusEl.textContent = '✓ ' + d.total_time_s + 'с'; statusEl.style.color = 'var(--green)'; - // Заменить кнопку на неактивный span — нельзя перезапустить - var span = document.createElement('span'); - span.className = 'cmp-done'; - span.setAttribute('data-gi', gi); - span.textContent = '✓ Готово (' + d.total_time_s + 'с)'; - span.style.cssText = 'display:inline-block;margin-top:6px;font-size:12px;height:28px;line-height:28px;padding:0 12px;background:var(--green);color:#fff;border-radius:6px;'; - btn.parentNode.replaceChild(span, btn); + // Заменить карточку на обработанную (другая вёрстка, нет кнопок) + markGroupDone(gi, d.total_time_s + 'с'); // Разблокировать остальные кнопки document.querySelectorAll('.cmp-btn').forEach(function(b) { b.disabled = false; }); - // Показать стрелку раскрытия - var arrow = document.getElementById('cmpArrow_' + gi); - if (arrow) arrow.textContent = '▾'; stepDone('stepCompare'); } else if (d.type === 'error') {