Skip to Content
FrontendBundlesCRUDImport/Export Components

Import/Export Components

The CRUD bundle provides robust import and export functionality for bulk data operations. These components support CSV and Excel files with validation, progress tracking, and error handling.


Component Overview

1. FileUploader

Drag-and-drop file upload component with validation and preview.

Props

interface FileUploaderProps { form: UseFormReturn<ImportFormDataType>; // React Hook Form instance fqcn_bui: IFQCN_BUI; // Component configuration onImport: (jobId: string) => void; // Import callback locale: string; // Locale for translations }

Features

  • Drag & Drop: Intuitive file upload interface
  • File Validation: Type and size validation
  • Preview: CSV data preview before import
  • Progress: Upload progress indicator
  • Error Handling: Clear error messages

2. ImportTable

Data preview table for imported CSV/Excel data.

Props

interface ImportTableProps { csvData: CSVDataType; // Parsed CSV data locale?: string; // Locale for translations } interface CSVDataType { headers: string[]; // Column headers rows: string[][]; // Data rows }

3. ImportForm

Configuration form for import settings.

Props

interface ImportFormProps { form: UseFormReturn<ImportFormDataType>; // Form instance fqcn_bui: IFQCN_BUI; // Configuration csrfJwt: string; // CSRF token locale?: string; // Locale tenant: string; // Tenant identifier }

Complete Implementation

import { FileUploader, ImportTable, ImportForm, ReviewContainer } from "@phpcreation/frontend-crud-react-nextjs-bundle/components"; function BasicImport() { const [importStep, setImportStep] = useState<'upload' | 'configure' | 'preview' | 'import'>('upload'); const [csvData, setCsvData] = useState<CSVDataType | null>(null); const [importJobId, setImportJobId] = useState<string | null>(null); const form = useForm<ImportFormDataType>({ defaultValues: { file: null, fileName: "", fieldDelimiter: ",", textDelimiter: '"', validation: "validate" } }); const handleFileImport = (jobId: string) => { setImportJobId(jobId); setImportStep('import'); }; return ( <div className="max-w-4xl mx-auto p-6"> <div className="bg-white rounded-lg shadow-md p-6"> <h1 className="text-2xl font-bold mb-6">Import Data</h1> {/* Step Indicator */} <div className="mb-8"> <div className="flex items-center justify-between"> {['upload', 'configure', 'preview', 'import'].map((step, index) => ( <div key={step} className="flex items-center"> <div className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium ${ importStep === step ? 'bg-blue-600 text-white' : 'bg-gray-200 text-gray-600' }`}> {index + 1} </div> <span className="ml-2 text-sm capitalize">{step}</span> {index < 3 && <div className="w-16 h-0.5 bg-gray-200 mx-4" />} </div> ))} </div> </div> {/* Upload Step */} {importStep === 'upload' && ( <div className="space-y-6"> <FileUploader form={form} fqcn_bui={{Bundle: "data", Unit: "import", Interface: "upload"}} onImport={handleFileImport} locale="en" /> {csvData && ( <div> <h3 className="text-lg font-semibold mb-4">Data Preview</h3> <ImportTable csvData={csvData} /> <div className="mt-4 text-right"> <Button onClick={() => setImportStep('configure')}> Configure Import </Button> </div> </div> )} </div> )} {/* Configure Step */} {importStep === 'configure' && ( <div className="space-y-6"> <ImportForm form={form} fqcn_bui={{Bundle: "data", Unit: "import", Interface: "config"}} csrfJwt={csrfToken} tenant={tenant} locale="en" /> <div className="flex justify-between"> <Button variant="outline" onClick={() => setImportStep('upload')} > Back </Button> <Button onClick={() => setImportStep('preview')}> Preview Import </Button> </div> </div> )} {/* Preview Step */} {importStep === 'preview' && ( <div className="space-y-6"> <ReviewContainer importData={csvData} formConfig={form.getValues()} onConfirm={() => setImportStep('import')} /> <div className="flex justify-between"> <Button variant="outline" onClick={() => setImportStep('configure')} > Back to Configuration </Button> <Button onClick={() => startImport()}> Start Import </Button> </div> </div> )} {/* Import Progress */} {importStep === 'import' && importJobId && ( <ImportProgress jobId={importJobId} /> )} </div> </div> ); }

Best Practices

Performance

  • Process large files in chunks
  • Use web workers for heavy processing
  • Implement progress indicators
  • Provide cancel functionality

Data Validation

  • Always validate file format and size
  • Implement comprehensive data validation
  • Handle encoding issues (UTF-8, etc.)
  • Provide clear error messages
Last updated on