Browse Source
- Restore image thumbnails as main preview in TemplateCard - Add small icon button in top right to trigger workflow preview - Create WorkflowPreviewModal for larger preview display - Fix WorkflowPreview to properly show all nodes with fitView - Add legend showing node type colors in modalhandoff-20260429-1057
4 changed files with 223 additions and 22 deletions
@ -0,0 +1,117 @@ |
|||||
|
"use client"; |
||||
|
|
||||
|
import { useEffect, useCallback } from "react"; |
||||
|
import { Node, Edge } from "@xyflow/react"; |
||||
|
import { WorkflowPreview } from "./WorkflowPreview"; |
||||
|
|
||||
|
interface WorkflowPreviewModalProps { |
||||
|
isOpen: boolean; |
||||
|
onClose: () => void; |
||||
|
templateName: string; |
||||
|
workflow: { nodes: Node[]; edges: Edge[] }; |
||||
|
} |
||||
|
|
||||
|
export function WorkflowPreviewModal({ |
||||
|
isOpen, |
||||
|
onClose, |
||||
|
templateName, |
||||
|
workflow, |
||||
|
}: WorkflowPreviewModalProps) { |
||||
|
// Handle escape key to close
|
||||
|
const handleKeyDown = useCallback( |
||||
|
(e: KeyboardEvent) => { |
||||
|
if (e.key === "Escape") { |
||||
|
onClose(); |
||||
|
} |
||||
|
}, |
||||
|
[onClose] |
||||
|
); |
||||
|
|
||||
|
useEffect(() => { |
||||
|
if (isOpen) { |
||||
|
document.addEventListener("keydown", handleKeyDown); |
||||
|
return () => document.removeEventListener("keydown", handleKeyDown); |
||||
|
} |
||||
|
}, [isOpen, handleKeyDown]); |
||||
|
|
||||
|
if (!isOpen) return null; |
||||
|
|
||||
|
return ( |
||||
|
<div |
||||
|
className="fixed inset-0 z-50 flex items-center justify-center" |
||||
|
onClick={onClose} |
||||
|
> |
||||
|
{/* Backdrop */} |
||||
|
<div className="absolute inset-0 bg-black/70" /> |
||||
|
|
||||
|
{/* Modal */} |
||||
|
<div |
||||
|
className="relative bg-neutral-900 border border-neutral-700 rounded-xl shadow-2xl w-[90vw] max-w-3xl max-h-[85vh] flex flex-col" |
||||
|
onClick={(e) => e.stopPropagation()} |
||||
|
> |
||||
|
{/* Header */} |
||||
|
<div className="flex items-center justify-between px-5 py-4 border-b border-neutral-700"> |
||||
|
<h3 className="text-base font-semibold text-neutral-100"> |
||||
|
{templateName} — Workflow Preview |
||||
|
</h3> |
||||
|
<button |
||||
|
onClick={onClose} |
||||
|
className="p-1.5 rounded-md text-neutral-400 hover:text-neutral-200 hover:bg-neutral-800 transition-colors" |
||||
|
> |
||||
|
<svg |
||||
|
className="w-5 h-5" |
||||
|
fill="none" |
||||
|
viewBox="0 0 24 24" |
||||
|
stroke="currentColor" |
||||
|
strokeWidth={2} |
||||
|
> |
||||
|
<path |
||||
|
strokeLinecap="round" |
||||
|
strokeLinejoin="round" |
||||
|
d="M6 18L18 6M6 6l12 12" |
||||
|
/> |
||||
|
</svg> |
||||
|
</button> |
||||
|
</div> |
||||
|
|
||||
|
{/* Preview Content */} |
||||
|
<div className="flex-1 min-h-0 p-4"> |
||||
|
<div className="w-full h-[60vh] bg-neutral-800/50 rounded-lg border border-neutral-700 overflow-hidden"> |
||||
|
<WorkflowPreview workflow={workflow} /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
{/* Legend */} |
||||
|
<div className="px-5 py-3 border-t border-neutral-700"> |
||||
|
<div className="flex flex-wrap items-center gap-4 text-xs text-neutral-400"> |
||||
|
<span className="font-medium text-neutral-300">Node Types:</span> |
||||
|
<div className="flex items-center gap-1.5"> |
||||
|
<div className="w-3 h-3 rounded bg-[#22c55e]" /> |
||||
|
<span>Image Input</span> |
||||
|
</div> |
||||
|
<div className="flex items-center gap-1.5"> |
||||
|
<div className="w-3 h-3 rounded bg-[#3b82f6]" /> |
||||
|
<span>Prompt</span> |
||||
|
</div> |
||||
|
<div className="flex items-center gap-1.5"> |
||||
|
<div className="w-3 h-3 rounded bg-[#f97316]" /> |
||||
|
<span>Generate Image</span> |
||||
|
</div> |
||||
|
<div className="flex items-center gap-1.5"> |
||||
|
<div className="w-3 h-3 rounded bg-[#a855f7]" /> |
||||
|
<span>Generate Video</span> |
||||
|
</div> |
||||
|
<div className="flex items-center gap-1.5"> |
||||
|
<div className="w-3 h-3 rounded bg-[#06b6d4]" /> |
||||
|
<span>LLM</span> |
||||
|
</div> |
||||
|
<div className="flex items-center gap-1.5"> |
||||
|
<div className="w-3 h-3 rounded bg-[#6b7280]" /> |
||||
|
<span>Output</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
); |
||||
|
} |
||||
Loading…
Reference in new issue