Add collapsible for workflow run tasks table (#1219)
Co-authored-by: Muhammed Salih Altun <muhammedsalihaltun@gmail.com>
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
import { Status, TaskApiResponse } from "@/api/types";
|
||||
import { StatusBadge } from "@/components/StatusBadge";
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
} from "@/components/ui/collapsible";
|
||||
import { TableCell, TableRow } from "@/components/ui/table";
|
||||
import { basicLocalTimeFormat, basicTimeFormat } from "@/util/timeFormat";
|
||||
import { ChevronDownIcon, ChevronRightIcon } from "@radix-ui/react-icons";
|
||||
import { useState } from "react";
|
||||
import { cn } from "@/util/utils";
|
||||
import { CodeEditor } from "./components/CodeEditor";
|
||||
import { AutoResizingTextarea } from "@/components/AutoResizingTextarea/AutoResizingTextarea";
|
||||
|
||||
type Props = {
|
||||
task: TaskApiResponse;
|
||||
onNavigate: (event: React.MouseEvent, id: string) => void;
|
||||
};
|
||||
|
||||
function WorkflowBlockCollapsibleContent({ task, onNavigate }: Props) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState(0);
|
||||
|
||||
const showExtractedInformation = task?.status === Status.Completed;
|
||||
const extractedInformation = showExtractedInformation ? (
|
||||
<CodeEditor
|
||||
language="json"
|
||||
value={JSON.stringify(task.extracted_information, null, 2)}
|
||||
readOnly
|
||||
minHeight={"96px"}
|
||||
maxHeight={"500px"}
|
||||
className="w-full"
|
||||
/>
|
||||
) : null;
|
||||
|
||||
const showFailureReason =
|
||||
task?.status === Status.Failed ||
|
||||
task?.status === Status.Terminated ||
|
||||
task?.status === Status.TimedOut;
|
||||
const failureReason = showFailureReason ? (
|
||||
<CodeEditor
|
||||
language="json"
|
||||
value={JSON.stringify(task.failure_reason, null, 2)}
|
||||
readOnly
|
||||
minHeight={"96px"}
|
||||
maxHeight={"500px"}
|
||||
className="w-full"
|
||||
/>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<Collapsible key={task.task_id} asChild open={open} onOpenChange={setOpen}>
|
||||
<>
|
||||
<TableRow
|
||||
className={cn("hover:bg-slate-elevation2", {
|
||||
"border-b-0 bg-slate-elevation2": open,
|
||||
})}
|
||||
>
|
||||
<TableCell>
|
||||
<CollapsibleTrigger asChild>
|
||||
<div className="w-fit cursor-pointer rounded-full p-2 hover:bg-muted">
|
||||
{open ? (
|
||||
<ChevronDownIcon className="size-6" />
|
||||
) : (
|
||||
<ChevronRightIcon className="size-6" />
|
||||
)}
|
||||
</div>
|
||||
</CollapsibleTrigger>
|
||||
</TableCell>
|
||||
<TableCell className="w-1/4 cursor-pointer">
|
||||
{task.request.title}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className="w-1/4 cursor-pointer"
|
||||
onClick={(event) => {
|
||||
onNavigate(event, task.task_id);
|
||||
}}
|
||||
>
|
||||
{task.task_id}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className="w-1/4 max-w-64 cursor-pointer overflow-hidden overflow-ellipsis whitespace-nowrap"
|
||||
onClick={(event) => onNavigate(event, task.task_id)}
|
||||
>
|
||||
{task.request.url}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className="w-1/6 cursor-pointer"
|
||||
onClick={(event) => onNavigate(event, task.task_id)}
|
||||
>
|
||||
<StatusBadge status={task.status} />
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className="w-1/4 cursor-pointer whitespace-nowrap"
|
||||
onClick={(event) => onNavigate(event, task.task_id)}
|
||||
title={basicTimeFormat(task.created_at)}
|
||||
>
|
||||
{basicLocalTimeFormat(task.created_at)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<CollapsibleContent asChild>
|
||||
<TableRow className="bg-slate-elevation2 hover:bg-slate-elevation2">
|
||||
<TableCell colSpan={6} className="border-b">
|
||||
<div className="space-y-2 px-6">
|
||||
<div className="flex gap-1">
|
||||
<div
|
||||
className={cn(
|
||||
"cursor-pointer rounded-sm px-3 py-2 text-slate-400 hover:bg-slate-700",
|
||||
{
|
||||
"bg-slate-700 text-foreground": activeTab === 0,
|
||||
},
|
||||
)}
|
||||
onClick={() => {
|
||||
setActiveTab(0);
|
||||
}}
|
||||
>
|
||||
{showExtractedInformation
|
||||
? "Extracted Information"
|
||||
: showFailureReason
|
||||
? "Failure Reason"
|
||||
: ""}
|
||||
</div>
|
||||
<div
|
||||
className={cn(
|
||||
"cursor-pointer rounded-sm px-3 py-2 text-slate-400 hover:bg-slate-700 hover:text-foreground",
|
||||
{
|
||||
"bg-slate-700 text-foreground": activeTab === 1,
|
||||
},
|
||||
)}
|
||||
onClick={() => {
|
||||
setActiveTab(1);
|
||||
}}
|
||||
>
|
||||
Navigation Goal
|
||||
</div>
|
||||
<div
|
||||
className={cn(
|
||||
"cursor-pointer rounded-sm px-3 py-2 text-slate-400 hover:bg-slate-700 hover:text-foreground",
|
||||
{
|
||||
"bg-slate-700 text-foreground": activeTab === 2,
|
||||
},
|
||||
)}
|
||||
onClick={() => {
|
||||
setActiveTab(2);
|
||||
}}
|
||||
>
|
||||
Parameters
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{activeTab === 0 &&
|
||||
(showExtractedInformation
|
||||
? extractedInformation
|
||||
: showFailureReason
|
||||
? failureReason
|
||||
: null)}
|
||||
{activeTab === 1 && (
|
||||
<AutoResizingTextarea
|
||||
value={task.request.navigation_goal ?? ""}
|
||||
readOnly
|
||||
/>
|
||||
)}
|
||||
{activeTab === 2 && (
|
||||
<CodeEditor
|
||||
language="json"
|
||||
value={JSON.stringify(
|
||||
task.request.navigation_payload,
|
||||
null,
|
||||
2,
|
||||
)}
|
||||
minHeight={"96px"}
|
||||
maxHeight={"500px"}
|
||||
className="w-full"
|
||||
readOnly
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</CollapsibleContent>
|
||||
</>
|
||||
</Collapsible>
|
||||
);
|
||||
}
|
||||
|
||||
export { WorkflowBlockCollapsibleContent };
|
||||
Reference in New Issue
Block a user