import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogDescription, DialogFooter } from "@/components/ui/dialog"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Code, Table as TableIcon, BarChart as ChartIcon, Download, LayoutDashboard, Loader2 } from "lucide-react"; import { ScrollArea } from "@/components/ui/scroll-area"; import { useDashboardStore, type ChartConfig } from "@/store/dashboardStore"; import { useVisualizationStore } from "@/store/visualizationStore"; import { useProjectStore } from "@/store/projectStore"; import { useTranslation } from "react-i18next"; import { VegaChart } from "./VegaChart"; export function VisualizationPanel() { const { t } = useTranslation(); const [view, setView] = useState<'table' | 'chart'>('chart'); const [confirmOpen, setConfirmOpen] = useState(false); const [pendingChart, setPendingChart] = useState | null>(null); const { addChart } = useDashboardStore(); const { currentProject } = useProjectStore(); const { currentData, currentSQL, currentChartSpec, currentChartInfo, isLoading, error } = useVisualizationStore(); const buildPendingChart = (): Omit | null => { if (!currentData || !currentSQL) return null; if (view === "table") { return { id: Date.now().toString(), title: currentChartSpec?.title || 'Generated Analysis', type: "table", data: currentData, sql: currentSQL, chartSpec: null, }; } const mark = currentChartSpec?.mark; const markType = typeof mark === "string" ? mark : mark?.type; const dashboardType = markType === "line" ? "line" : "bar"; return { id: Date.now().toString(), title: currentChartSpec?.title || 'Generated Analysis', type: dashboardType, data: currentData, sql: currentSQL, chartSpec: currentChartSpec, }; }; const handleAddToDashboard = () => { if (!currentProject) return; const chart = buildPendingChart(); if (!chart) return; setPendingChart(chart); setConfirmOpen(true); }; const handleConfirmAdd = () => { if (!pendingChart || !currentProject) return; addChart(pendingChart, currentProject.id); setConfirmOpen(false); setPendingChart(null); }; if (isLoading) { return (
Generating visualization...
); } if (error) { return (
Visualization Error
{error}
) } if (!currentData || currentData.length === 0) { return (

No data to visualize.

Ask the chat to generate some insights!

); } const objectRows = currentData.filter((row) => row && typeof row === "object" && !Array.isArray(row)); if (objectRows.length === 0) { return (

Data format is not supported for visualization.

); } const columns = Object.keys(objectRows[0] as Record); return (
{/* Toolbar */}

Visualization

SQL } /> Generated SQL Query This is the SQL query generated by the AI to retrieve the data shown below.
{currentSQL}
{/* Content */}
{currentChartSpec?.title || 'Analysis Result'} {currentChartInfo?.reasoning || currentChartSpec?.description || 'Generated from your query'} {view === 'chart' ? (
{currentChartSpec ? ( ) : (

No chart configuration available for this data.

)}
) : ( {columns.map(col => {col})} {objectRows.map((row, i) => ( {columns.map(col => ( {String((row as Record)[col] ?? "")} ))} ))}
)}
{t('confirmAddToDashboard')} {t('confirmAddChartToDashboardDesc')}
); }