feat: run log dialog
This commit is contained in:
parent
009589630d
commit
3e5ff7702e
@ -7,10 +7,12 @@ import { toast } from "sonner";
|
||||
|
||||
export function CopyButton({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: {
|
||||
text: string;
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<Button
|
||||
@ -21,7 +23,7 @@ export function CopyButton({
|
||||
}}
|
||||
className={cn(" p-2 min-h-0 aspect-square", className)}
|
||||
>
|
||||
<Copy size={14} />
|
||||
{children} <Copy size={14} />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export type LogsType = {
|
||||
machine_id?: string;
|
||||
@ -36,10 +37,24 @@ export function LogsViewer({ logs }: { logs: LogsType }) {
|
||||
}
|
||||
container.current = ref;
|
||||
}}
|
||||
className="flex flex-col text-xs p-2 overflow-y-scroll max-h-[400px] whitespace-break-spaces"
|
||||
className="flex flex-col text-xs p-2 overflow-y-scroll whitespace-break-spaces"
|
||||
>
|
||||
{logs.map((x, i) => (
|
||||
<div key={i}>{x.logs}</div>
|
||||
<div
|
||||
key={i}
|
||||
className="hover:bg-gray-100 flex flex-row items-center gap-2"
|
||||
onClick={() => {
|
||||
toast.success("Copied to clipboard");
|
||||
navigator.clipboard.writeText(x.logs);
|
||||
}}
|
||||
>
|
||||
<span className="min-w-fit">
|
||||
{new Date(x.timestamp).toLocaleString()}
|
||||
</span>
|
||||
<div className="h-full w-[1px] bg-stone-400 flex-shrink-0"></div>
|
||||
{/* Display timestamp */}
|
||||
<div>{x.logs}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
@ -3,8 +3,10 @@ import { RunOutputs } from "@/components/RunOutputs";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
@ -20,6 +22,8 @@ import { type findAllRuns } from "@/server/findAllRuns";
|
||||
import { Suspense } from "react";
|
||||
import { LiveStatus } from "./LiveStatus";
|
||||
import { LogsType, LogsViewer } from "@/components/LogsViewer";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Edit, ExternalLink } from "lucide-react";
|
||||
|
||||
export async function RunDisplay({
|
||||
run,
|
||||
@ -75,8 +79,7 @@ export async function RunDisplay({
|
||||
<div className="max-h-96 overflow-y-scroll">
|
||||
<RunInputs run={run} />
|
||||
<Suspense>
|
||||
<RunOutputs run_id={run.id} />
|
||||
{run.run_log && <LogsViewer logs={run.run_log} />}
|
||||
<RunOutputs run={run} />
|
||||
</Suspense>
|
||||
</div>
|
||||
{/* <div className="max-h-96 overflow-y-scroll">{view}</div> */}
|
||||
|
@ -1,3 +1,13 @@
|
||||
import {
|
||||
Dialog,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
import { OutputRender } from "./OutputRender";
|
||||
import { CodeBlock } from "@/components/CodeBlock";
|
||||
import {
|
||||
@ -8,10 +18,17 @@ import {
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import type { findAllRuns } from "@/server/findAllRuns";
|
||||
import { getRunsOutput } from "@/server/getRunsOutput";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
import { LogsViewer } from "@/components/LogsViewer";
|
||||
import { CopyButton } from "@/components/CopyButton";
|
||||
|
||||
export async function RunOutputs({ run_id }: { run_id: string }) {
|
||||
const outputs = await getRunsOutput(run_id);
|
||||
export async function RunOutputs({
|
||||
run,
|
||||
}: { run: Awaited<ReturnType<typeof findAllRuns>>[0] }) {
|
||||
const outputs = await getRunsOutput(run.id);
|
||||
return (
|
||||
<Table className="table-fixed">
|
||||
<TableHeader className="bg-background top-0 sticky">
|
||||
@ -21,6 +38,42 @@ export async function RunOutputs({ run_id }: { run_id: string }) {
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow key={run.id}>
|
||||
<TableCell className="break-words">Run log</TableCell>
|
||||
<TableCell>
|
||||
{run.run_log ? (
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="secondary" className="w-fit">
|
||||
View Log <ExternalLink size={14} />
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="sm:max-w-[1000px] h-full max-h-[600px] grid grid-rows-[auto,1fr,auto]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Run Log</DialogTitle>
|
||||
</DialogHeader>
|
||||
<LogsViewer logs={run.run_log} />
|
||||
<DialogFooter>
|
||||
<CopyButton
|
||||
className="w-fit aspect-auto p-4"
|
||||
text={JSON.stringify(run.run_log)}
|
||||
>
|
||||
Copy
|
||||
</CopyButton>
|
||||
<DialogClose>
|
||||
<Button type="button" variant="secondary">
|
||||
Close
|
||||
</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
) : (
|
||||
"No log available"
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
{outputs?.map((run) => {
|
||||
const fileName =
|
||||
run.data.images?.[0].filename ||
|
||||
@ -45,7 +98,7 @@ export async function RunOutputs({ run_id }: { run_id: string }) {
|
||||
<TableRow key={run.id}>
|
||||
<TableCell className="break-words">{fileName}</TableCell>
|
||||
<TableCell>
|
||||
<OutputRender run_id={run_id} filename={fileName} />
|
||||
<OutputRender run_id={run.run_id} filename={fileName} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
|
@ -5,9 +5,9 @@ import { db } from "@/db/db";
|
||||
import { workflowRunOutputs } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
export async function getRunsOutputDisplay(run_id: string) {
|
||||
return <RunOutputs run_id={run_id} />;
|
||||
}
|
||||
// export async function getRunsOutputDisplay(run_id: string) {
|
||||
// return <RunOutputs run_id={run_id} />;
|
||||
// }
|
||||
|
||||
export async function getRunsOutput(run_id: string) {
|
||||
// throw new Error("Not implemented");
|
||||
|
Loading…
x
Reference in New Issue
Block a user