/** * AnnotationView Component * * Annotation interface with LabelStudio editor integration. * Requirements: 3.2, 8.1, 8.2, 8.3, 10.4 */ import React, { useEffect, useState, useRef } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { useAtom } from 'jotai'; import { Button, IconArrowLeft, IconCheck, IconForward, } from '@humansignal/ui'; import { getTask, getProject, createAnnotation, updateTask } from '../../services/api'; import { currentTaskAtom } from '../../atoms/task-atoms'; import { currentProjectAtom } from '../../atoms/project-atoms'; export const AnnotationView: React.FC = () => { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const [currentTask, setCurrentTask] = useAtom(currentTaskAtom); const [currentProject, setCurrentProject] = useAtom(currentProjectAtom); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [isSaving, setIsSaving] = useState(false); const editorContainerRef = useRef(null); // Load task and project data useEffect(() => { if (!id) return; const loadData = async () => { try { setLoading(true); setError(null); // Load task details const taskData = await getTask(id); setCurrentTask(taskData); // Load project details to get annotation config const projectData = await getProject(taskData.project_id); setCurrentProject(projectData); } catch (err: any) { setError(err.message || '加载任务失败'); } finally { setLoading(false); } }; loadData(); }, [id]); const handleSave = async () => { if (!currentTask || !id) return; try { setIsSaving(true); // TODO: Get annotation result from LabelStudio editor const annotationResult = {}; // Create annotation await createAnnotation({ task_id: id, user_id: 'current_user', // TODO: Get from auth context result: annotationResult, }); // Update task status to in_progress or completed await updateTask(id, { status: 'in_progress', }); // Navigate back to tasks list navigate('/tasks'); } catch (err: any) { setError(err.message || '保存标注失败'); } finally { setIsSaving(false); } }; const handleSkip = () => { // Navigate back to tasks list without saving navigate('/tasks'); }; if (loading) { return (

加载中...

); } if (error) { return (
加载失败 {error}
); } if (!currentTask || !currentProject) { return (

任务不存在

); } return (
{/* Header */}

{currentTask.name}

项目: {currentProject.name} | 进度: {currentTask.progress}%

{/* Editor Container */}
{/* LabelStudio editor will be mounted here */}

标注编辑器

LabelStudio 编辑器将在此处加载

任务数据:

                  {JSON.stringify(currentTask.data, null, 2)}
                
); };