feat(web): add custom file download button for runs output
This commit is contained in:
parent
8f67a136c3
commit
ee68507755
@ -6,12 +6,13 @@ import { z } from "zod";
|
|||||||
const Request = z.object({
|
const Request = z.object({
|
||||||
file_name: z.string(),
|
file_name: z.string(),
|
||||||
run_id: z.string(),
|
run_id: z.string(),
|
||||||
type: z.enum(["image/png", "image/jpeg"]),
|
type: z.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const dynamic = "force-dynamic";
|
export const dynamic = "force-dynamic";
|
||||||
|
|
||||||
export async function GET(request: Request) {
|
export async function GET(request: Request) {
|
||||||
|
console.log("yo hello");
|
||||||
const [data, error] = await parseDataSafe(Request, request);
|
const [data, error] = await parseDataSafe(Request, request);
|
||||||
if (!data || error) return error;
|
if (!data || error) return error;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ export async function POST(request: Request) {
|
|||||||
|
|
||||||
const { run_id, status, output_data } = data;
|
const { run_id, status, output_data } = data;
|
||||||
|
|
||||||
console.log(run_id, status, output_data);
|
// console.log(run_id, status, output_data);
|
||||||
|
|
||||||
if (output_data) {
|
if (output_data) {
|
||||||
const workflow_run_output = await db.insert(workflowRunOutputs).values({
|
const workflow_run_output = await db.insert(workflowRunOutputs).values({
|
||||||
@ -25,7 +25,7 @@ export async function POST(request: Request) {
|
|||||||
data: output_data,
|
data: output_data,
|
||||||
});
|
});
|
||||||
} else if (status) {
|
} else if (status) {
|
||||||
console.log("status", status);
|
// console.log("status", status);
|
||||||
const workflow_run = await db
|
const workflow_run = await db
|
||||||
.update(workflowRunsTable)
|
.update(workflowRunsTable)
|
||||||
.set({
|
.set({
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
import { replaceCDNUrl } from "@/server/resource";
|
|
||||||
import { NextResponse, type NextRequest } from "next/server";
|
import { NextResponse, type NextRequest } from "next/server";
|
||||||
|
import { getFileDownloadUrl } from "../../../server/getFileDownloadUrl";
|
||||||
|
|
||||||
export async function GET(request: NextRequest) {
|
export async function GET(request: NextRequest) {
|
||||||
const file = new URL(request.url).searchParams.get("file");
|
const file = new URL(request.url).searchParams.get("file");
|
||||||
// console.log(`${process.env.SPACES_ENDPOINT}/comfyui-deploy/${file}`);
|
if (!file) return NextResponse.redirect("/");
|
||||||
return NextResponse.redirect(
|
return NextResponse.redirect(getFileDownloadUrl(file));
|
||||||
replaceCDNUrl(
|
}
|
||||||
`${process.env.SPACES_ENDPOINT}/${process.env.SPACES_BUCKET}/${file}`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
@ -3,5 +3,5 @@ import { LoaderIcon } from "lucide-react";
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
export function LoadingIcon() {
|
export function LoadingIcon() {
|
||||||
return <LoaderIcon size={14} className="ml-2 animate-spin" />;
|
return <LoaderIcon size={14} className="animate-spin" />;
|
||||||
}
|
}
|
||||||
|
31
web/src/components/OutputRender.tsx
Normal file
31
web/src/components/OutputRender.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { Download } from "lucide-react";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { getFileDownloadUrl } from "@/server/getFileDownloadUrl";
|
||||||
|
|
||||||
|
|
||||||
|
export function OutputRender(props: { run_id: string; filename: string; }) {
|
||||||
|
if (props.filename.endsWith(".png")) {
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
className="max-w-[200px]"
|
||||||
|
alt={props.filename}
|
||||||
|
src={`/api/view?file=${encodeURIComponent(
|
||||||
|
`outputs/runs/${props.run_id}/${props.filename}`
|
||||||
|
)}`} />
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return <Button className="gap-2" onClick={async () => {
|
||||||
|
const url = await getFileDownloadUrl(`outputs/runs/${props.run_id}/${props.filename}`);
|
||||||
|
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = props.filename;
|
||||||
|
a.target = '_blank'; // Add this line
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
}}>Download <Download size={14} /></Button>;
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
import { RunInputs } from "@/components/RunInputs";
|
import { RunInputs } from "@/components/RunInputs";
|
||||||
import { LiveStatus } from "./LiveStatus";
|
import { LiveStatus } from "./LiveStatus";
|
||||||
import { RunOutputs } from "@/components/RunOutputs";
|
import { RunOutputs } from "@/components/RunOutputs";
|
||||||
@ -51,17 +52,3 @@ export async function RunDisplay({
|
|||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function OutputRender(props: { run_id: string; filename: string }) {
|
|
||||||
if (props.filename.endsWith(".png")) {
|
|
||||||
return (
|
|
||||||
<img
|
|
||||||
className="max-w-[200px]"
|
|
||||||
alt={props.filename}
|
|
||||||
src={`/api/view?file=${encodeURIComponent(
|
|
||||||
`outputs/runs/${props.run_id}/${props.filename}`
|
|
||||||
)}`}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { OutputRender } from "./RunDisplay";
|
import { OutputRender } from "./OutputRender";
|
||||||
import { CodeBlock } from "@/components/CodeBlock";
|
import { CodeBlock } from "@/components/CodeBlock";
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { OutputRender } from "./RunDisplay";
|
import { OutputRender } from "./OutputRender";
|
||||||
import { CodeBlock } from "@/components/CodeBlock";
|
import { CodeBlock } from "@/components/CodeBlock";
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
|
@ -128,7 +128,7 @@ export function RunWorkflowButton({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Run <Play size={14} /> {isLoading && <LoadingIcon />}
|
Run {isLoading ? <LoadingIcon /> : <Play size={14} />}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ export function CreateDeploymentButton({
|
|||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button className="gap-2" disabled={isLoading} variant="outline">
|
<Button className="gap-2" disabled={isLoading} variant="outline">
|
||||||
Deploy <MoreVertical size={14} /> {isLoading && <LoadingIcon />}
|
Deploy {isLoading ? <LoadingIcon /> : <MoreVertical size={14} /> }
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="w-56">
|
<DropdownMenuContent className="w-56">
|
||||||
|
9
web/src/server/getFileDownloadUrl.ts
Normal file
9
web/src/server/getFileDownloadUrl.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
'use server'
|
||||||
|
|
||||||
|
import { replaceCDNUrl } from "@/server/resource";
|
||||||
|
|
||||||
|
export async function getFileDownloadUrl(file: string) {
|
||||||
|
return replaceCDNUrl(
|
||||||
|
`${process.env.SPACES_ENDPOINT}/${process.env.SPACES_BUCKET}/${file}`
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user