Add Jobs page for active job management

- Create /jobs route showing queued, processing, and recently cancelled jobs
- Modify /history to exclude active jobs, show only completed/failed/old cancelled
- Add Jobs link to navbar between Analyze and History
- Jobs page has real-time status updates like history page
- Proper job filtering by status and time for each page
parent 5014c7f8
...@@ -90,6 +90,7 @@ ...@@ -90,6 +90,7 @@
<nav class="nav"> <nav class="nav">
<a href="/dashboard" {% if active_page == 'dashboard' %}class="active"{% endif %}>Dashboard</a> <a href="/dashboard" {% if active_page == 'dashboard' %}class="active"{% endif %}>Dashboard</a>
<a href="/analyze" {% if active_page == 'analyze' %}class="active"{% endif %}>Analyze</a> <a href="/analyze" {% if active_page == 'analyze' %}class="active"{% endif %}>Analyze</a>
<a href="/jobs" {% if active_page == 'jobs' %}class="active"{% endif %}>Jobs</a>
<a href="/history" {% if active_page == 'history' %}class="active"{% endif %}>History</a> <a href="/history" {% if active_page == 'history' %}class="active"{% endif %}>History</a>
<div class="docs-menu"> <div class="docs-menu">
<div class="docs-icon" onclick="toggleDocsMenu()">Documentations</div> <div class="docs-icon" onclick="toggleDocsMenu()">Documentations</div>
......
This diff is collapsed.
...@@ -315,17 +315,82 @@ def analyze(): ...@@ -315,17 +315,82 @@ def analyze():
@app.route('/jobs')
@login_required
def jobs():
"""Active jobs page - shows queued, processing, and recently cancelled jobs."""
user = get_current_user_session()
all_queue_items = get_user_queue_items(user['id'])
# Filter for active jobs: queued, processing, and cancelled jobs from last 24 hours
import time
current_time = time.time()
twenty_four_hours_ago = current_time - (24 * 60 * 60)
active_jobs = []
for job in all_queue_items:
# Include queued and processing jobs
if job['status'] in ['queued', 'processing']:
active_jobs.append(job)
# Include cancelled jobs from last 24 hours
elif job['status'] == 'cancelled':
job_time = job.get('created_at')
if isinstance(job_time, str):
from datetime import datetime
try:
job_timestamp = datetime.fromisoformat(job_time.replace('Z', '+00:00')).timestamp()
if job_timestamp > twenty_four_hours_ago:
active_jobs.append(job)
except:
# If we can't parse the timestamp, include it anyway
active_jobs.append(job)
else:
# If no timestamp, include it
active_jobs.append(job)
return render_template('jobs.html',
user=user,
tokens=get_user_tokens(user["id"]),
queue_items=active_jobs,
active_page='jobs')
@app.route('/history') @app.route('/history')
@login_required @login_required
def history(): def history():
"""Job history page.""" """Job history page - shows completed and failed jobs."""
user = get_current_user_session() user = get_current_user_session()
queue_items = get_user_queue_items(user['id']) all_queue_items = get_user_queue_items(user['id'])
# Filter for historical jobs: completed, failed, and cancelled jobs older than 24 hours
import time
current_time = time.time()
twenty_four_hours_ago = current_time - (24 * 60 * 60)
historical_jobs = []
for job in all_queue_items:
# Include completed and failed jobs
if job['status'] in ['completed', 'failed']:
historical_jobs.append(job)
# Include cancelled jobs older than 24 hours
elif job['status'] == 'cancelled':
job_time = job.get('created_at')
if isinstance(job_time, str):
from datetime import datetime
try:
job_timestamp = datetime.fromisoformat(job_time.replace('Z', '+00:00')).timestamp()
if job_timestamp <= twenty_four_hours_ago:
historical_jobs.append(job)
except:
# If we can't parse the timestamp, exclude it (better safe than sorry)
pass
# If no timestamp, exclude it
# Exclude queued and processing jobs from history
return render_template('history.html', return render_template('history.html',
user=user, user=user,
tokens=get_user_tokens(user["id"]), tokens=get_user_tokens(user["id"]),
queue_items=queue_items, queue_items=historical_jobs,
active_page='history') active_page='history')
......
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