/** * Jotai atoms for data export state management. * Manages export jobs, progress, and download state. * * Requirements: 8.1, 8.2, 8.3, 8.4, 8.6 */ import { atom } from 'jotai'; /** * Export format type */ export type ExportFormat = 'json' | 'csv' | 'coco' | 'yolo' | 'pascal_voc' | 'sharegpt' | 'alpaca'; /** * Export status type */ export type ExportStatus = 'pending' | 'processing' | 'completed' | 'failed'; /** * Status filter type for export */ export type StatusFilter = 'all' | 'completed' | 'pending' | 'in_progress'; /** * Export request interface */ export interface ExportRequest { format: ExportFormat; status_filter: StatusFilter; include_metadata: boolean; } /** * Export job interface */ export interface ExportJob { id: string; project_id: string; format: ExportFormat; status: ExportStatus; status_filter: StatusFilter; include_metadata: boolean; file_path: string | null; download_url: string | null; error_message: string | null; created_at: string; completed_at: string | null; total_tasks: number; exported_tasks: number; } /** * Export progress interface */ export interface ExportProgress { id: string; status: ExportStatus; progress: number; total_tasks: number; exported_tasks: number; error_message: string | null; } /** * Atom storing the current export job */ export const exportJobAtom = atom(null); /** * Atom storing export progress */ export const exportProgressAtom = atom(0); /** * Atom tracking export loading state */ export const exportLoadingAtom = atom(false); /** * Atom storing export-related errors */ export const exportErrorAtom = atom(null); /** * Atom storing export dialog open state */ export const exportDialogOpenAtom = atom(false); /** * Atom storing export request configuration */ export const exportRequestAtom = atom({ format: 'json', status_filter: 'all', include_metadata: true, }); /** * Atom storing export history (list of past exports) */ export const exportHistoryAtom = atom([]); /** * Derived atom to check if export is in progress */ export const isExportingAtom = atom((get) => { const job = get(exportJobAtom); return job?.status === 'pending' || job?.status === 'processing'; }); /** * Derived atom to check if export is completed */ export const isExportCompletedAtom = atom((get) => { const job = get(exportJobAtom); return job?.status === 'completed'; }); /** * Derived atom to check if export failed */ export const isExportFailedAtom = atom((get) => { const job = get(exportJobAtom); return job?.status === 'failed'; }); /** * Derived atom to get download URL */ export const exportDownloadUrlAtom = atom((get) => { const job = get(exportJobAtom); return job?.download_url ?? null; }); /** * Write-only atom to reset export state */ export const resetExportAtom = atom(null, (get, set) => { set(exportJobAtom, null); set(exportProgressAtom, 0); set(exportErrorAtom, null); set(exportRequestAtom, { format: 'json', status_filter: 'all', include_metadata: true, }); }); /** * Write-only atom to open export dialog */ export const openExportDialogAtom = atom(null, (get, set) => { set(exportDialogOpenAtom, true); set(resetExportAtom); }); /** * Write-only atom to close export dialog */ export const closeExportDialogAtom = atom(null, (get, set) => { set(exportDialogOpenAtom, false); }); /** * Export format options for UI */ export const exportFormatOptions: Array<{ value: ExportFormat; label: string; description: string; }> = [ { value: 'json', label: 'JSON', description: '原始 JSON 格式,包含完整数据', }, { value: 'csv', label: 'CSV', description: '表格格式,适合数据分析', }, { value: 'coco', label: 'COCO', description: '目标检测标准格式', }, { value: 'yolo', label: 'YOLO', description: 'YOLO 训练格式', }, { value: 'pascal_voc', label: 'VOC', description: 'PascalVOC XML 格式', }, { value: 'sharegpt', label: 'ShareGPT', description: '对话模型训练格式', }, { value: 'alpaca', label: 'Alpaca', description: 'LLM 指令微调格式', }, ]; /** * Status filter options for UI */ export const statusFilterOptions: Array<{ value: StatusFilter; label: string; }> = [ { value: 'all', label: '全部' }, { value: 'completed', label: '已完成' }, { value: 'in_progress', label: '进行中' }, { value: 'pending', label: '待处理' }, ];