import { useState, useEffect } from 'react'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Label } from '@/components/ui/label'; import { Checkbox } from '@/components/ui/checkbox'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Download, FileJson, FileText } from 'lucide-react'; import { toast } from 'sonner'; import { getHttpApiClient } from '@/lib/http-api-client'; import type { Feature } from '@/store/app-store'; type ExportFormat = 'json' | 'yaml'; interface ExportFeaturesDialogProps { open: boolean; onOpenChange: (open: boolean) => void; projectPath: string; features: Feature[]; selectedFeatureIds?: string[]; } export function ExportFeaturesDialog({ open, onOpenChange, projectPath, features, selectedFeatureIds, }: ExportFeaturesDialogProps) { const [format, setFormat] = useState('json'); const [includeHistory, setIncludeHistory] = useState(true); const [includePlanSpec, setIncludePlanSpec] = useState(true); const [isExporting, setIsExporting] = useState(false); // Determine which features to export const featuresToExport = selectedFeatureIds && selectedFeatureIds.length > 0 ? features.filter((f) => selectedFeatureIds.includes(f.id)) : features; // Reset state when dialog opens useEffect(() => { if (open) { setFormat('json'); setIncludeHistory(true); setIncludePlanSpec(true); } }, [open]); const handleExport = async () => { setIsExporting(true); try { const api = getHttpApiClient(); const result = await api.features.export(projectPath, { featureIds: selectedFeatureIds, format, includeHistory, includePlanSpec, prettyPrint: true, }); if (!result.success || !result.data) { toast.error(result.error || 'Failed to export features'); return; } // Create a blob and trigger download const mimeType = format === 'json' ? 'application/json' : 'application/x-yaml'; const blob = new Blob([result.data], { type: mimeType }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = result.filename || `features-export.${format}`; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); toast.success(`Exported ${featuresToExport.length} feature(s) to ${format.toUpperCase()}`); onOpenChange(false); } catch (error) { toast.error(error instanceof Error ? error.message : 'Failed to export features'); } finally { setIsExporting(false); } }; return ( Export Features Export {featuresToExport.length} feature(s) to a file for backup or sharing with other projects.
{/* Format Selection */}
{/* Options */}
setIncludeHistory(!!checked)} data-testid="export-include-history" />
setIncludePlanSpec(!!checked)} data-testid="export-include-plan-spec" />
{/* Features to Export Preview */} {featuresToExport.length > 0 && featuresToExport.length <= 10 && (
{featuresToExport.map((f) => (
{f.title || f.description.slice(0, 50)}...
))}
)}
); }