diff --git a/web/main.py b/web/main.py
index 1e06eb3..5ecd6e0 100644
--- a/web/main.py
+++ b/web/main.py
@@ -356,6 +356,7 @@ def run_analysis_task(session_id: str, files: list, user_requirement: str, is_fo
class StartRequest(BaseModel):
requirement: str
template: Optional[str] = None
+ files: Optional[List[str]] = None
class ChatRequest(BaseModel):
session_id: str
@@ -383,10 +384,15 @@ async def upload_files(files: list[UploadFile] = File(...)):
async def start_analysis(request: StartRequest, background_tasks: BackgroundTasks):
session_id = session_manager.create_session()
- # Use only the most recently uploaded files, not everything in uploads/
- files = getattr(app.state, 'last_uploaded_files', None)
+ # Priority: request.files (from frontend) > last_uploaded > scan uploads/
+ files = None
+ if request.files:
+ files = [f for f in request.files if os.path.exists(f)]
+ if not files:
+ files = getattr(app.state, 'last_uploaded_files', None)
+ if files:
+ files = [f for f in files if os.path.exists(f)]
if not files:
- # Fallback: scan uploads directory
files = glob.glob("uploads/*.csv") + glob.glob("uploads/*.xlsx")
if not files:
raise HTTPException(status_code=400, detail="No data files found. Please upload files first.")
diff --git a/web/static/clean_style.css b/web/static/clean_style.css
index 6506574..58d5857 100644
--- a/web/static/clean_style.css
+++ b/web/static/clean_style.css
@@ -409,6 +409,18 @@ body {
border-radius: 0.25rem;
}
+.file-remove {
+ margin-left: auto;
+ cursor: pointer;
+ color: #9CA3AF;
+ font-size: 1.1rem;
+ line-height: 1;
+ padding: 0 0.25rem;
+}
+.file-remove:hover {
+ color: #EF4444;
+}
+
/* Tabs */
.tabs {
display: flex;
diff --git a/web/static/script.js b/web/static/script.js
index dde336a..0566962 100644
--- a/web/static/script.js
+++ b/web/static/script.js
@@ -64,29 +64,49 @@ if (fileInput) {
fileInput.addEventListener('click', (e) => e.stopPropagation());
}
+// Track all uploaded file paths for this session
+let uploadedFilePaths = [];
+
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) alert('Upload failed');
+ if (!res.ok) { alert('Upload failed'); return; }
+ const data = await res.json();
+ // Accumulate uploaded paths
+ if (data.paths) {
+ uploadedFilePaths = uploadedFilePaths.concat(data.paths);
+ }
+ renderFileList();
} catch (e) {
console.error(e);
alert('Upload failed');
}
}
+function renderFileList() {
+ fileList.innerHTML = '';
+ for (let i = 0; i < uploadedFilePaths.length; i++) {
+ const fname = uploadedFilePaths[i].split('/').pop().split('\\').pop();
+ const fileItem = document.createElement('div');
+ fileItem.className = 'file-item';
+ fileItem.innerHTML = ` ${fname}
+ ×`;
+ fileList.appendChild(fileItem);
+ }
+}
+
+window.removeUploadedFile = function(index) {
+ uploadedFilePaths.splice(index, 1);
+ renderFileList();
+}
+
// --- Template Logic ---
async function loadTemplates() {
try {
@@ -142,6 +162,9 @@ async function startAnalysis() {
if (selectedTemplate) {
body.template = selectedTemplate;
}
+ if (uploadedFilePaths.length > 0) {
+ body.files = uploadedFilePaths;
+ }
const res = await fetch('/api/start', {
method: 'POST',