'use client'; import React, { useState, useEffect } from 'react'; import { useSearchParams } from 'next/navigation'; import { Plus, Search, Filter, Database, FileText, BarChart3, Trash2, Edit3, Eye, Lock, Users, Globe, Upload } from 'lucide-react'; import { Dataset, Document, AccessGroup, AccessFilter, } from '@/services'; import { AppLayout } from '@/components/layout/app-layout'; import { AuthGuard } from '@/components/auth/auth-guard'; import { GT2_CAPABILITIES } from '@/lib/capabilities'; import { DatasetCard, DatasetCreateModal, DatasetEditModal, BulkUpload, DocumentSummaryModal, CreateDatasetData, UpdateDatasetData, DatasetDetailsDrawer } from '@/components/datasets'; import { DatasetDocumentsModal } from '@/components/datasets/dataset-documents-modal'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { usePageTitle } from '@/hooks/use-page-title'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { useDatasets, useDatasetSummary, useCreateDataset, useUpdateDataset, useDeleteDataset, datasetKeys } from '@/hooks/use-datasets'; import { useQueryClient } from '@tanstack/react-query'; import { formatStorageSize } from '@/lib/utils'; // Statistics interface interface DatasetSummary { total_datasets: number; owned_datasets: number; team_datasets: number; org_datasets: number; total_documents: number; assigned_documents: number; unassigned_documents: number; total_storage_mb: number; assigned_storage_mb: number; unassigned_storage_mb: number; is_admin?: boolean; total_tenant_storage_mb?: number; } function DatasetsPageContent() { usePageTitle('Datasets'); const searchParams = useSearchParams(); const queryClient = useQueryClient(); // Filter and search state const [searchQuery, setSearchQuery] = useState(''); const [accessFilter, setAccessFilter] = useState('all'); // React Query hooks const { data: datasets = [], isLoading: loading } = useDatasets(accessFilter); const { data: summary = null } = useDatasetSummary(); const createDataset = useCreateDataset(); const updateDataset = useUpdateDataset(); const deleteDataset = useDeleteDataset(); // Helper to refresh dataset data const refreshDatasets = () => { queryClient.invalidateQueries({ queryKey: datasetKeys.all }); }; // UI state const [selectedDatasetId, setSelectedDatasetId] = useState(null); const [showDetailsDrawer, setShowDetailsDrawer] = useState(false); const [selectedDatasets, setSelectedDatasets] = useState([]); // Modal states const [showCreateModal, setShowCreateModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false); const [showBulkUpload, setShowBulkUpload] = useState(false); const [selectedDatasetForUpload, setSelectedDatasetForUpload] = useState(''); const [editingDataset, setEditingDataset] = useState(null); const [showDocumentSummary, setShowDocumentSummary] = useState(false); const [summaryDocumentId, setSummaryDocumentId] = useState(''); const [showDocumentsModal, setShowDocumentsModal] = useState(false); const [documentsDatasetId, setDocumentsDatasetId] = useState(null); const [documentsDatasetName, setDocumentsDatasetName] = useState(''); const [lastUploadedDatasetId, setLastUploadedDatasetId] = useState(null); const [initialDocuments, setInitialDocuments] = useState([]); // Documents from recent upload // Clear any stale dataset selections on mount to prevent foreign key errors useEffect(() => { setSelectedDatasetForUpload(''); setSelectedDatasets([]); }, []); // Dataset action handlers const handleCreateDataset = async (datasetData: CreateDatasetData) => { try { const result = await createDataset.mutateAsync({ name: datasetData.name, description: datasetData.description, access_group: datasetData.access_group, team_members: datasetData.team_members, tags: datasetData.tags }); console.log('Dataset created successfully:', result?.name); } catch (error) { console.error('Failed to create dataset:', error); } }; const handleDatasetView = (datasetId: string) => { const dataset = datasets.find(d => d.id === datasetId); setDocumentsDatasetId(datasetId); setDocumentsDatasetName(dataset?.name || ''); setShowDocumentsModal(true); }; const handleDatasetEdit = (datasetId: string) => { const dataset = datasets.find(d => d.id === datasetId); if (dataset) { setEditingDataset(dataset); setShowEditModal(true); } }; const handleUpdateDataset = async (datasetId: string, updateData: UpdateDatasetData) => { try { const result = await updateDataset.mutateAsync({ datasetId, updateData }); console.log('Dataset updated successfully:', result?.name); setShowEditModal(false); setEditingDataset(null); } catch (error) { console.error('Failed to update dataset:', error); } }; const handleDatasetDelete = async (datasetId: string) => { if (!confirm('Are you sure you want to delete this dataset? This action cannot be undone.')) { return; } try { await deleteDataset.mutateAsync(datasetId); console.log('Dataset deleted successfully'); } catch (error) { console.error('Failed to delete dataset:', error); } }; const handleDatasetUpload = (datasetId: string) => { console.log('Uploading to dataset:', datasetId); // Verify the dataset still exists in our current list const dataset = datasets.find(d => d.id === datasetId); if (!dataset) { console.error('Dataset not found:', datasetId); alert('Dataset not found. Please refresh the page and try again.'); refreshDatasets(); // Refresh datasets return; } // Store the dataset ID for routing after upload completes setLastUploadedDatasetId(datasetId); setSelectedDatasetForUpload(datasetId); setShowBulkUpload(true); }; const handleDatasetProcess = (datasetId: string) => { console.log('Processing dataset:', datasetId); // TODO: Trigger processing for all documents in dataset }; const handleDatasetReindex = (datasetId: string) => { console.log('Reindexing dataset:', datasetId); // TODO: Trigger reindexing }; // Filter datasets based on search query const filteredDatasets = datasets.filter(dataset => dataset.name.toLowerCase().includes(searchQuery.toLowerCase()) || dataset.description?.toLowerCase().includes(searchQuery.toLowerCase()) || dataset.tags.some(tag => tag.toLowerCase().includes(searchQuery.toLowerCase())) ); // Get icon for access group const getAccessIcon = (accessGroup: AccessGroup) => { switch (accessGroup) { case 'individual': return ; case 'team': return ; case 'organization': return ; default: return ; } }; // Get access group color const getAccessColor = (accessGroup: AccessGroup) => { switch (accessGroup) { case 'individual': return 'text-gray-600'; case 'team': return 'text-blue-600'; case 'organization': return 'text-green-600'; default: return 'text-gray-600'; } }; return (
{/* Header */}

