diff --git a/frontend/src/pages/DataAnnotation/Create/components/CreateAnnotationTaskDialog.tsx b/frontend/src/pages/DataAnnotation/Create/components/CreateAnnotationTaskDialog.tsx index bef90ec..0abdc4c 100644 --- a/frontend/src/pages/DataAnnotation/Create/components/CreateAnnotationTaskDialog.tsx +++ b/frontend/src/pages/DataAnnotation/Create/components/CreateAnnotationTaskDialog.tsx @@ -1,8 +1,9 @@ -import { queryDatasetsUsingGet } from "@/pages/DataManagement/dataset.api"; +import { queryDatasetsUsingGet, previewDatasetUsingGet } from "@/pages/DataManagement/dataset.api"; import { mapDataset } from "@/pages/DataManagement/dataset.const"; -import { Button, Form, Input, Modal, Select, message, Tabs, Radio } from "antd"; +import { Button, Form, Input, Modal, Select, message, Radio, Table } from "antd"; import TextArea from "antd/es/input/TextArea"; import { useEffect, useState } from "react"; +import { Eye } from "lucide-react"; import { createAnnotationTaskUsingPost, queryAnnotationTemplatesUsingGet, @@ -32,10 +33,15 @@ export default function CreateAnnotationTask({ const [showPreview, setShowPreview] = useState(false); const [previewTaskData, setPreviewTaskData] = useState>({}); const [configMode, setConfigMode] = useState<"template" | "custom">("template"); - const [templateEditTab, setTemplateEditTab] = useState<"visual" | "xml">("visual"); // 是否已选择模板(用于启用受限编辑模式) const [hasSelectedTemplate, setHasSelectedTemplate] = useState(false); + // 数据集预览相关状态 + const [datasetPreviewVisible, setDatasetPreviewVisible] = useState(false); + const [datasetPreviewData, setDatasetPreviewData] = useState([]); + const [datasetPreviewLoading, setDatasetPreviewLoading] = useState(false); + const [selectedDatasetId, setSelectedDatasetId] = useState(null); + useEffect(() => { if (!open) return; const fetchData = async () => { @@ -77,11 +83,35 @@ export default function CreateAnnotationTask({ setShowPreview(false); setPreviewTaskData({}); setConfigMode("template"); - setTemplateEditTab("visual"); setHasSelectedTemplate(false); + setSelectedDatasetId(null); + setDatasetPreviewData([]); } }, [open, manualForm]); + // 预览数据集 + const handlePreviewDataset = async () => { + if (!selectedDatasetId) { + message.warning("请先选择数据集"); + return; + } + setDatasetPreviewLoading(true); + try { + const res = await previewDatasetUsingGet(selectedDatasetId, { limit: 10 }); + if (res.code === 200 && res.data) { + setDatasetPreviewData(res.data || []); + setDatasetPreviewVisible(true); + } else { + message.error("获取数据集预览失败"); + } + } catch (error) { + console.error("Preview dataset error:", error); + message.error("获取数据集预览失败"); + } finally { + setDatasetPreviewLoading(false); + } + }; + const generateXmlFromConfig = (objects: any[], labels: any[]) => { let xml = '\n'; @@ -118,16 +148,6 @@ export default function CreateAnnotationTask({ return xml; }; - // 从表单值同步生成 XML - const syncFormToXml = () => { - const objects = manualForm.getFieldValue("objects"); - const labels = manualForm.getFieldValue("labels"); - if (objects && objects.length > 0) { - const xml = generateXmlFromConfig(objects, labels || []); - setCustomXml(xml); - } - }; - // 根据 objects 配置生成预览用的示例数据 const generateExampleData = (objects: any[]) => { const exampleUrls: Record = { @@ -307,7 +327,22 @@ export default function CreateAnnotationTask({ {/* 数据集 与 标注工程名称 并排显示(数据集在左) */}
+ 数据集 + +
+ } name="datasetId" rules={[{ required: true, message: "请选择数据集" }]} > @@ -328,6 +363,7 @@ export default function CreateAnnotationTask({ }; })} onChange={(value) => { + setSelectedDatasetId(value); // 如果用户未手动修改名称,则用数据集名称作为默认任务名 if (!nameManuallyEdited) { const ds = datasets.find((d) => d.id === value); @@ -442,53 +478,12 @@ export default function CreateAnnotationTask({ /> - { - // 切换到 XML 时,从表单同步生成 XML - if (key === "xml") { - syncFormToXml(); - } - setTemplateEditTab(key as "visual" | "xml"); - }} - size="small" - items={[ - { - key: "visual", - label: "可视化配置", - children: ( -
- -
- ), - }, - { - key: "xml", - label: hasSelectedTemplate ? "XML配置(只读)" : "XML编辑器(高级)", - children: ( -
-
- {hasSelectedTemplate - ? "基于模板创建时,XML 配置为只读。如需完全自定义,请切换'自定义配置'模式。" - : "直接编辑 Label Studio XML 配置。注意:在此修改后切换回可视化配置可能会丢失部分高级设置。" - } -
-