diff --git a/site/static/files.js b/site/static/files.js index f30891c..b4a2fba 100644 --- a/site/static/files.js +++ b/site/static/files.js @@ -511,20 +511,44 @@ async function onFilesSelected(newFiles) { if (newFiles.length === 0) return; fileInput.disabled = true; - - // Сбросить прогресс пайплайна при добавлении новых файлов resetStepper('stepUpload'); - // Обработать каждый файл + // Фаза 1: ВСЕ строки в таблицу сразу for (var i = 0; i < newFiles.length; i++) { var f = newFiles[i]; if (f.name.toLowerCase().endsWith('.zip')) { await addZipFile(f); - } else { - await addRegularFile(f); + continue; } + state.files.push({ name: f.name, lastModified: f.lastModified, size: f.size, file: f, status: { kind: 'uploading', pct: 0 }, zip_source: null }); + state.files[state.files.length - 1]._pendingFile = f; + } + render(state); + + // Фаза 2: загрузка по одному с обновлением строки + for (var j = 0; j < state.files.length; j++) { + var entry = state.files[j]; + var pendingFile = entry._pendingFile; + if (!pendingFile) continue; + delete entry._pendingFile; + var f = pendingFile; + try { + var resp = await uploadFile(f, function(pct) { + entry.status = { kind: 'uploading', pct: pct }; + render(state); + }); + if (resp && resp.contract_id) state.contractId = resp.contract_id; + entry.doc_id = resp.doc_id; + entry.status = { kind: 'uploaded' }; + entry.uploaded = true; + var pr = resp.parsed; + var elapsed = pr && pr.status === 'parsed' ? '0.0' : null; + applyParseResult(entry, pr, elapsed); + } catch(err) { + entry.status = { kind: 'error', text: err.message }; + } + render(state); } - // Завершить цикл await finalizeUpload(); }