Dataset Management Hub

Manage your datasets and documents for RAG in one unified interface

{/* Statistics Cards */} {summary && (

My Storage

{formatStorageSize(summary.total_storage_mb)}

{/* TODO: Show % of allocation when storage_allocation_mb added to tenant schema */}
{summary.is_admin && summary.total_tenant_storage_mb !== undefined && (

Total Tenant Storage

{formatStorageSize(summary.total_tenant_storage_mb)}

)}
)} {/* Main Content Area */}
{/* Controls */}
{/* Search */}
setSearchQuery(value)} className="pl-10" clearable />
{/* Access Filter */}
{/* Dataset List */} {loading ? (
) : (
{filteredDatasets.map((dataset) => ( ))}
)} {!loading && filteredDatasets.length === 0 && (

No datasets found

{searchQuery ? `No datasets match "${searchQuery}"` : "Create your first dataset to get started" }

)}
{/* Modals */} { setShowBulkUpload(open); if (!open) { setSelectedDatasetForUpload(''); // Clear selection when modal closes } }} datasets={datasets.map(d => ({ id: d.id, name: d.name, document_count: d.document_count }))} preselectedDatasetId={selectedDatasetForUpload} onCreateDataset={() => { setShowBulkUpload(false); setShowCreateModal(true); }} onUploadStart={(datasetId, documents) => { // Route to documents page immediately when upload starts // Store any initial documents to display immediately if (documents && documents.length > 0) { setInitialDocuments(documents); } handleDatasetView(datasetId); }} onUploadComplete={async (results) => { console.log('Upload documents completed:', results); // React Query will auto-refresh via cache invalidation }} /> { setShowEditModal(open); if (!open) { setEditingDataset(null); } }} onUpdateDataset={handleUpdateDataset} dataset={editingDataset} loading={updateDataset.isPending} /> { setShowDetailsDrawer(false); setSelectedDatasetId(null); }} onDatasetDeleted={refreshDatasets} onDatasetUpdated={refreshDatasets} /> { setShowDocumentSummary(open); if (!open) { setSummaryDocumentId(''); } }} documentId={summaryDocumentId} /> { setShowDocumentsModal(open); if (!open) { setDocumentsDatasetId(null); setDocumentsDatasetName(''); setInitialDocuments([]); // Clear initial documents when modal closes } }} datasetId={documentsDatasetId} datasetName={documentsDatasetName} initialDocuments={initialDocuments} />
); } export default function DatasetsPage() { return ( ); }