v1.0.176: раскрывающиеся результаты классификации прямо в таблице
This commit is contained in:
+57
-4
@@ -56,22 +56,75 @@ function resetStepper(fromId) {
|
|||||||
|
|
||||||
function renderTable() {
|
function renderTable() {
|
||||||
if (fileQueue.length === 0) {
|
if (fileQueue.length === 0) {
|
||||||
fileTable.innerHTML = '<tr class="empty-row"><td colspan="6">Нет файлов — выберите .docx / .pdf</td></tr>';
|
fileTable.innerHTML = '<tr class="empty-row"><td colspan="7">Нет файлов — выберите .docx / .pdf</td></tr>';
|
||||||
} else {
|
} else {
|
||||||
fileTable.innerHTML = fileQueue.map(function(f, i) {
|
fileTable.innerHTML = fileQueue.map(function(f, i) {
|
||||||
return '<tr id="row_' + i + '">' +
|
var rows = '<tr id="row_' + i + '">' +
|
||||||
'<td class="name-cell">' + escHtml(f.name) + '</td>' +
|
'<td class="name-cell" style="cursor:pointer;" onclick="toggleClassifyDetail(' + i + ')">' +
|
||||||
|
(f.doc_id ? '<span id="expand_' + i + '" style="font-size:10px;margin-right:4px;">▸</span>' : '') +
|
||||||
|
escHtml(f.name) + '</td>' +
|
||||||
'<td style="font-size:12px;color:var(--muted);">' + formatDate(f.lastModified) + '</td>' +
|
'<td style="font-size:12px;color:var(--muted);">' + formatDate(f.lastModified) + '</td>' +
|
||||||
'<td class="num-cell" style="font-size:12px;color:var(--muted);">' + formatSize(f.size) + '</td>' +
|
'<td class="num-cell" style="font-size:12px;color:var(--muted);">' + formatSize(f.size) + '</td>' +
|
||||||
'<td class="status-cell">' + (f.status || '') + '</td>' +
|
'<td class="status-cell">' + (f.status || '') + '</td>' +
|
||||||
'<td><button class="info-btn' + (f.doc_id ? ' visible' : '') + '" onclick="showText(' + i + ')" title="Текст / Распарсено"><i data-lucide="file-text" style="width:16px;height:16px;"></i></button></td>' +
|
'<td><button class="info-btn' + (f.doc_id ? ' visible' : '') + '" onclick="showText(' + i + ')" title="Текст / Распарсено"><i data-lucide="file-text" style="width:16px;height:16px;"></i></button></td>' +
|
||||||
'<td><button class="remove-btn" onclick="removeFile(' + i + ')" title="Удалить"><i data-lucide="trash-2" style="width:16px;height:16px;"></i></button></td>' +
|
'<td><button class="remove-btn" onclick="removeFile(' + i + ')" title="Удалить"><i data-lucide="trash-2" style="width:16px;height:16px;"></i></button></td>' +
|
||||||
'</tr>';
|
'</tr>' +
|
||||||
|
'<tr id="detail_' + i + '" style="display:none;"><td colspan="7" style="padding:4px 12px;font-size:11px;background:var(--brand-grey-light);"><span style="color:var(--muted);">Загрузка...</span></td></tr>';
|
||||||
|
return rows;
|
||||||
}).join('');
|
}).join('');
|
||||||
}
|
}
|
||||||
lucide.createIcons();
|
lucide.createIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Раскрыть/скрыть результат классификации под строкой файла ──
|
||||||
|
window.toggleClassifyDetail = async function(i) {
|
||||||
|
var detailRow = document.getElementById('detail_' + i);
|
||||||
|
var expandIcon = document.getElementById('expand_' + i);
|
||||||
|
if (!detailRow) return;
|
||||||
|
|
||||||
|
if (detailRow.style.display !== 'none') {
|
||||||
|
detailRow.style.display = 'none';
|
||||||
|
if (expandIcon) expandIcon.textContent = '▸';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var f = fileQueue[i];
|
||||||
|
if (!f || !f.doc_id) return;
|
||||||
|
|
||||||
|
detailRow.style.display = '';
|
||||||
|
if (expandIcon) expandIcon.textContent = '▾';
|
||||||
|
|
||||||
|
try {
|
||||||
|
var resp = await fetch(VM_API + '/api/documents/' + f.doc_id);
|
||||||
|
var qData = await resp.json();
|
||||||
|
if (!qData.ok) { detailRow.cells[0].innerHTML = '<span style="color:var(--destructive);">Ошибка загрузки</span>'; return; }
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
if (qData.classify_status === 'classified') {
|
||||||
|
html += '<div style="font-weight:600;margin-bottom:4px;">🏷️ Результат классификации</div>';
|
||||||
|
html += '<div style="display:flex;gap:16px;flex-wrap:wrap;">';
|
||||||
|
if (qData.doc_type) html += '<span><b>Тип:</b> ' + escHtml(qData.doc_type) + '</span>';
|
||||||
|
if (qData.own_number) html += '<span><b>Номер:</b> ' + escHtml(qData.own_number) + '</span>';
|
||||||
|
if (qData.parent_number) html += '<span><b>Родительский:</b> ' + escHtml(qData.parent_number) + '</span>';
|
||||||
|
if (qData.doc_date) html += '<span><b>Дата:</b> ' + escHtml(qData.doc_date) + '</span>';
|
||||||
|
if (qData.counterparty) html += '<span><b>Контрагент:</b> ' + escHtml(qData.counterparty) + '</span>';
|
||||||
|
html += '</div>';
|
||||||
|
if (qData.classify_raw) {
|
||||||
|
html += '<details style="margin-top:4px;"><summary style="cursor:pointer;color:var(--brand-primary);">Сырой ответ LLM</summary>';
|
||||||
|
html += '<pre style="font-size:10px;max-height:150px;overflow:auto;background:#fff;padding:4px;border-radius:3px;margin-top:2px;">' + escHtml(qData.classify_raw) + '</pre>';
|
||||||
|
html += '</details>';
|
||||||
|
}
|
||||||
|
} else if (qData.classify_status === 'failed') {
|
||||||
|
html += '<span style="color:var(--destructive);">✗ Ошибка классификации: ' + escHtml(qData.error_message || '?') + '</span>';
|
||||||
|
} else {
|
||||||
|
html += '<span style="color:var(--muted);">Ещё не классифицирован</span>';
|
||||||
|
}
|
||||||
|
detailRow.cells[0].innerHTML = html;
|
||||||
|
} catch(e) {
|
||||||
|
detailRow.cells[0].innerHTML = '<span style="color:var(--destructive);">Ошибка: ' + escHtml(e.message) + '</span>';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// moveUp/moveDown/removeFile/openAbout/closeAbout — вынесены в app_utils.js
|
// moveUp/moveDown/removeFile/openAbout/closeAbout — вынесены в app_utils.js
|
||||||
|
|
||||||
// ── Автозагрузка при выборе файлов ──────────────────────────
|
// ── Автозагрузка при выборе файлов ──────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user