import { useState } from "react"; import { Loader2, X } from "lucide-react"; import { createAnalysis, type Analysis, type DataBindItem } from "@/services/orchestrationApi"; import { BusinessQuestionsEditor } from "./BusinessQuestionsEditor"; import { DataBindSelector } from "./DataBindSelector"; import { compactQuestions } from "./utils"; function formatCreateAnalysisError(err: unknown) { const message = err instanceof Error ? err.message : "Failed to create analysis"; if (message.includes("unsupported jsonb version")) { return "Backend analysis creation is blocked by a JSONB storage error. The request payload is valid, but the Golang service/database returned an internal JSONB validation failure. Please fix POST /api/v1/analyses before creating an analysis."; } if (message.toLowerCase().includes("invalid request body")) { return "Backend rejected the analysis payload. Check that POST /api/v1/analyses accepts analysis_title, objective, business_questions, and data_bind as documented."; } return message; } function isDuplicateName(candidate: string, existing: Analysis[]): boolean { const normalized = candidate.trim().toLowerCase(); if (!normalized) return false; return existing.some((a) => a.analysis_title.trim().toLowerCase() === normalized); } interface NewAnalysisDialogProps { open: boolean; onClose: () => void; onCreated: (analysis: Analysis) => void; existingAnalyses: Analysis[]; } export function NewAnalysisDialog({ open, onClose, onCreated, existingAnalyses }: NewAnalysisDialogProps) { const [title, setTitle] = useState(""); const [objective, setObjective] = useState(""); const [questions, setQuestions] = useState(["", ""]); const [dataBind, setDataBind] = useState([]); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(null); if (!open) return null; const duplicateName = isDuplicateName(title, existingAnalyses); const canSubmit = title.trim() && !duplicateName && objective.trim() && compactQuestions(questions).length >= 2 && dataBind.length > 0; const submit = async (event: React.FormEvent) => { event.preventDefault(); if (!canSubmit) return; setSubmitting(true); setError(null); try { const analysis = await createAnalysis({ analysis_title: title.trim(), objective: objective.trim(), business_questions: compactQuestions(questions), data_bind: dataBind, }); onCreated(analysis); setTitle(""); setObjective(""); setQuestions(["", ""]); setDataBind([]); onClose(); } catch (err) { setError(formatCreateAnalysisError(err)); } finally { setSubmitting(false); } }; return (

New Analysis

Set the goal and bind the sources before starting the conversation.

setTitle(event.target.value)} disabled={submitting} placeholder="Q3 revenue movement" className="w-full rounded-lg border border-slate-200 px-3 py-2 text-sm outline-none focus:border-emerald-500 focus:ring-2 focus:ring-emerald-100" /> {duplicateName && (

An analysis with this name already exists. Choose a different name.

)}