/** * ExportButton Component * * CSV export dropdown with two options: * 1. Export Selected Rows (client-side, immediate) * 2. Export All Filtered Results (server-side via Server Action, max 5000) * * Features: * - Dropdown menu with export options * - Disabled state when no data/selection * - Loading state for server-side export * - Warning when result set > 5000 rows */ 'use client'; import { useState } from 'react'; import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { Download, Loader2 } from 'lucide-react'; import { generatePolicySettingsCsv, downloadCsv, generateCsvFilename } from '@/lib/utils/csv-export'; import { exportPolicySettingsCSV } from '@/lib/actions/policySettings'; import type { PolicySettingRow } from '@/lib/types/policy-table'; import { toast } from 'sonner'; interface ExportButtonProps { selectedRows: PolicySettingRow[]; selectedCount: number; totalCount: number; // Filter state for server-side export policyTypes?: string[]; searchQuery?: string; sortBy?: string; sortDir?: 'asc' | 'desc'; } export function ExportButton({ selectedRows, selectedCount, totalCount, policyTypes, searchQuery, sortBy, sortDir, }: ExportButtonProps) { const [isExporting, setIsExporting] = useState(false); const hasSelection = selectedCount > 0; const hasData = totalCount > 0; const exceedsLimit = totalCount > 5000; // Client-side export: Export selected rows const handleExportSelected = () => { if (!hasSelection) return; try { const csvContent = generatePolicySettingsCsv(selectedRows); const filename = generateCsvFilename('policy-settings', selectedCount); downloadCsv(csvContent, filename); toast.success(`Exported ${selectedCount} rows to ${filename}`); } catch (error) { console.error('Export error:', error); toast.error('Failed to export selected rows'); } }; // Server-side export: Export all filtered results const handleExportAll = async () => { setIsExporting(true); try { const result = await exportPolicySettingsCSV({ policyTypes: policyTypes && policyTypes.length > 0 ? policyTypes : undefined, searchQuery: searchQuery || undefined, sortBy: sortBy as 'settingName' | 'policyName' | 'policyType' | 'lastSyncedAt' | undefined, sortDir, maxRows: 5000, }); if (result.success && result.csv && result.filename) { downloadCsv(result.csv, result.filename); toast.success(`Exported ${result.rowCount} rows to ${result.filename}`); } else { toast.error(result.error || 'Failed to export data'); } } catch (error) { console.error('Export error:', error); toast.error('An unexpected error occurred during export'); } finally { setIsExporting(false); } }; return ( Export to CSV
Export Selected {hasSelection ? `${selectedCount} rows` : 'No rows selected'}
Export All Filtered {exceedsLimit ? `${totalCount} rows (limited to 5000)` : `${totalCount} rows`}
{exceedsLimit && ( <>
⚠️ Results exceed 5000 rows. Export will be limited.
)}
); }