diff --git a/backend/endpoints/responses/__init__.py b/backend/endpoints/responses/__init__.py index 7b25841af..6aa0726c1 100644 --- a/backend/endpoints/responses/__init__.py +++ b/backend/endpoints/responses/__init__.py @@ -75,7 +75,8 @@ class TaskExecutionResponse(TypedDict): task_name: str task_id: str status: JobStatus - queued_at: str + created_at: str + enqueued_at: str | None class BaseTaskStatusResponse(TaskExecutionResponse): diff --git a/backend/endpoints/tasks.py b/backend/endpoints/tasks.py index d030a7f46..30211523c 100644 --- a/backend/endpoints/tasks.py +++ b/backend/endpoints/tasks.py @@ -121,15 +121,17 @@ def _build_task_status_response( task_type = job_meta.get("task_type") # Convert datetime objects to ISO format strings - queued_at = job.created_at.isoformat() if job.created_at else None + created_at = job.created_at.isoformat() if job.created_at else None started_at = job.started_at.isoformat() if job.started_at else None ended_at = job.ended_at.isoformat() if job.ended_at else None + enqueued_at = job.enqueued_at.isoformat() if job.enqueued_at else None common_data = { "task_name": task_name, "task_id": job.get_id(), "status": job.get_status(), - "queued_at": queued_at or "", + "created_at": created_at or "", + "enqueued_at": enqueued_at, "started_at": started_at, "ended_at": ended_at, } @@ -275,7 +277,10 @@ async def get_tasks_status(request: Request) -> list[TaskStatusResponse]: job = Job.fetch(job_id, connection=redis_client) all_tasks.append(_build_task_status_response(job)) - all_tasks.sort(key=lambda x: x["started_at"] or x["queued_at"], reverse=True) + all_tasks.sort( + key=lambda x: x["started_at"] or x["enqueued_at"] or x["created_at"], + reverse=True, + ) return all_tasks @@ -344,7 +349,8 @@ async def run_all_tasks(request: Request) -> list[TaskExecutionResponse]: task_name=task_name, task_id=job.get_id(), status=job.get_status() or JobStatus.QUEUED, - queued_at=datetime.now(timezone.utc).isoformat(), + created_at=datetime.now(timezone.utc).isoformat(), + enqueued_at=None, ) for (task_name, job) in jobs ] @@ -390,5 +396,6 @@ async def run_single_task(request: Request, task_name: str) -> TaskExecutionResp "task_name": task_instance.title, "task_id": job.get_id(), "status": job.get_status() or JobStatus.QUEUED, - "queued_at": datetime.now(timezone.utc).isoformat(), + "created_at": datetime.now(timezone.utc).isoformat(), + "enqueued_at": None, } diff --git a/backend/tests/endpoints/test_tasks.py b/backend/tests/endpoints/test_tasks.py index fa5809f0a..34e4cddb9 100644 --- a/backend/tests/endpoints/test_tasks.py +++ b/backend/tests/endpoints/test_tasks.py @@ -370,7 +370,8 @@ class TestRunSingleTask: assert data["task_name"] == "Test Task" assert data["task_id"] == "1" assert data["status"] == "queued" - assert "queued_at" in data + assert "created_at" in data + assert "enqueued_at" in data mock_queue.assert_called_once() diff --git a/frontend/src/__generated__/models/CleanupTaskStatusResponse.ts b/frontend/src/__generated__/models/CleanupTaskStatusResponse.ts index fca0a4ffd..3046cb682 100644 --- a/frontend/src/__generated__/models/CleanupTaskStatusResponse.ts +++ b/frontend/src/__generated__/models/CleanupTaskStatusResponse.ts @@ -8,7 +8,8 @@ export type CleanupTaskStatusResponse = { task_name: string; task_id: string; status: JobStatus; - queued_at: string; + created_at: string; + enqueued_at: (string | null); started_at: (string | null); ended_at: (string | null); task_type: string; diff --git a/frontend/src/__generated__/models/ConversionTaskStatusResponse.ts b/frontend/src/__generated__/models/ConversionTaskStatusResponse.ts index 25210fe54..296b2f76b 100644 --- a/frontend/src/__generated__/models/ConversionTaskStatusResponse.ts +++ b/frontend/src/__generated__/models/ConversionTaskStatusResponse.ts @@ -8,7 +8,8 @@ export type ConversionTaskStatusResponse = { task_name: string; task_id: string; status: JobStatus; - queued_at: string; + created_at: string; + enqueued_at: (string | null); started_at: (string | null); ended_at: (string | null); task_type: string; diff --git a/frontend/src/__generated__/models/GenericTaskStatusResponse.ts b/frontend/src/__generated__/models/GenericTaskStatusResponse.ts index 5bd2d171c..50ace58d8 100644 --- a/frontend/src/__generated__/models/GenericTaskStatusResponse.ts +++ b/frontend/src/__generated__/models/GenericTaskStatusResponse.ts @@ -8,7 +8,8 @@ export type GenericTaskStatusResponse = { task_name: string; task_id: string; status: JobStatus; - queued_at: string; + created_at: string; + enqueued_at: (string | null); started_at: (string | null); ended_at: (string | null); task_type: string; diff --git a/frontend/src/__generated__/models/ScanTaskStatusResponse.ts b/frontend/src/__generated__/models/ScanTaskStatusResponse.ts index 83525529f..82fe7a045 100644 --- a/frontend/src/__generated__/models/ScanTaskStatusResponse.ts +++ b/frontend/src/__generated__/models/ScanTaskStatusResponse.ts @@ -8,7 +8,8 @@ export type ScanTaskStatusResponse = { task_name: string; task_id: string; status: JobStatus; - queued_at: string; + created_at: string; + enqueued_at: (string | null); started_at: (string | null); ended_at: (string | null); task_type: string; diff --git a/frontend/src/__generated__/models/TaskExecutionResponse.ts b/frontend/src/__generated__/models/TaskExecutionResponse.ts index 5a77514be..2008475dd 100644 --- a/frontend/src/__generated__/models/TaskExecutionResponse.ts +++ b/frontend/src/__generated__/models/TaskExecutionResponse.ts @@ -7,6 +7,7 @@ export type TaskExecutionResponse = { task_name: string; task_id: string; status: JobStatus; - queued_at: string; + created_at: string; + enqueued_at: (string | null); }; diff --git a/frontend/src/__generated__/models/UpdateTaskStatusResponse.ts b/frontend/src/__generated__/models/UpdateTaskStatusResponse.ts index 20866a606..1bebb3948 100644 --- a/frontend/src/__generated__/models/UpdateTaskStatusResponse.ts +++ b/frontend/src/__generated__/models/UpdateTaskStatusResponse.ts @@ -8,7 +8,8 @@ export type UpdateTaskStatusResponse = { task_name: string; task_id: string; status: JobStatus; - queued_at: string; + created_at: string; + enqueued_at: (string | null); started_at: (string | null); ended_at: (string | null); task_type: string; diff --git a/frontend/src/__generated__/models/WatcherTaskStatusResponse.ts b/frontend/src/__generated__/models/WatcherTaskStatusResponse.ts index 9fbe60d47..704e1151a 100644 --- a/frontend/src/__generated__/models/WatcherTaskStatusResponse.ts +++ b/frontend/src/__generated__/models/WatcherTaskStatusResponse.ts @@ -8,7 +8,8 @@ export type WatcherTaskStatusResponse = { task_name: string; task_id: string; status: JobStatus; - queued_at: string; + created_at: string; + enqueued_at: (string | null); started_at: (string | null); ended_at: (string | null); task_type: string; diff --git a/frontend/src/components/Settings/Administration/RunningTaskItem.vue b/frontend/src/components/Settings/Administration/RunningTaskItem.vue index 1907312e6..d92787fd6 100644 --- a/frontend/src/components/Settings/Administration/RunningTaskItem.vue +++ b/frontend/src/components/Settings/Administration/RunningTaskItem.vue @@ -20,17 +20,26 @@ const statusIconColor = computed(() => { const taskDuration = computed(() => { if (!props.task.started_at) return null; if (!props.task.ended_at && props.task.status === "failed") return null; + if ( + props.task.ended_at && + new Date(props.task.started_at) >= new Date(props.task.ended_at) + ) { + return null; + } const duration = intervalToDuration({ start: new Date(props.task.started_at), end: props.task.ended_at ? new Date(props.task.ended_at) : new Date(), }); + return formatDuration(duration); }); const taskDistanceFromNow = computed(() => { return formatDistanceToNow( - new Date(props.task.started_at || props.task.queued_at), + new Date( + props.task.started_at || props.task.enqueued_at || props.task.created_at, + ), { addSuffix: true }, ); }); @@ -71,7 +80,11 @@ const taskDistanceFromNow = computed(() => { size="small" variant="tonal" class="text-caption" - :title="formatTimestamp(task.started_at || task.queued_at)" + :title=" + formatTimestamp( + task.started_at || task.enqueued_at || task.created_at, + ) + " > {{ taskDistanceFromNow }}