From ed0bac7345e3af6fd06c18fa14062987a3bf6bbc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 16:12:44 +0000 Subject: [PATCH] feat(ui): add auto-refresh after upload and inline file preview - Auto-refresh files table after successful uploads using custom event - Add inline preview support for PDFs, images, and text files - Set Content-Disposition header to inline for preview endpoint - Add download button as secondary action in file details view Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- app/api/files.py | 2 +- frontend/static/js/upload.js | 6 ++++++ frontend/templates/file_detail.html | 24 ++++++++++++++++++++---- frontend/templates/files.html | 26 ++++++++------------------ 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/app/api/files.py b/app/api/files.py index de4fa541..ab1ba50a 100644 --- a/app/api/files.py +++ b/app/api/files.py @@ -568,7 +568,7 @@ def get_file_preview( return FileResponse( path=file_path, media_type=file_record.mime_type or "application/pdf", - filename=file_record.original_filename, + headers={"Content-Disposition": f'inline; filename="{file_record.original_filename}"'}, ) except HTTPException: diff --git a/frontend/static/js/upload.js b/frontend/static/js/upload.js index 48be819c..13786cf7 100644 --- a/frontend/static/js/upload.js +++ b/frontend/static/js/upload.js @@ -195,6 +195,12 @@ function updateOverallStatus(statusMessage) { if (completed === total) { statusMessage.textContent = `All uploads completed (${completed}/${total})`; + + // Trigger a custom event when all uploads are complete + const allUploadsComplete = new CustomEvent('allUploadsComplete', { + detail: { total: total, completed: completed } + }); + window.dispatchEvent(allUploadsComplete); } else { statusMessage.textContent = `Uploading files (${completed}/${total})`; } diff --git a/frontend/templates/file_detail.html b/frontend/templates/file_detail.html index 3996422f..93c05010 100644 --- a/frontend/templates/file_detail.html +++ b/frontend/templates/file_detail.html @@ -863,12 +863,24 @@

Original File

- + {% if file.mime_type and file.mime_type.startswith('image/') %} + + {{ file.original_filename }} + {% elif file.mime_type and file.mime_type.startswith('text/') %} + + + {% else %} + + + {% endif %}
-
+
Open in new tab + + Download +
{% endif %} @@ -877,12 +889,16 @@

Processed File

- + +
-
+
Open in new tab + + Download +
{% endif %} diff --git a/frontend/templates/files.html b/frontend/templates/files.html index 0d780e16..e27e295b 100644 --- a/frontend/templates/files.html +++ b/frontend/templates/files.html @@ -835,27 +835,17 @@ // Process the dropped files processFiles(e.dataTransfer.files, uploadProgressContainer, uploadStatusMessage); - - // Optionally reload page after uploads complete (with a delay) - setTimeout(() => { - const fileStatuses = document.querySelectorAll('.file-status'); - let allCompleted = true; - fileStatuses.forEach(status => { - if (!status.textContent.includes('Success') && !status.textContent.includes('Error')) { - allCompleted = false; - } - }); - - if (allCompleted && fileStatuses.length > 0) { - // Refresh the page after a short delay to show the new files - setTimeout(() => { - window.location.reload(); - }, 2000); - } - }, 1000); } }); + // Listen for upload completion event and reload the page to show new files + window.addEventListener('allUploadsComplete', (e) => { + // Wait 2 seconds to let users see the success message + setTimeout(() => { + window.location.reload(); + }, 2000); + }); + function closeUploadModal() { uploadModal.classList.remove('active'); }