diff --git a/deploy/app.js b/deploy/app.js index 726bbc3..1f22724 100644 --- a/deploy/app.js +++ b/deploy/app.js @@ -414,19 +414,40 @@ async function loadGroups() { escHtml(d.filename) + (d.doc_date ? ' ' + escHtml(d.doc_date) + '' : '') + ''; - }).join('') + ''; - card.innerHTML += ''; + }).join('') + '' + + '' + + ''; } diffBody.appendChild(card); }); + // Один обработчик на все кнопки сравнения + diffBody.querySelectorAll('.cmp-btn').forEach(function(btn) { + btn.addEventListener('click', function() { + var gi = parseInt(this.getAttribute('data-gi')); + runCompareForGroup(gi, this); + }); + }); lucide.createIcons(); } -window.runCompareForGroup = async function(gi) { +// Текущий активный EventSource (только один одновременно) +var _activeCompareES = null; +var _activeCompareTimer = null; + +window.runCompareForGroup = async function(gi, btn) { var group = window._groupsData[gi]; if (!group || group.contract_number === '__unresolved__') return; - var btn = event.target; + // Остановить предыдущее сравнение + if (_activeCompareES) { _activeCompareES.close(); _activeCompareES = null; } + if (_activeCompareTimer) { clearInterval(_activeCompareTimer); _activeCompareTimer = null; } + + // Свернуть все раскрытые сравнения + document.querySelectorAll('.cmp-body').forEach(function(el) { el.style.display = 'none'; }); + document.querySelectorAll('.cmp-btn').forEach(function(b) { + b.disabled = false; b.innerHTML = '▶ Сравнить эту группу'; + }); + btn.disabled = true; btn.innerHTML = ' Применяю...'; @@ -441,23 +462,26 @@ window.runCompareForGroup = async function(gi) { } var cid = ad.contract_ids[0]; + var cmpBody = document.getElementById('cmpBody_' + gi); + cmpBody.style.display = 'block'; + cmpBody.innerHTML = ''; btn.innerHTML = ' Сравнение...'; stepActive('stepCompare'); - var compareCard = document.getElementById('compareCard'); - var compareBody = document.getElementById('compareBody'); - var compareStatus = document.getElementById('compareStatus'); - compareCard.style.display = 'block'; - compareBody.innerHTML = ''; - compareStatus.textContent = '⏳ 0.0с'; + var statusEl = document.createElement('div'); + statusEl.style.cssText = 'font-size:11px;color:var(--muted);margin-bottom:4px;'; + statusEl.textContent = '⏳ 0.0с'; + cmpBody.appendChild(statusEl); var start = Date.now(); - var timer = setInterval(function() { - compareStatus.textContent = '⏳ ' + ((Date.now() - start) / 1000).toFixed(1) + 'с'; + _activeCompareTimer = setInterval(function() { + statusEl.textContent = '⏳ ' + ((Date.now() - start) / 1000).toFixed(1) + 'с'; }, 200); var es = new EventSource(VM_API + '/process-v2?contract_id=' + cid); + _activeCompareES = es; var sections = {}; + es.onmessage = function(e) { var d = JSON.parse(e.data); @@ -469,7 +493,7 @@ window.runCompareForGroup = async function(gi) { var body = sec.querySelector('.diff-section-body'); body.style.display = body.style.display === 'none' ? 'block' : 'none'; }); - compareBody.appendChild(sec); + cmpBody.appendChild(sec); sections[d.supplement_id] = sec; } else if (d.type === 'llm_done') { @@ -497,18 +521,30 @@ window.runCompareForGroup = async function(gi) { } } else if (d.type === 'done') { - clearInterval(timer); es.close(); - compareStatus.textContent = '✓ ' + d.total_time_s + 'с'; - btn.innerHTML = '✓ Готово'; btn.disabled = false; + clearInterval(_activeCompareTimer); _activeCompareTimer = null; + es.close(); _activeCompareES = null; + statusEl.textContent = '✓ ' + d.total_time_s + 'с'; + statusEl.style.color = 'var(--green)'; + btn.innerHTML = '✓ Готово (' + d.total_time_s + 'с)'; + btn.style.background = 'var(--green)'; + btn.style.color = '#fff'; + btn.style.borderColor = 'var(--green)'; + btn.style.cursor = 'default'; + btn.disabled = false; stepDone('stepCompare'); } else if (d.type === 'error') { - clearInterval(timer); es.close(); - compareBody.innerHTML += '
✗ ' + d.message + '
'; + clearInterval(_activeCompareTimer); _activeCompareTimer = null; + es.close(); _activeCompareES = null; + cmpBody.innerHTML += '
✗ ' + d.message + '
'; btn.innerHTML = '✗'; btn.disabled = false; } }; - es.onerror = function() { clearInterval(timer); es.close(); btn.innerHTML = '✗ соединение'; btn.disabled = false; }; + es.onerror = function() { + clearInterval(_activeCompareTimer); _activeCompareTimer = null; + es.close(); _activeCompareES = null; + btn.innerHTML = '✗ соединение'; btn.disabled = false; + }; }; function uploadFile(file, onProgress) {