// Document upload and list management const DOC_UI = { async init() { $("#doc-upload").addEventListener("change", (e) => this.handleUpload(e)); // Periodically refresh document list setInterval(() => this.refreshList(), 30000); }, async handleUpload(e) { const file = e.target.files[0]; if (!file) return; const output = $("#research-output"); if (!output.querySelector(".empty-state")) output.innerHTML = ""; output.innerHTML = '
Reading file...'; const formData = new FormData(); formData.append("file", file); const res = await fetch("/api/documents/upload", { method: "POST", body: formData }); const data = await res.json(); if (res.ok) { showToast(`Document indexed: ${data.chunks || "unknown"} chunks`, "info"); STORE.documents = []; await this.refreshList(); // Select the new document if (data.doc_id) { STORE.currentDocId = data.doc_id; this.renderDocList(); $("#viewer-doc-name").textContent = file.name; } } else { output.innerHTML = `

Upload failed: ${data.detail || data.error || "unknown"}

`; } e.target.value = ""; }, async refreshList() { try { const res = await API.get("/api/documents"); STORE.documents = res.documents || []; this.renderDocList(); // Update stats const stats = $("#sidebar-stats"); const total = STORE.documents.length; const indexed = STORE.documents.filter(d => d.status === "indexed").length; stats.textContent = `${indexed}/${total} documents indexed`; } catch (e) { console.warn("Doc list refresh failed:", e); } }, async selectDoc(docId) { STORE.currentDocId = docId; this.renderDocList(); // Load into viewer if (STORE.viewerDoc) { DOC_VIEWER.loadDocument(docId); } // Switch to viewer tab $$(".tab").forEach(t => t.classList.remove("active")); $$(".tab-pane").forEach(p => p.classList.remove("active")); document.querySelector('[data-tab="viewer"]').classList.add("active"); $("#tab-viewer").classList.add("active"); }, renderDocList() { const list = $("#doc-list"); if (!list) return; if (!STORE.documents.length) { list.innerHTML = '
No documents
'; return; } list.innerHTML = STORE.documents.map(doc => { const ext = doc.filename.split(".").pop().toLowerCase(); const icons = { pdf: "📄", txt: "📝", md: "📋", doc: "📑" }; const icon = icons[ext] || "📄"; const isActive = doc.id === STORE.currentDocId; return `
${icon} ${doc.filename.length > 25 ? doc.filename.substring(0, 25) + '...' : doc.filename} ${doc.status.charAt(0).toUpperCase() + doc.status.slice(1)}
`; }).join(''); // Click handlers list.querySelectorAll(".doc-item").forEach(item => { item.addEventListener("click", (e) => { if (e.target.closest(".file-remove")) return; this.selectDoc(item.dataset.docId); }); }); }, };