"use client"; import { useEffect, useState } from "react"; import { Folder, Search, X } from "lucide-react"; import type { Document, Workflow } from "../shared/types"; import { createTabularReview } from "@/app/lib/mikeApi"; import { useRouter } from "next/navigation"; import { useDirectoryData } from "../shared/useDirectoryData"; import { FileDirectory } from "../shared/FileDirectory"; import type { Project } from "../shared/types"; import { useChatHistoryContext } from "@/app/contexts/ChatHistoryContext"; import { Modal } from "../shared/Modal"; import { WorkflowPickerContent } from "./WorkflowPickerContent"; import { workflowDetailPath } from "./workflowRoutes"; interface Props { workflows: Workflow[]; workflow: Workflow | null; onClose: () => void; } // --------------------------------------------------------------------------- // Toggle switch // --------------------------------------------------------------------------- function Toggle({ on, onToggle }: { on: boolean; onToggle: () => void }) { return ( ); } // --------------------------------------------------------------------------- // Simple project picker (input + dropdown) // --------------------------------------------------------------------------- function SimpleProjectPicker({ projects, selectedId, onSelect, }: { projects: Project[]; selectedId: string | null; onSelect: (id: string | null) => void; }) { const [search, setSearch] = useState(""); const [open, setOpen] = useState(false); const selected = projects.find((p) => p.id === selectedId); const filtered = search ? projects.filter((p) => p.name.toLowerCase().includes(search.toLowerCase()), ) : projects; return (
{ setSearch(e.target.value); setOpen(true); onSelect(null); }} onFocus={() => setOpen(true)} onBlur={() => setTimeout(() => setOpen(false), 150)} placeholder="Select a project…" className="w-full text-xs text-gray-700 placeholder:text-gray-400 bg-gray-50 border border-gray-200 rounded-md px-3 py-2 outline-none" /> {selectedId && ( )} {open && !selectedId && (
{filtered.length === 0 ? (

No projects found

) : ( filtered.map((p) => ( )) )}
)}
); } // --------------------------------------------------------------------------- // DisplayWorkflowModal // --------------------------------------------------------------------------- export function DisplayWorkflowModal({ workflows, workflow, onClose }: Props) { const [screen, setScreen] = useState<"select" | "configure">("select"); const [selected, setSelected] = useState(workflow); const [listSearch, setListSearch] = useState(""); // Configure screen state const [inProject, setInProject] = useState(false); const [selectedProjectId, setSelectedProjectId] = useState( null, ); const [selectedDocIds, setSelectedDocIds] = useState>( new Set(), ); const [docSearch, setDocSearch] = useState(""); const [assistantPrompt, setAssistantPrompt] = useState(""); const [saving, setSaving] = useState(false); const router = useRouter(); const { saveChat, setNewChatMessages } = useChatHistoryContext(); const { loading: dirLoading, projects, standaloneDocuments, } = useDirectoryData(screen === "configure"); useEffect(() => { if (workflow) { setSelected(workflow); setScreen("select"); setListSearch(""); } else { setSelected(null); } }, [workflow?.id]); // Reset configure state on back useEffect(() => { if (screen === "select") { setInProject(false); setSelectedProjectId(null); setSelectedDocIds(new Set()); setDocSearch(""); setAssistantPrompt(""); } }, [screen]); function handleClose() { setSelected(null); setScreen("select"); onClose(); } if (!workflow) return null; const wf = selected ?? workflow; // --------------------------------------------------------------------------- // Handlers // --------------------------------------------------------------------------- async function handleStartChat() { setSaving(true); try { const projectId = inProject ? selectedProjectId! : undefined; const chatId = await saveChat(projectId); if (!chatId) return; const allDocs: Document[] = [ ...standaloneDocuments, ...projects.flatMap((p) => p.documents || []), ]; const files = allDocs .filter((d) => selectedDocIds.has(d.id)) .map((d) => ({ filename: d.filename, document_id: d.id, })); const content = assistantPrompt.trim() ? `implement workflow\n\n${assistantPrompt.trim()}` : "implement workflow"; setNewChatMessages([ { role: "user", content, files: files.length > 0 ? files : undefined, }, ]); handleClose(); router.push( projectId ? `/projects/${projectId}/assistant/chat/${chatId}` : `/assistant/chat/${chatId}`, ); } finally { setSaving(false); } } async function handleCreateReview() { const allDocs: Document[] = [ ...standaloneDocuments, ...projects.flatMap((p) => p.documents || []), ]; const docIds = allDocs .filter((d) => selectedDocIds.has(d.id)) .map((d) => d.id); const projectId = inProject ? selectedProjectId! : undefined; setSaving(true); try { const review = await createTabularReview({ title: wf.title, document_ids: docIds, columns_config: wf.columns_config || [], workflow_id: wf.is_system ? undefined : wf.id, project_id: projectId, }); handleClose(); router.push( projectId ? `/projects/${projectId}/tabular-reviews/${review.id}` : `/tabular-reviews/${review.id}`, ); } finally { setSaving(false); } } // --------------------------------------------------------------------------- // Tabular doc browser helpers // --------------------------------------------------------------------------- const q = docSearch.toLowerCase().trim(); const selectedProject = projects.find((p) => p.id === selectedProjectId); const projectDocs = selectedProject?.documents ?? []; const filteredProjectDocs = q ? projectDocs.filter((d) => d.filename.toLowerCase().includes(q), ) : projectDocs; const filteredStandalone = q ? standaloneDocuments.filter((d) => d.filename.toLowerCase().includes(q), ) : standaloneDocuments; const filteredAllProjects = projects .map((p) => ({ ...p, documents: (p.documents || []).filter( (d) => !q || d.filename.toLowerCase().includes(q), ), })) .filter( (p) => !q || p.name.toLowerCase().includes(q) || p.documents.length > 0, ); const breadcrumbs = screen === "select" ? ["Workflows", "Select workflow"] : [ , wf.title, wf.type === "assistant" ? "New Chat" : "New Review", ]; const selectPageAction = () => { router.push(workflowDetailPath(wf)); handleClose(); }; // --------------------------------------------------------------------------- // Render // --------------------------------------------------------------------------- return ( 0 : selectedDocIds.size > 0) ? ( {selectedDocIds.size} selected ) : null } primaryAction={ screen === "select" ? { label: "Use", onClick: () => setScreen("configure"), } : wf.type === "assistant" ? { label: saving ? "Starting…" : "Start Chat", onClick: handleStartChat, disabled: saving || (inProject && !selectedProjectId), } : { label: saving ? "Creating…" : "Create Review", onClick: handleCreateReview, disabled: saving || selectedDocIds.size === 0 || (inProject && !selectedProjectId), } } cancelAction={false} > {/* ── SELECT SCREEN ── */} {screen === "select" && ( { if (next) setSelected(next); }} search={listSearch} onSearchChange={setListSearch} workflowType="all" previewMode="auto" showTypeIcon allowClearPreview={false} /> )} {/* ── ASSISTANT CONFIGURE SCREEN ── */} {screen === "configure" && wf.type === "assistant" && (
{/* Add-on prompt */}

Message (optional)