Merge pull request #177 from multica-ai/forrestchang/task-queue-readability
fix(web): improve agent task queue readability
This commit is contained in:
commit
c2af66411d
1 changed files with 58 additions and 9 deletions
|
|
@ -66,6 +66,7 @@ import { api } from "@/shared/api";
|
|||
import { useAuthStore } from "@/features/auth";
|
||||
import { useWorkspaceStore } from "@/features/workspace";
|
||||
import { useRuntimeStore } from "@/features/runtimes";
|
||||
import { useIssueStore } from "@/features/issues";
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -977,6 +978,7 @@ function TriggersTab({
|
|||
function TasksTab({ agent }: { agent: Agent }) {
|
||||
const [tasks, setTasks] = useState<AgentTask[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const issues = useIssueStore((s) => s.issues);
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
|
|
@ -995,6 +997,21 @@ function TasksTab({ agent }: { agent: Agent }) {
|
|||
);
|
||||
}
|
||||
|
||||
// Sort: active tasks (running > dispatched > queued) first, then completed/failed by date
|
||||
const activeStatuses = ["running", "dispatched", "queued"];
|
||||
const sortedTasks = [...tasks].sort((a, b) => {
|
||||
const aActive = activeStatuses.indexOf(a.status);
|
||||
const bActive = activeStatuses.indexOf(b.status);
|
||||
const aIsActive = aActive !== -1;
|
||||
const bIsActive = bActive !== -1;
|
||||
if (aIsActive && !bIsActive) return -1;
|
||||
if (!aIsActive && bIsActive) return 1;
|
||||
if (aIsActive && bIsActive) return aActive - bActive;
|
||||
return new Date(b.created_at).getTime() - new Date(a.created_at).getTime();
|
||||
});
|
||||
|
||||
const issueMap = new Map(issues.map((i) => [i.id, i]));
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
|
|
@ -1013,22 +1030,54 @@ function TasksTab({ agent }: { agent: Agent }) {
|
|||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
{tasks.map((task) => {
|
||||
<div className="space-y-1.5">
|
||||
{sortedTasks.map((task) => {
|
||||
const config = taskStatusConfig[task.status] ?? taskStatusConfig.queued!;
|
||||
const Icon = config.icon;
|
||||
const issue = issueMap.get(task.issue_id);
|
||||
const isActive = task.status === "running" || task.status === "dispatched";
|
||||
const isRunning = task.status === "running";
|
||||
|
||||
return (
|
||||
<div key={task.id} className="flex items-center gap-3 rounded-lg border px-4 py-3">
|
||||
<Icon className={`h-4 w-4 shrink-0 ${config.color}`} />
|
||||
<div
|
||||
key={task.id}
|
||||
className={`flex items-center gap-3 rounded-lg border px-4 py-3 ${
|
||||
isRunning
|
||||
? "border-success/40 bg-success/5"
|
||||
: task.status === "dispatched"
|
||||
? "border-info/40 bg-info/5"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<Icon
|
||||
className={`h-4 w-4 shrink-0 ${config.color} ${
|
||||
isRunning ? "animate-spin" : ""
|
||||
}`}
|
||||
/>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="text-sm font-medium truncate">
|
||||
Issue {task.issue_id.slice(0, 8)}...
|
||||
<div className="flex items-center gap-2">
|
||||
{issue && (
|
||||
<span className="shrink-0 text-xs font-mono text-muted-foreground">
|
||||
{issue.identifier}
|
||||
</span>
|
||||
)}
|
||||
<span className={`text-sm truncate ${isActive ? "font-medium" : ""}`}>
|
||||
{issue?.title ?? `Issue ${task.issue_id.slice(0, 8)}...`}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{new Date(task.created_at).toLocaleString()}
|
||||
<div className="text-xs text-muted-foreground mt-0.5">
|
||||
{isRunning && task.started_at
|
||||
? `Started ${new Date(task.started_at).toLocaleString()}`
|
||||
: task.status === "dispatched" && task.dispatched_at
|
||||
? `Dispatched ${new Date(task.dispatched_at).toLocaleString()}`
|
||||
: task.status === "completed" && task.completed_at
|
||||
? `Completed ${new Date(task.completed_at).toLocaleString()}`
|
||||
: task.status === "failed" && task.completed_at
|
||||
? `Failed ${new Date(task.completed_at).toLocaleString()}`
|
||||
: `Queued ${new Date(task.created_at).toLocaleString()}`}
|
||||
</div>
|
||||
</div>
|
||||
<span className={`text-xs font-medium ${config.color}`}>
|
||||
<span className={`shrink-0 text-xs font-medium ${config.color}`}>
|
||||
{config.label}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue