feat: run log dialog
This commit is contained in:
parent
009589630d
commit
3e5ff7702e
@ -7,10 +7,12 @@ import { toast } from "sonner";
|
|||||||
|
|
||||||
export function CopyButton({
|
export function CopyButton({
|
||||||
className,
|
className,
|
||||||
|
children,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
text: string;
|
text: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
children?: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
@ -21,7 +23,7 @@ export function CopyButton({
|
|||||||
}}
|
}}
|
||||||
className={cn(" p-2 min-h-0 aspect-square", className)}
|
className={cn(" p-2 min-h-0 aspect-square", className)}
|
||||||
>
|
>
|
||||||
<Copy size={14} />
|
{children} <Copy size={14} />
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useEffect, useRef } from "react";
|
import React, { useEffect, useRef } from "react";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
|
||||||
export type LogsType = {
|
export type LogsType = {
|
||||||
machine_id?: string;
|
machine_id?: string;
|
||||||
@ -36,10 +37,24 @@ export function LogsViewer({ logs }: { logs: LogsType }) {
|
|||||||
}
|
}
|
||||||
container.current = ref;
|
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) => (
|
{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>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -3,8 +3,10 @@ import { RunOutputs } from "@/components/RunOutputs";
|
|||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
|
DialogClose,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogDescription,
|
DialogDescription,
|
||||||
|
DialogFooter,
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
@ -20,6 +22,8 @@ import { type findAllRuns } from "@/server/findAllRuns";
|
|||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
import { LiveStatus } from "./LiveStatus";
|
import { LiveStatus } from "./LiveStatus";
|
||||||
import { LogsType, LogsViewer } from "@/components/LogsViewer";
|
import { LogsType, LogsViewer } from "@/components/LogsViewer";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Edit, ExternalLink } from "lucide-react";
|
||||||
|
|
||||||
export async function RunDisplay({
|
export async function RunDisplay({
|
||||||
run,
|
run,
|
||||||
@ -75,8 +79,7 @@ export async function RunDisplay({
|
|||||||
<div className="max-h-96 overflow-y-scroll">
|
<div className="max-h-96 overflow-y-scroll">
|
||||||
<RunInputs run={run} />
|
<RunInputs run={run} />
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<RunOutputs run_id={run.id} />
|
<RunOutputs run={run} />
|
||||||
{run.run_log && <LogsViewer logs={run.run_log} />}
|
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="max-h-96 overflow-y-scroll">{view}</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 { OutputRender } from "./OutputRender";
|
||||||
import { CodeBlock } from "@/components/CodeBlock";
|
import { CodeBlock } from "@/components/CodeBlock";
|
||||||
import {
|
import {
|
||||||
@ -8,10 +18,17 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
|
import type { findAllRuns } from "@/server/findAllRuns";
|
||||||
import { getRunsOutput } from "@/server/getRunsOutput";
|
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 }) {
|
export async function RunOutputs({
|
||||||
const outputs = await getRunsOutput(run_id);
|
run,
|
||||||
|
}: { run: Awaited<ReturnType<typeof findAllRuns>>[0] }) {
|
||||||
|
const outputs = await getRunsOutput(run.id);
|
||||||
return (
|
return (
|
||||||
<Table className="table-fixed">
|
<Table className="table-fixed">
|
||||||
<TableHeader className="bg-background top-0 sticky">
|
<TableHeader className="bg-background top-0 sticky">
|
||||||
@ -21,6 +38,42 @@ export async function RunOutputs({ run_id }: { run_id: string }) {
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<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) => {
|
{outputs?.map((run) => {
|
||||||
const fileName =
|
const fileName =
|
||||||
run.data.images?.[0].filename ||
|
run.data.images?.[0].filename ||
|
||||||
@ -45,7 +98,7 @@ export async function RunOutputs({ run_id }: { run_id: string }) {
|
|||||||
<TableRow key={run.id}>
|
<TableRow key={run.id}>
|
||||||
<TableCell className="break-words">{fileName}</TableCell>
|
<TableCell className="break-words">{fileName}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<OutputRender run_id={run_id} filename={fileName} />
|
<OutputRender run_id={run.run_id} filename={fileName} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
);
|
||||||
|
@ -5,9 +5,9 @@ import { db } from "@/db/db";
|
|||||||
import { workflowRunOutputs } from "@/db/schema";
|
import { workflowRunOutputs } from "@/db/schema";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
|
|
||||||
export async function getRunsOutputDisplay(run_id: string) {
|
// export async function getRunsOutputDisplay(run_id: string) {
|
||||||
return <RunOutputs run_id={run_id} />;
|
// return <RunOutputs run_id={run_id} />;
|
||||||
}
|
// }
|
||||||
|
|
||||||
export async function getRunsOutput(run_id: string) {
|
export async function getRunsOutput(run_id: string) {
|
||||||
// throw new Error("Not implemented");
|
// throw new Error("Not implemented");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user