// DOM Elements const uploadZone = document.getElementById('uploadZone'); const fileInput = document.getElementById('fileInput'); const fileList = document.getElementById('fileList'); const startBtn = document.getElementById('startBtn'); const requirementInput = document.getElementById('requirementInput'); const statusDot = document.getElementById('statusDot'); const statusText = document.getElementById('statusText'); const logOutput = document.getElementById('logOutput'); const reportContainer = document.getElementById('reportContainer'); const downloadScriptBtn = document.getElementById('downloadScriptBtn'); let isRunning = false; let pollingInterval = null; let currentSessionId = null; // --- Upload Logic --- if (uploadZone) { uploadZone.addEventListener('dragover', (e) => { e.preventDefault(); uploadZone.classList.add('dragover'); }); uploadZone.addEventListener('dragleave', () => uploadZone.classList.remove('dragover')); uploadZone.addEventListener('drop', (e) => { e.preventDefault(); uploadZone.classList.remove('dragover'); handleFiles(e.dataTransfer.files); }); uploadZone.addEventListener('click', () => fileInput.click()); } if (fileInput) { fileInput.addEventListener('change', (e) => handleFiles(e.target.files)); fileInput.addEventListener('click', (e) => e.stopPropagation()); // Prevent bubbling to uploadZone } async function handleFiles(files) { if (files.length === 0) return; fileList.innerHTML = ''; const formData = new FormData(); for (const file of files) { formData.append('files', file); const fileItem = document.createElement('div'); fileItem.className = 'file-item'; fileItem.innerHTML = ` ${file.name}`; fileList.appendChild(fileItem); } try { const res = await fetch('/api/upload', { method: 'POST', body: formData }); if (res.ok) { console.log('Upload success'); } else { alert('Upload failed'); } } catch (e) { console.error(e); alert('Upload failed'); } } // --- Analysis Logic --- if (startBtn) { startBtn.addEventListener('click', startAnalysis); } async function startAnalysis() { if (isRunning) return; const requirement = requirementInput.value.trim(); if (!requirement) { alert('Please enter analysis requirement'); return; } setRunningState(true); try { const res = await fetch('/api/start', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ requirement }) }); if (res.ok) { const data = await res.json(); currentSessionId = data.session_id; console.log("Started Session:", currentSessionId); startPolling(); switchTab('logs'); } else { const err = await res.json(); alert('Failed to start: ' + err.detail); setRunningState(false); } } catch (e) { console.error(e); alert('Error starting analysis'); setRunningState(false); } } function setRunningState(running) { isRunning = running; startBtn.disabled = running; if (running) { startBtn.innerHTML = ' Analysis in Progress...'; statusDot.className = 'status-dot running'; statusText.innerText = 'Analyzing'; statusText.style.color = 'var(--primary-color)'; // Hide follow-up and download during run const followUpSection = document.getElementById('followUpSection'); if (followUpSection) followUpSection.classList.add('hidden'); if (downloadScriptBtn) downloadScriptBtn.classList.add('hidden'); } else { startBtn.innerHTML = ' Start Analysis'; statusDot.className = 'status-dot'; statusText.innerText = 'Completed'; statusText.style.color = 'var(--text-secondary)'; const followUpSection = document.getElementById('followUpSection'); if (currentSessionId && followUpSection) { followUpSection.classList.remove('hidden'); } } } function startPolling() { if (pollingInterval) clearInterval(pollingInterval); if (!currentSessionId) return; pollingInterval = setInterval(async () => { try { const res = await fetch(`/api/status?session_id=${currentSessionId}`); if (!res.ok) return; const data = await res.json(); // Update Logs logOutput.innerText = data.log || "Waiting for output..."; // Auto scroll const logTab = document.getElementById('logsTab'); if (logTab) logTab.scrollTop = logTab.scrollHeight; if (!data.is_running && isRunning) { // Finished setRunningState(false); clearInterval(pollingInterval); if (data.has_report) { await loadReport(); // 强制跳转到 Report Tab switchTab('report'); console.log("Analysis done, switched to report tab"); } // Check for script if (data.script_path) { if (downloadScriptBtn) { downloadScriptBtn.classList.remove('hidden'); downloadScriptBtn.style.display = 'inline-flex'; } } } } catch (e) { console.error('Polling error', e); } }, 2000); } // --- Report Logic --- async function loadReport() { if (!currentSessionId) return; try { const res = await fetch(`/api/report?session_id=${currentSessionId}`); const data = await res.json(); if (!data.content || data.content === "Report not ready.") { reportContainer.innerHTML = '
Analysis in progress or no report generated yet.
Failed to load report.
'; } } // --- Gallery Logic --- let galleryImages = []; let currentImageIndex = 0; async function loadGallery() { if (!currentSessionId) return; try { const res = await fetch(`/api/figures?session_id=${currentSessionId}`); const data = await res.json(); galleryImages = data.figures || []; currentImageIndex = 0; renderGalleryImage(); } catch (e) { console.error("Gallery load failed", e); document.getElementById('carouselSlide').innerHTML = 'Failed to load images.
'; } } function renderGalleryImage() { const slide = document.getElementById('carouselSlide'); const info = document.getElementById('imageInfo'); if (galleryImages.length === 0) { slide.innerHTML = 'No images generated in this session.
'; info.innerHTML = ''; return; } const img = galleryImages[currentImageIndex]; // Image slide.innerHTML = `