Enhance analyze page with progress display and auto-redirect

- Remove 'Progress shown below' from job submission success message
- Add progress bar display in analyze page sidebar (same as jobs page)
- Add spinner animation for processing jobs
- Auto-redirect to results page when job completes (2 second delay)
- Update JavaScript to fetch and display real-time progress updates
- Add CSS styles for progress bar and spinner animations
parent ea5592e0
......@@ -5,7 +5,7 @@
{% block head %}
<script>
// Set job ID from template
var currentJobId = {% if submitted_job %}{{ submitted_job.id }}{% else %}null{% endif %};
var currentJobId = "{{ submitted_job.id if submitted_job else 'null' }}";
</script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
......@@ -43,6 +43,10 @@
.alert-error { background: #fee2e2; color: #dc2626; border: 1px solid #fecaca; }
.alert-success { background: #d1fae5; color: #065f46; border: 1px solid #a7f3d0; }
/* Spinner animation for processing jobs */
.spinner { display: inline-block; width: 12px; height: 12px; border: 2px solid #f3f3f3; border-top: 2px solid #667eea; border-radius: 50%; animation: spin 1s linear infinite; margin-right: 0.5rem; }
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
/* File Browser Modal */
.modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); }
.modal-content { background-color: white; margin: 5% auto; padding: 0; width: 80%; max-width: 800px; border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
......@@ -71,6 +75,7 @@
if (currentJobId) {
html += '<h3>Job Progress</h3>';
html += '<div id="job-status">Loading job status...</div>';
html += '<div id="job-progress" style="margin-top: 1rem;"></div>';
html += '<hr>';
}
......@@ -147,8 +152,14 @@
let resultText = typeof data.result === 'string' ? data.result : JSON.stringify(data.result);
statusHtml += `<p><strong>Result:</strong> ${resultText.substring(0, 200)}${resultText.length > 200 ? '...' : ''}</p>`;
}
// Auto-redirect to results page after 2 seconds
setTimeout(() => {
window.location.href = `/job_result/${currentJobId}`;
}, 2000);
} else if (data.status === 'processing') {
statusHtml += '<p style="color: blue;">⟳ Job is being processed...</p>';
statusHtml += '<p style="color: blue;"><div class="spinner"></div>Job is being processed...</p>';
// Update progress for processing jobs
updateJobProgress();
} else if (data.status === 'queued') {
statusHtml += '<p style="color: orange;">⏳ Job is queued for processing...</p>';
} else if (data.status === 'failed') {
......@@ -166,6 +177,72 @@
console.error('Error updating job status:', e);
});
}
function updateJobProgress() {
if (!currentJobId) return;
fetch(`/api/job_progress/${currentJobId}`)
.then(response => response.json())
.then(progressData => {
if (progressData && progressData.progress !== undefined) {
updateJobProgressDisplay(currentJobId, progressData);
} else if (progressData && progressData.status === 'no_progress') {
// No progress available yet, ensure it shows "Processing..."
const progressElement = document.getElementById('job-progress');
if (progressElement && progressElement.textContent === '') {
progressElement.textContent = 'Processing...';
}
}
})
.catch(error => {
console.log(`Error getting progress for job ${currentJobId}:`, error);
// On error, ensure it shows "Processing..."
const progressElement = document.getElementById('job-progress');
if (progressElement && progressElement.textContent === '') {
progressElement.textContent = 'Processing...';
}
});
}
function updateJobProgressDisplay(jobId, progressData) {
const progressElement = document.getElementById('job-progress');
if (progressElement) {
const progressPercent = progressData.progress || 0;
const stage = progressData.stage || 'processing';
const message = progressData.message || '';
// Create progress bar
const progressBar = document.createElement('div');
progressBar.style.width = '100%';
progressBar.style.height = '8px';
progressBar.style.backgroundColor = '#e5e7eb';
progressBar.style.borderRadius = '4px';
progressBar.style.overflow = 'hidden';
progressBar.style.marginBottom = '4px';
const progressFill = document.createElement('div');
progressFill.style.width = `${progressPercent}%`;
progressFill.style.height = '100%';
progressFill.style.backgroundColor = '#3b82f6';
progressFill.style.transition = 'width 0.3s ease';
progressBar.appendChild(progressFill);
// Update progress text
const progressText = document.createElement('div');
progressText.style.fontSize = '0.75rem';
progressText.style.color = '#6b7280';
progressText.style.wordWrap = 'break-word';
progressText.style.overflowWrap = 'break-word';
progressText.style.whiteSpace = 'normal';
progressText.style.lineHeight = '1.2';
progressText.textContent = `${progressPercent}% - ${stage}: ${message}`;
progressElement.innerHTML = '';
progressElement.appendChild(progressBar);
progressElement.appendChild(progressText);
}
}
setInterval(updateStats, 5000);
window.onload = updateStats;
......
......@@ -340,7 +340,7 @@ def analyze():
from .database import update_user_tokens
update_user_tokens(user['id'], -10) # Analysis costs 10 tokens
flash('Analysis job submitted successfully! Progress shown below.', 'success')
flash('Analysis job submitted successfully!', 'success')
return render_template('analyze.html',
user=user,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment