commit
951ccc7d12
4 changed files with 40 additions and 0 deletions
|
|
@ -76,6 +76,22 @@ export function TaskNotificationMenu() {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formatDuration = (seconds?: number) => {
|
||||||
|
if (!seconds || seconds < 0) return null
|
||||||
|
|
||||||
|
if (seconds < 60) {
|
||||||
|
return `${Math.round(seconds)}s`
|
||||||
|
} else if (seconds < 3600) {
|
||||||
|
const mins = Math.floor(seconds / 60)
|
||||||
|
const secs = Math.round(seconds % 60)
|
||||||
|
return secs > 0 ? `${mins}m ${secs}s` : `${mins}m`
|
||||||
|
} else {
|
||||||
|
const hours = Math.floor(seconds / 3600)
|
||||||
|
const mins = Math.floor((seconds % 3600) / 60)
|
||||||
|
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const formatRelativeTime = (dateString: string) => {
|
const formatRelativeTime = (dateString: string) => {
|
||||||
// Handle different timestamp formats
|
// Handle different timestamp formats
|
||||||
let date: Date
|
let date: Date
|
||||||
|
|
@ -153,6 +169,11 @@ export function TaskNotificationMenu() {
|
||||||
</div>
|
</div>
|
||||||
<CardDescription className="text-xs">
|
<CardDescription className="text-xs">
|
||||||
Started {formatRelativeTime(task.created_at)}
|
Started {formatRelativeTime(task.created_at)}
|
||||||
|
{formatDuration(task.duration_seconds) && (
|
||||||
|
<span className="ml-2 text-muted-foreground">
|
||||||
|
• {formatDuration(task.duration_seconds)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
{formatTaskProgress(task) && (
|
{formatTaskProgress(task) && (
|
||||||
|
|
@ -256,6 +277,11 @@ export function TaskNotificationMenu() {
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-muted-foreground">
|
<div className="text-xs text-muted-foreground">
|
||||||
{formatRelativeTime(task.updated_at)}
|
{formatRelativeTime(task.updated_at)}
|
||||||
|
{formatDuration(task.duration_seconds) && (
|
||||||
|
<span className="ml-2">
|
||||||
|
• {formatDuration(task.duration_seconds)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* Show final results for completed tasks */}
|
{/* Show final results for completed tasks */}
|
||||||
{task.status === 'completed' && formatTaskProgress(task)?.detailed && (
|
{task.status === 'completed' && formatTaskProgress(task)?.detailed && (
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ export interface Task {
|
||||||
failed_files?: number
|
failed_files?: number
|
||||||
created_at: string
|
created_at: string
|
||||||
updated_at: string
|
updated_at: string
|
||||||
|
duration_seconds?: number
|
||||||
result?: Record<string, unknown>
|
result?: Record<string, unknown>
|
||||||
error?: string
|
error?: string
|
||||||
files?: Record<string, Record<string, unknown>>
|
files?: Record<string, Record<string, unknown>>
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,11 @@ class FileTask:
|
||||||
created_at: float = field(default_factory=time.time)
|
created_at: float = field(default_factory=time.time)
|
||||||
updated_at: float = field(default_factory=time.time)
|
updated_at: float = field(default_factory=time.time)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def duration_seconds(self) -> float:
|
||||||
|
"""Duration in seconds from creation to last update"""
|
||||||
|
return self.updated_at - self.created_at
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class UploadTask:
|
class UploadTask:
|
||||||
|
|
@ -33,3 +38,8 @@ class UploadTask:
|
||||||
status: TaskStatus = TaskStatus.PENDING
|
status: TaskStatus = TaskStatus.PENDING
|
||||||
created_at: float = field(default_factory=time.time)
|
created_at: float = field(default_factory=time.time)
|
||||||
updated_at: float = field(default_factory=time.time)
|
updated_at: float = field(default_factory=time.time)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def duration_seconds(self) -> float:
|
||||||
|
"""Duration in seconds from creation to last update"""
|
||||||
|
return self.updated_at - self.created_at
|
||||||
|
|
|
||||||
|
|
@ -224,6 +224,7 @@ class TaskService:
|
||||||
"retry_count": file_task.retry_count,
|
"retry_count": file_task.retry_count,
|
||||||
"created_at": file_task.created_at,
|
"created_at": file_task.created_at,
|
||||||
"updated_at": file_task.updated_at,
|
"updated_at": file_task.updated_at,
|
||||||
|
"duration_seconds": file_task.duration_seconds,
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -235,6 +236,7 @@ class TaskService:
|
||||||
"failed_files": upload_task.failed_files,
|
"failed_files": upload_task.failed_files,
|
||||||
"created_at": upload_task.created_at,
|
"created_at": upload_task.created_at,
|
||||||
"updated_at": upload_task.updated_at,
|
"updated_at": upload_task.updated_at,
|
||||||
|
"duration_seconds": upload_task.duration_seconds,
|
||||||
"files": file_statuses,
|
"files": file_statuses,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -262,6 +264,7 @@ class TaskService:
|
||||||
"failed_files": upload_task.failed_files,
|
"failed_files": upload_task.failed_files,
|
||||||
"created_at": upload_task.created_at,
|
"created_at": upload_task.created_at,
|
||||||
"updated_at": upload_task.updated_at,
|
"updated_at": upload_task.updated_at,
|
||||||
|
"duration_seconds": upload_task.duration_seconds,
|
||||||
}
|
}
|
||||||
|
|
||||||
# First, add user-owned tasks; then shared anonymous;
|
# First, add user-owned tasks; then shared anonymous;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue