import { useCallback, useEffect, useState } from "react"; import { Workflow, Plus, Square, RefreshCw, ChevronDown, ChevronRight, Loader2, AlertTriangle, } from "lucide-react"; import { cn } from "@/lib/utils"; import { useFlows, type FlowSummary } from "@/hooks/use-flows"; import { useSocket } from "@/providers/socket-provider"; import { useNotification } from "@/providers/notification-provider"; import { Dialog } from "@/components/ui/dialog"; import { Badge } from "@/components/ui/badge"; // --------------------------------------------------------------------------- // Start flow dialog // --------------------------------------------------------------------------- function StartFlowDialog({ open, onClose, onStart, }: { open: boolean; onClose: () => void; onStart: ( id: string, blueprint: string, description: string, params: Record, ) => Promise; }) { const socket = useSocket(); const [blueprints, setBlueprints] = useState([]); const [loadingBlueprints, setLoadingBlueprints] = useState(false); const [id, setId] = useState(""); const [blueprint, setBlueprint] = useState(""); const [description, setDescription] = useState(""); const [paramsJson, setParamsJson] = useState("{}"); const [submitting, setSubmitting] = useState(false); const [paramsError, setParamsError] = useState(null); // Fetch blueprints when dialog opens useEffect(() => { if (!open) return; setLoadingBlueprints(true); socket .flows() .getFlowBlueprints() .then((names) => { const list = names ?? []; setBlueprints(list); if (list.length > 0 && !blueprint) { setBlueprint(list[0]!); } }) .catch(() => setBlueprints([])) .finally(() => setLoadingBlueprints(false)); // eslint-disable-next-line react-hooks/exhaustive-deps }, [open, socket]); const reset = () => { setId(""); setBlueprint(""); setDescription(""); setParamsJson("{}"); setParamsError(null); setSubmitting(false); }; const handleSubmit = async () => { let params: Record = {}; try { params = JSON.parse(paramsJson); setParamsError(null); } catch { setParamsError("Invalid JSON"); return; } setSubmitting(true); try { await onStart(id, blueprint, description, params); reset(); onClose(); } catch { setSubmitting(false); } }; const isValid = id.trim().length > 0 && blueprint.length > 0 && description.trim().length > 0; return ( { if (!submitting) { reset(); onClose(); } }} title="Start Flow" footer={ <> } > {/* Flow ID */}
setId(e.target.value)} placeholder="my-flow-id" className="w-full rounded-lg border border-border bg-surface-100 px-3 py-2 text-sm text-fg placeholder:text-fg-subtle focus:border-brand-500 focus:outline-none focus:ring-1 focus:ring-brand-500" />
{/* Blueprint name */}
{loadingBlueprints ? (
Loading blueprints...
) : ( )}
{/* Description */}
setDescription(e.target.value)} placeholder="Human-readable description" className="w-full rounded-lg border border-border bg-surface-100 px-3 py-2 text-sm text-fg placeholder:text-fg-subtle focus:border-brand-500 focus:outline-none focus:ring-1 focus:ring-brand-500" />
{/* Parameters (JSON) */}