Tasks page implementation (#120)
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
||||
function RunningTaskSkeleton() {
|
||||
// 4 cards with skeletons for each part
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<Skeleton className="h-4 w-48" />
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
<Skeleton className="h-6 w-24" />
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<Skeleton className="h-4 w-48" />
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
<Skeleton className="h-6 w-24" />
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<Skeleton className="h-4 w-48" />
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
<Skeleton className="h-6 w-24" />
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>
|
||||
<Skeleton className="h-4 w-48" />
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
<Skeleton className="h-6 w-24" />
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export { RunningTaskSkeleton };
|
||||
81
skyvern-frontend/src/routes/tasks/running/RunningTasks.tsx
Normal file
81
skyvern-frontend/src/routes/tasks/running/RunningTasks.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import { client } from "@/api/AxiosClient";
|
||||
import { Status, TaskApiResponse } from "@/api/types";
|
||||
import { keepPreviousData, useQuery } from "@tanstack/react-query";
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { PAGE_SIZE } from "../constants";
|
||||
import { RunningTaskSkeleton } from "./RunningTaskSkeleton";
|
||||
import { basicTimeFormat } from "@/util/timeFormat";
|
||||
|
||||
function RunningTasks() {
|
||||
const navigate = useNavigate();
|
||||
const [searchParams] = useSearchParams();
|
||||
const page = searchParams.get("page") ? Number(searchParams.get("page")) : 1;
|
||||
|
||||
const {
|
||||
data: tasks,
|
||||
isPending,
|
||||
isError,
|
||||
error,
|
||||
} = useQuery<Array<TaskApiResponse>>({
|
||||
queryKey: ["tasks", page],
|
||||
queryFn: async () => {
|
||||
return client
|
||||
.get("/tasks", {
|
||||
params: {
|
||||
page,
|
||||
page_size: PAGE_SIZE,
|
||||
},
|
||||
})
|
||||
.then((response) => response.data);
|
||||
},
|
||||
refetchInterval: 3000,
|
||||
placeholderData: keepPreviousData,
|
||||
});
|
||||
|
||||
if (isPending) {
|
||||
return <RunningTaskSkeleton />;
|
||||
}
|
||||
|
||||
if (isError) {
|
||||
return <div>Error: {error?.message}</div>;
|
||||
}
|
||||
|
||||
if (!tasks) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const runningTasks = tasks.filter((task) => task.status === Status.Running);
|
||||
|
||||
if (runningTasks.length === 0) {
|
||||
return <div>No running tasks</div>;
|
||||
}
|
||||
|
||||
return runningTasks.map((task) => {
|
||||
return (
|
||||
<Card
|
||||
key={task.task_id}
|
||||
className="hover:bg-primary-foreground cursor-pointer"
|
||||
onClick={() => {
|
||||
navigate(`/tasks/${task.task_id}`);
|
||||
}}
|
||||
>
|
||||
<CardHeader>
|
||||
<CardTitle>{task.request.url}</CardTitle>
|
||||
<CardDescription></CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>Goal: {task.request.navigation_goal}</CardContent>
|
||||
<CardFooter>Created: {basicTimeFormat(task.created_at)}</CardFooter>
|
||||
</Card>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export { RunningTasks };
|
||||
Reference in New Issue
Block a user