You've already forked DataMate
Merge branch 'ModelEngine-Group:main' into develop_label_tool
This commit is contained in:
@@ -168,12 +168,12 @@ function CardView<T extends BaseCardDataType>(props: CardViewProps<T>) {
|
|||||||
const ops = (item) =>
|
const ops = (item) =>
|
||||||
typeof operations === "function" ? operations(item) : operations;
|
typeof operations === "function" ? operations(item) : operations;
|
||||||
return (
|
return (
|
||||||
<div className="flex-1 flex flex-col overflow-auto">
|
<div className="flex-overflow-hidden">
|
||||||
<div className="overflow-auto grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 gap-4">
|
<div className="flex-overflow-auto grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 gap-4">
|
||||||
{data.map((item) => (
|
{data.map((item) => (
|
||||||
<div
|
<div
|
||||||
key={item.id}
|
key={item.id}
|
||||||
className="border border-gray-100 rounded-lg p-4 bg-white hover:shadow-lg transition-shadow duration-200"
|
className="border-card p-4 bg-white hover:shadow-lg transition-shadow duration-200"
|
||||||
>
|
>
|
||||||
<div className="flex flex-col space-y-4 h-full">
|
<div className="flex flex-col space-y-4 h-full">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ function DetailHeader<T>({
|
|||||||
<div className="flex items-start justify-between">
|
<div className="flex items-start justify-between">
|
||||||
<div className="flex items-start gap-4 flex-1">
|
<div className="flex items-start gap-4 flex-1">
|
||||||
<div
|
<div
|
||||||
className={`w-16 h-16 text-white rounded-xl flex items-center justify-center shadow-lg ${
|
className={`w-16 h-16 text-white rounded-lg flex-center shadow-lg ${
|
||||||
data?.iconColor
|
data?.iconColor
|
||||||
? data.iconColor
|
? data.iconColor
|
||||||
: "bg-gradient-to-br from-blue-100 to-blue-200"
|
: "bg-gradient-to-br from-blue-100 to-blue-200"
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import { Button } from "antd";
|
import { Button } from "antd";
|
||||||
|
const DevelopmentInProgress = ({ showHome = true, showTime = "" }) => {
|
||||||
const DevelopmentInProgress = ({ showHome = true }) => {
|
|
||||||
return (
|
return (
|
||||||
<div className="mt-40 flex flex-col items-center justify-center">
|
<div className="mt-40 flex flex-col items-center justify-center">
|
||||||
<div className="hero-icon">🚧</div>
|
<div className="hero-icon">🚧</div>
|
||||||
<h1 className="text-2xl font-bold">功能开发中</h1>
|
<h1 className="text-2xl font-bold">功能开发中</h1>
|
||||||
<p className="mt-4">
|
{showTime && (
|
||||||
为了给您带来更好的体验,我们计划<b>2025.10.30</b>
|
<p className="mt-4">
|
||||||
开放此功能
|
为了给您带来更好的体验,我们计划<b>{showTime}</b>
|
||||||
</p>
|
开放此功能
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
{showHome && (
|
{showHome && (
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const RadioCard: React.FC<RadioCardProps> = ({
|
|||||||
{options.map((option) => (
|
{options.map((option) => (
|
||||||
<div
|
<div
|
||||||
key={option.value}
|
key={option.value}
|
||||||
className="border border-gray-200 rounded-lg hover:shadow-lg p-4 text-center"
|
className="border-card hover:shadow-lg p-4 text-center"
|
||||||
style={{
|
style={{
|
||||||
borderColor: value === option.value ? "#1677ff" : undefined,
|
borderColor: value === option.value ? "#1677ff" : undefined,
|
||||||
background: value === option.value ? "#e6f7ff" : undefined,
|
background: value === option.value ? "#e6f7ff" : undefined,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ function CustomTag({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={tag.id}
|
key={tag.id}
|
||||||
className="flex items-center justify-between px-4 py-2 border border-gray-100 rounded-md hover:bg-gray-50"
|
className="flex items-center justify-between px-4 py-2 border-card hover:bg-gray-50"
|
||||||
>
|
>
|
||||||
{editingTag?.id === tag.id ? (
|
{editingTag?.id === tag.id ? (
|
||||||
<div className="flex gap-2 flex-1">
|
<div className="flex gap-2 flex-1">
|
||||||
@@ -92,17 +92,6 @@ function CustomTag({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mockPreparedTags = [
|
|
||||||
{ id: "1", name: "重要" },
|
|
||||||
{ id: "2", name: "待处理" },
|
|
||||||
{ id: "3", name: "已完成" },
|
|
||||||
{ id: "4", name: "审核中" },
|
|
||||||
{ id: "5", name: "高优先级" },
|
|
||||||
{ id: "6", name: "低优先级" },
|
|
||||||
{ id: "7", name: "客户A" },
|
|
||||||
{ id: "8", name: "客户B" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const TagManager: React.FC = ({
|
const TagManager: React.FC = ({
|
||||||
onFetch,
|
onFetch,
|
||||||
onCreate,
|
onCreate,
|
||||||
@@ -112,7 +101,7 @@ const TagManager: React.FC = ({
|
|||||||
onFetch: () => Promise<any>;
|
onFetch: () => Promise<any>;
|
||||||
onCreate: (tag: Pick<TagItem, "name">) => Promise<{ ok: boolean }>;
|
onCreate: (tag: Pick<TagItem, "name">) => Promise<{ ok: boolean }>;
|
||||||
onDelete: (tagId: number) => Promise<{ ok: boolean }>;
|
onDelete: (tagId: number) => Promise<{ ok: boolean }>;
|
||||||
onUpdate: (oldTagId: number, newTag: string) => Promise<{ ok: boolean }>;
|
onUpdate: (tag: TagItem) => Promise<{ ok: boolean }>;
|
||||||
}) => {
|
}) => {
|
||||||
const [showTagManager, setShowTagManager] = useState(false);
|
const [showTagManager, setShowTagManager] = useState(false);
|
||||||
const { message } = App.useApp();
|
const { message } = App.useApp();
|
||||||
@@ -121,9 +110,6 @@ const TagManager: React.FC = ({
|
|||||||
const [editingTag, setEditingTag] = useState<string | null>(null);
|
const [editingTag, setEditingTag] = useState<string | null>(null);
|
||||||
const [editingTagValue, setEditingTagValue] = useState("");
|
const [editingTagValue, setEditingTagValue] = useState("");
|
||||||
|
|
||||||
// 预置标签
|
|
||||||
const [preparedTags, setPreparedTags] = useState(mockPreparedTags);
|
|
||||||
|
|
||||||
// 获取标签列表
|
// 获取标签列表
|
||||||
const fetchTags = async () => {
|
const fetchTags = async () => {
|
||||||
if (!onFetch) return;
|
if (!onFetch) return;
|
||||||
@@ -161,7 +147,7 @@ const TagManager: React.FC = ({
|
|||||||
|
|
||||||
const updateTag = async (oldTag: TagItem, newTag: string) => {
|
const updateTag = async (oldTag: TagItem, newTag: string) => {
|
||||||
try {
|
try {
|
||||||
await onUpdate?.(oldTag.id, { ...oldTag, name: newTag });
|
await onUpdate?.({ ...oldTag, name: newTag });
|
||||||
fetchTags();
|
fetchTags();
|
||||||
message.success("标签更新成功");
|
message.success("标签更新成功");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -213,55 +199,48 @@ const TagManager: React.FC = ({
|
|||||||
title="标签管理"
|
title="标签管理"
|
||||||
width={500}
|
width={500}
|
||||||
>
|
>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4 flex-overflow">
|
||||||
{/* Add New Tag */}
|
{/* Add New Tag */}
|
||||||
<div className="space-y-2">
|
<div className="flex gap-2">
|
||||||
<div className="flex gap-2">
|
<Input
|
||||||
<Input
|
placeholder="输入标签名称..."
|
||||||
placeholder="输入标签名称..."
|
value={newTag}
|
||||||
value={newTag}
|
allowClear
|
||||||
allowClear
|
onChange={(e) => setNewTag(e.target.value)}
|
||||||
onChange={(e) => setNewTag(e.target.value)}
|
onKeyPress={(e) => {
|
||||||
onKeyPress={(e) => {
|
if (e.key === "Enter") {
|
||||||
if (e.key === "Enter") {
|
addTag(e.target.value);
|
||||||
addTag(e.target.value);
|
}
|
||||||
}
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
<Button
|
||||||
<Button
|
type="primary"
|
||||||
type="primary"
|
onClick={handleCreateNewTag}
|
||||||
onClick={handleCreateNewTag}
|
disabled={!newTag.trim()}
|
||||||
disabled={!newTag.trim()}
|
icon={<PlusOutlined />}
|
||||||
icon={<PlusOutlined />}
|
>
|
||||||
>
|
添加
|
||||||
添加
|
</Button>
|
||||||
</Button>
|
</div>
|
||||||
|
|
||||||
|
<div className="flex-overflow">
|
||||||
|
<div className="overflow-auto grid grid-cols-2 gap-2">
|
||||||
|
{tags.map((tag) => (
|
||||||
|
<CustomTag
|
||||||
|
isEditable
|
||||||
|
key={tag.id}
|
||||||
|
tag={tag}
|
||||||
|
editingTag={editingTag}
|
||||||
|
editingTagValue={editingTagValue}
|
||||||
|
setEditingTag={setEditingTag}
|
||||||
|
setEditingTagValue={setEditingTagValue}
|
||||||
|
handleEditTag={handleEditTag}
|
||||||
|
handleCancelEdit={handleCancelEdit}
|
||||||
|
handleDeleteTag={handleDeleteTag}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 className="font-large font-bold w-full">预置标签</h2>
|
|
||||||
<div className="grid grid-cols-2 gap-2">
|
|
||||||
{preparedTags.length > 0 &&
|
|
||||||
preparedTags.map((tag) => <CustomTag key={tag.id} tag={tag} />)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2 className="font-large font-bold w-full">自定义标签</h2>
|
|
||||||
<div className="grid grid-cols-2 gap-2 mt-4">
|
|
||||||
{tags.map((tag) => (
|
|
||||||
<CustomTag
|
|
||||||
isEditable
|
|
||||||
key={tag.id}
|
|
||||||
tag={tag}
|
|
||||||
editingTag={editingTag}
|
|
||||||
editingTagValue={editingTagValue}
|
|
||||||
setEditingTag={setEditingTag}
|
|
||||||
setEditingTagValue={setEditingTagValue}
|
|
||||||
handleEditTag={handleEditTag}
|
|
||||||
handleCancelEdit={handleCancelEdit}
|
|
||||||
handleDeleteTag={handleDeleteTag}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export default function TaskPopover() {
|
|||||||
{tasks.map((task) => (
|
{tasks.map((task) => (
|
||||||
<div
|
<div
|
||||||
key={task.id}
|
key={task.id}
|
||||||
className="p-3 border border-gray-100 rounded-lg hover:bg-gray-50"
|
className="p-3 border-card hover:bg-gray-50"
|
||||||
>
|
>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
|
|||||||
@@ -43,3 +43,27 @@
|
|||||||
visibility: visible;
|
visibility: visible;
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
.flex-center {
|
||||||
|
@apply flex items-center justify-center;
|
||||||
|
}
|
||||||
|
.flex-overflow-auto {
|
||||||
|
@apply flex-1 flex flex-col overflow-auto h-full;
|
||||||
|
}
|
||||||
|
.flex-overflow-hidden {
|
||||||
|
@apply flex flex-col h-full overflow-hidden;
|
||||||
|
}
|
||||||
|
.border-card {
|
||||||
|
@apply border border-[#f0f0f0] rounded-lg bg-white;
|
||||||
|
}
|
||||||
|
.border {
|
||||||
|
@apply border border-gray-100;
|
||||||
|
}
|
||||||
|
.border-bottom {
|
||||||
|
@apply border-b border-gray-100;
|
||||||
|
}
|
||||||
|
.border-top {
|
||||||
|
@apply border-t border-gray-100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -429,7 +429,7 @@ export default function ImageAnnotationWorkspace({
|
|||||||
}`}
|
}`}
|
||||||
onClick={() => setSelectedImageIndex(index)}
|
onClick={() => setSelectedImageIndex(index)}
|
||||||
>
|
>
|
||||||
<div className="w-8 h-8 bg-gray-200 rounded flex items-center justify-center text-sm font-medium mr-3">
|
<div className="w-8 h-8 bg-gray-200 rounded flex-center text-sm font-medium mr-3">
|
||||||
{index + 1}
|
{index + 1}
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
@@ -462,7 +462,7 @@ export default function ImageAnnotationWorkspace({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-1 border rounded-lg overflow-hidden bg-gray-100 relative">
|
<div className="flex-1 border-card overflow-hidden bg-gray-100 relative">
|
||||||
<canvas
|
<canvas
|
||||||
ref={canvasRef}
|
ref={canvasRef}
|
||||||
width={800}
|
width={800}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export default function AnnotationTaskCreate() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full flex flex-col overflow-auto">
|
<div className="flex-overflow-auto">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex items-center mb-2">
|
<div className="flex items-center mb-2">
|
||||||
<Link to="/data/annotation">
|
<Link to="/data/annotation">
|
||||||
@@ -134,7 +134,7 @@ export default function AnnotationTaskCreate() {
|
|||||||
<h1 className="text-xl font-bold bg-clip-text">创建标注任务</h1>
|
<h1 className="text-xl font-bold bg-clip-text">创建标注任务</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="h-full flex-1 overflow-y-auto flex flex-col bg-white rounded-lg shadow-sm">
|
<div className="flex-overflow-auto bg-white rounded-lg shadow-sm">
|
||||||
<div className="flex-1 overflow-y-auto p-6">
|
<div className="flex-1 overflow-y-auto p-6">
|
||||||
<Form
|
<Form
|
||||||
form={form}
|
form={form}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { queryDatasetsUsingGet } from "@/pages/DataManagement/dataset.api";
|
import { queryDatasetsUsingGet } from "@/pages/DataManagement/dataset.api";
|
||||||
import { datasetTypeMap } from "@/pages/DataManagement/dataset.const";
|
import {
|
||||||
|
datasetTypeMap,
|
||||||
|
mapDataset,
|
||||||
|
} from "@/pages/DataManagement/dataset.const";
|
||||||
import { Button, Form, Input, Modal, Select } from "antd";
|
import { Button, Form, Input, Modal, Select } from "antd";
|
||||||
import TextArea from "antd/es/input/TextArea";
|
import TextArea from "antd/es/input/TextArea";
|
||||||
import { Database } from "lucide-react";
|
import { Database } from "lucide-react";
|
||||||
@@ -26,7 +29,7 @@ export default function CreateAnnotationTask({
|
|||||||
page: 0,
|
page: 0,
|
||||||
size: 1000,
|
size: 1000,
|
||||||
});
|
});
|
||||||
setDatasets(data.content || []);
|
setDatasets(data.content.map(mapDataset) || []);
|
||||||
};
|
};
|
||||||
fetchDatasets();
|
fetchDatasets();
|
||||||
}, [open]);
|
}, [open]);
|
||||||
@@ -74,22 +77,20 @@ export default function CreateAnnotationTask({
|
|||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
placeholder="请选择数据集"
|
placeholder="请选择数据集"
|
||||||
options={datasets.map((dataset) => ({
|
options={datasets.map((dataset) => {
|
||||||
label: (
|
return {
|
||||||
<div className="flex items-center justify-between gap-3 py-2">
|
label: (
|
||||||
<div className="flex items-center font-sm text-gray-900">
|
<div className="flex items-center justify-between gap-3 py-2">
|
||||||
<span>
|
<div className="flex items-center font-sm text-gray-900">
|
||||||
{dataset.icon || <Database className="w-4 h-4 mr-2" />}
|
<span className="mr-2">{dataset.icon}</span>
|
||||||
</span>
|
<span>{dataset.name}</span>
|
||||||
<span>{dataset.name}</span>
|
</div>
|
||||||
|
<div className="text-xs text-gray-500">{dataset.size}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-gray-500">
|
),
|
||||||
{datasetTypeMap[dataset?.datasetType]?.label}
|
value: dataset.id,
|
||||||
</div>
|
};
|
||||||
</div>
|
})}
|
||||||
),
|
|
||||||
value: dataset.id,
|
|
||||||
}))}
|
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
@@ -19,8 +19,10 @@ import {
|
|||||||
import { mapAnnotationTask } from "../annotation.const";
|
import { mapAnnotationTask } from "../annotation.const";
|
||||||
import CreateAnnotationTask from "../Create/components/CreateAnnptationTaskDialog";
|
import CreateAnnotationTask from "../Create/components/CreateAnnptationTaskDialog";
|
||||||
import { ColumnType } from "antd/es/table";
|
import { ColumnType } from "antd/es/table";
|
||||||
|
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
||||||
|
|
||||||
export default function DataAnnotation() {
|
export default function DataAnnotation() {
|
||||||
|
return <DevelopmentInProgress showTime="2025.10.30" />;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [viewMode, setViewMode] = useState<"list" | "card">("list");
|
const [viewMode, setViewMode] = useState<"list" | "card">("list");
|
||||||
const [showCreateDialog, setShowCreateDialog] = useState(false);
|
const [showCreateDialog, setShowCreateDialog] = useState(false);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { get, post, put, del, download } from "@/utils/request";
|
|||||||
|
|
||||||
// 标注任务管理相关接口
|
// 标注任务管理相关接口
|
||||||
export function queryAnnotationTasksUsingGet(params?: any) {
|
export function queryAnnotationTasksUsingGet(params?: any) {
|
||||||
return get("/api/project/mappings/list", params);
|
return get("/project/mappings/list", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createAnnotationTaskUsingPost(data: any) {
|
export function createAnnotationTaskUsingPost(data: any) {
|
||||||
|
|||||||
@@ -101,9 +101,9 @@ export default function CleansingTaskCreate() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Step Content */}
|
{/* Step Content */}
|
||||||
<div className="h-full mb-4 flex flex-col overflow-auto flex-1 bg-white rounded shadow-sm">
|
<div className="flex-overflow-auto bg-white border-card">
|
||||||
<div className="flex-1 overflow-auto m-6">{renderStepContent()}</div>
|
<div className="flex-1 overflow-auto m-6">{renderStepContent()}</div>
|
||||||
<div className="flex justify-end p-6 gap-3 border-t border-gray-200">
|
<div className="flex justify-end p-6 gap-3 border-top">
|
||||||
<Button onClick={() => navigate("/data/cleansing")}>取消</Button>
|
<Button onClick={() => navigate("/data/cleansing")}>取消</Button>
|
||||||
{currentStep > 1 && <Button onClick={handlePrev}>上一步</Button>}
|
{currentStep > 1 && <Button onClick={handlePrev}>上一步</Button>}
|
||||||
{currentStep === 2 ? (
|
{currentStep === 2 ? (
|
||||||
|
|||||||
@@ -90,9 +90,9 @@ export default function CleansingTemplateCreate() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="h-full mb-4 flex flex-col overflow-auto flex-1 bg-white rounded shadow-sm">
|
<div className="flex-overflow-auto border-card">
|
||||||
<div className="flex-1 overflow-auto m-6">{renderStepContent()}</div>
|
<div className="flex-1 overflow-auto m-6">{renderStepContent()}</div>
|
||||||
<div className="flex justify-end p-6 gap-3 border-t border-gray-200">
|
<div className="flex justify-end p-6 gap-3 border-top">
|
||||||
<Button onClick={() => navigate("/data/cleansing")}>取消</Button>
|
<Button onClick={() => navigate("/data/cleansing")}>取消</Button>
|
||||||
{currentStep > 1 && <Button onClick={handlePrev}>上一步</Button>}
|
{currentStep > 1 && <Button onClick={handlePrev}>上一步</Button>}
|
||||||
{currentStep === 2 ? (
|
{currentStep === 2 ? (
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { queryDatasetsUsingGet } from "@/pages/DataManagement/dataset.api";
|
|||||||
import {
|
import {
|
||||||
datasetTypeMap,
|
datasetTypeMap,
|
||||||
datasetTypes,
|
datasetTypes,
|
||||||
|
mapDataset,
|
||||||
} from "@/pages/DataManagement/dataset.const";
|
} from "@/pages/DataManagement/dataset.const";
|
||||||
import {
|
import {
|
||||||
Dataset,
|
Dataset,
|
||||||
@@ -34,7 +35,7 @@ export default function CreateTaskStepOne({
|
|||||||
|
|
||||||
const fetchDatasets = async () => {
|
const fetchDatasets = async () => {
|
||||||
const { data } = await queryDatasetsUsingGet({ page: 0, size: 1000 });
|
const { data } = await queryDatasetsUsingGet({ page: 0, size: 1000 });
|
||||||
setDatasets(data.content || []);
|
setDatasets(data.content.map(mapDataset) || []);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -76,22 +77,20 @@ export default function CreateTaskStepOne({
|
|||||||
<Form.Item label="源数据集" name="srcDatasetId" required>
|
<Form.Item label="源数据集" name="srcDatasetId" required>
|
||||||
<Select
|
<Select
|
||||||
placeholder="请选择源数据集"
|
placeholder="请选择源数据集"
|
||||||
options={datasets.map((dataset) => ({
|
options={datasets.map((dataset) => {
|
||||||
label: (
|
return {
|
||||||
<div className="flex items-center justify-between gap-3 py-2">
|
label: (
|
||||||
<div className="flex items-center font-sm text-gray-900">
|
<div className="flex items-center justify-between gap-3 py-2">
|
||||||
<span>
|
<div className="flex items-center font-sm text-gray-900">
|
||||||
{dataset.icon || <Database className="w-4 h-4 mr-2" />}
|
<span className="mr-2">{dataset.icon}</span>
|
||||||
</span>
|
<span>{dataset.name}</span>
|
||||||
<span>{dataset.name}</span>
|
</div>
|
||||||
|
<div className="text-xs text-gray-500">{dataset.size}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-gray-500">
|
),
|
||||||
{datasetTypeMap[dataset?.datasetType]?.label}
|
value: dataset.id,
|
||||||
</div>
|
};
|
||||||
</div>
|
})}
|
||||||
),
|
|
||||||
value: dataset.id,
|
|
||||||
}))}
|
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="目标数据集名称" name="destDatasetName" required>
|
<Form.Item label="目标数据集名称" name="destDatasetName" required>
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ const OperatorFlow: React.FC<OperatorFlowProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
{/* 编排区域 */}
|
{/* 编排区域 */}
|
||||||
<div
|
<div
|
||||||
className="flex-1 overflow-auto p-4 flex flex-col gap-2"
|
className="flex-overflow-auto p-4 gap-2"
|
||||||
onDragOver={(e) => e.preventDefault()}
|
onDragOver={(e) => e.preventDefault()}
|
||||||
onDragLeave={handleContainerDragLeave}
|
onDragLeave={handleContainerDragLeave}
|
||||||
onDrop={handleDropToContainer}
|
onDrop={handleDropToContainer}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export default function ProcessFlowDiagram() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rounded-xl border border-gray-200 p-6 bg-white">
|
<div className="border-card p-6">
|
||||||
<div className="w-full flex items-center justify-center">
|
<div className="w-full flex items-center justify-center">
|
||||||
<div className="w-full flex items-center space-x-12">
|
<div className="w-full flex items-center space-x-12">
|
||||||
{flowSteps.map((step, index) => {
|
{flowSteps.map((step, index) => {
|
||||||
|
|||||||
@@ -16,7 +16,11 @@ export interface CleansingTask {
|
|||||||
color: string;
|
color: string;
|
||||||
};
|
};
|
||||||
startedAt: string;
|
startedAt: string;
|
||||||
progress: number;
|
progress: {
|
||||||
|
finishedFileNum: number;
|
||||||
|
process: 100,
|
||||||
|
totalFileNum: number;
|
||||||
|
};
|
||||||
operators: OperatorI[];
|
operators: OperatorI[];
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ const defaultTemplates = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export default function CollectionTaskCreate() {
|
export default function CollectionTaskCreate() {
|
||||||
return <DevelopmentInProgress />;
|
return <DevelopmentInProgress showTime="2025.10.30" />;
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export default function DataCollection() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [activeTab, setActiveTab] = useState("task-management");
|
const [activeTab, setActiveTab] = useState("task-management");
|
||||||
|
|
||||||
return <DevelopmentInProgress />;
|
return <DevelopmentInProgress showTime="2025.10.30" />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -180,9 +180,7 @@ export default function DataEvaluationPage() {
|
|||||||
setTasks(tasks.filter((task) => task.id !== taskId));
|
setTasks(tasks.filter((task) => task.id !== taskId));
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return <DevelopmentInProgress showTime="2025.11.30" />;
|
||||||
<DevelopmentInProgress />
|
|
||||||
);
|
|
||||||
// 主列表界面
|
// 主列表界面
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export default function DatasetCreate() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* form */}
|
{/* form */}
|
||||||
<div className="h-full flex flex-col flex-1 overflow-auto bg-white border-gray-200 rounded shadow-sm">
|
<div className="flex-overflow-auto border-card">
|
||||||
<div className="flex-1 p-6 overflow-auto">
|
<div className="flex-1 p-6 overflow-auto">
|
||||||
<Form
|
<Form
|
||||||
form={form}
|
form={form}
|
||||||
@@ -67,7 +67,7 @@ export default function DatasetCreate() {
|
|||||||
<BasicInformation data={newDataset} setData={setNewDataset} />
|
<BasicInformation data={newDataset} setData={setNewDataset} />
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2 justify-end p-6 border-t border-gray-200">
|
<div className="flex gap-2 justify-end p-6 border-top">
|
||||||
<Button onClick={() => navigate("/data/management")}>取消</Button>
|
<Button onClick={() => navigate("/data/management")}>取消</Button>
|
||||||
<Button type="primary" onClick={handleSubmit}>
|
<Button type="primary" onClick={handleSubmit}>
|
||||||
确定
|
确定
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import RadioCard from "@/components/RadioCard";
|
|||||||
import { Input, Select, Form } from "antd";
|
import { Input, Select, Form } from "antd";
|
||||||
import { datasetTypes } from "../../dataset.const";
|
import { datasetTypes } from "../../dataset.const";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { mockPreparedTags } from "@/components/TagManagement";
|
|
||||||
import { queryDatasetTagsUsingGet } from "../../dataset.api";
|
import { queryDatasetTagsUsingGet } from "../../dataset.api";
|
||||||
|
|
||||||
export default function BasicInformation({
|
export default function BasicInformation({
|
||||||
@@ -26,26 +25,11 @@ export default function BasicInformation({
|
|||||||
const fetchTags = async () => {
|
const fetchTags = async () => {
|
||||||
try {
|
try {
|
||||||
const { data } = await queryDatasetTagsUsingGet();
|
const { data } = await queryDatasetTagsUsingGet();
|
||||||
const preparedTags = mockPreparedTags.map((tag) => ({
|
|
||||||
label: tag.name,
|
|
||||||
value: tag.name,
|
|
||||||
}));
|
|
||||||
const customTags = data.map((tag) => ({
|
const customTags = data.map((tag) => ({
|
||||||
label: tag.name,
|
label: tag.name,
|
||||||
value: tag.name,
|
value: tag.name,
|
||||||
}));
|
}));
|
||||||
setTagOptions([
|
setTagOptions(customTags);
|
||||||
{
|
|
||||||
label: <span>预置标签</span>,
|
|
||||||
title: "prepared",
|
|
||||||
options: preparedTags,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: <span>自定义标签</span>,
|
|
||||||
title: "custom",
|
|
||||||
options: customTags,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching tags: ", error);
|
console.error("Error fetching tags: ", error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ export default function DatasetDetail() {
|
|||||||
{
|
{
|
||||||
icon: <Clock className="text-blue-400 w-4 h-4" />,
|
icon: <Clock className="text-blue-400 w-4 h-4" />,
|
||||||
key: "time",
|
key: "time",
|
||||||
value: dataset?.createdAt,
|
value: dataset?.updatedAt,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ export default function DatasetDetail() {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="h-full flex flex-col flex-1 overflow-auto p-6 pt-2 bg-white rounded-md shadow">
|
<div className="flex-overflow-auto p-6 pt-2 bg-white rounded-md shadow">
|
||||||
<Tabs activeKey={activeTab} items={tabList} onChange={setActiveTab} />
|
<Tabs activeKey={activeTab} items={tabList} onChange={setActiveTab} />
|
||||||
<div className="h-full overflow-auto">
|
<div className="h-full overflow-auto">
|
||||||
{activeTab === "overview" && (
|
{activeTab === "overview" && (
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import {
|
|||||||
deleteDatasetByIdUsingDelete,
|
deleteDatasetByIdUsingDelete,
|
||||||
createDatasetTagUsingPost,
|
createDatasetTagUsingPost,
|
||||||
queryDatasetTagsUsingGet,
|
queryDatasetTagsUsingGet,
|
||||||
updateDatasetTagByIdUsingPut,
|
deleteDatasetTagUsingDelete,
|
||||||
deleteDatasetTagByIdUsingDelete,
|
updateDatasetTagUsingPut,
|
||||||
} from "../dataset.api";
|
} from "../dataset.api";
|
||||||
import { formatBytes } from "@/utils/unit";
|
import { formatBytes } from "@/utils/unit";
|
||||||
import EditDataset from "../Create/EditDataset";
|
import EditDataset from "../Create/EditDataset";
|
||||||
@@ -295,8 +295,8 @@ export default function DatasetManagementPage() {
|
|||||||
{/* tasks */}
|
{/* tasks */}
|
||||||
<TagManager
|
<TagManager
|
||||||
onCreate={createDatasetTagUsingPost}
|
onCreate={createDatasetTagUsingPost}
|
||||||
onDelete={deleteDatasetTagByIdUsingDelete}
|
onDelete={(ids: string) => deleteDatasetTagUsingDelete({ ids })}
|
||||||
onUpdate={updateDatasetTagByIdUsingPut}
|
onUpdate={updateDatasetTagUsingPut}
|
||||||
onFetch={queryDatasetTagsUsingGet}
|
onFetch={queryDatasetTagsUsingGet}
|
||||||
/>
|
/>
|
||||||
<Link to="/data/management/create">
|
<Link to="/data/management/create">
|
||||||
|
|||||||
@@ -97,13 +97,13 @@ export function createDatasetTagUsingPost(data: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新数据集标签
|
// 更新数据集标签
|
||||||
export function updateDatasetTagByIdUsingPut(id: string | number, data: any) {
|
export function updateDatasetTagUsingPut(data: any) {
|
||||||
return put(`/api/data-management/tags/${id}`, data);
|
return put(`/api/data-management/tags`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除数据集标签
|
// 删除数据集标签
|
||||||
export function deleteDatasetTagByIdUsingDelete(id: string | number) {
|
export function deleteDatasetTagUsingDelete(data: any) {
|
||||||
return del(`/api/data-management/tags/${id}`);
|
return del(`/api/data-management/tags`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据集质量检查
|
// 数据集质量检查
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import {
|
|||||||
Music,
|
Music,
|
||||||
Videotape,
|
Videotape,
|
||||||
Database,
|
Database,
|
||||||
|
Image,
|
||||||
|
ScanText,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
|
||||||
export const datasetTypeMap: Record<
|
export const datasetTypeMap: Record<
|
||||||
@@ -41,8 +43,8 @@ export const datasetTypeMap: Record<
|
|||||||
value: DatasetType.TEXT,
|
value: DatasetType.TEXT,
|
||||||
label: "文本",
|
label: "文本",
|
||||||
order: 1,
|
order: 1,
|
||||||
icon: FileText,
|
icon: ScanText,
|
||||||
iconColor: "#3b82f6",
|
iconColor: "blue",
|
||||||
children: [
|
children: [
|
||||||
DatasetSubType.TEXT_DOCUMENT,
|
DatasetSubType.TEXT_DOCUMENT,
|
||||||
DatasetSubType.TEXT_WEB,
|
DatasetSubType.TEXT_WEB,
|
||||||
@@ -54,8 +56,8 @@ export const datasetTypeMap: Record<
|
|||||||
value: DatasetType.IMAGE,
|
value: DatasetType.IMAGE,
|
||||||
label: "图像",
|
label: "图像",
|
||||||
order: 2,
|
order: 2,
|
||||||
icon: FileImage,
|
icon: Image,
|
||||||
iconColor: "#3b82f6",
|
iconColor: "green",
|
||||||
children: [DatasetSubType.IMAGE_IMAGE, DatasetSubType.IMAGE_CAPTION],
|
children: [DatasetSubType.IMAGE_IMAGE, DatasetSubType.IMAGE_CAPTION],
|
||||||
description: "用于处理和分析图像数据的数据集",
|
description: "用于处理和分析图像数据的数据集",
|
||||||
},
|
},
|
||||||
@@ -64,7 +66,7 @@ export const datasetTypeMap: Record<
|
|||||||
label: "音频",
|
label: "音频",
|
||||||
order: 3,
|
order: 3,
|
||||||
icon: Music,
|
icon: Music,
|
||||||
iconColor: "#3b82f6",
|
iconColor: "orange",
|
||||||
children: [DatasetSubType.AUDIO_AUDIO, DatasetSubType.AUDIO_JSONL],
|
children: [DatasetSubType.AUDIO_AUDIO, DatasetSubType.AUDIO_JSONL],
|
||||||
description: "用于处理和分析音频数据的数据集",
|
description: "用于处理和分析音频数据的数据集",
|
||||||
},
|
},
|
||||||
@@ -73,7 +75,7 @@ export const datasetTypeMap: Record<
|
|||||||
label: "视频",
|
label: "视频",
|
||||||
order: 3,
|
order: 3,
|
||||||
icon: Video,
|
icon: Video,
|
||||||
iconColor: "#3b82f6",
|
iconColor: "purple",
|
||||||
children: [DatasetSubType.VIDEO_VIDEO, DatasetSubType.VIDEO_JSONL],
|
children: [DatasetSubType.VIDEO_VIDEO, DatasetSubType.VIDEO_JSONL],
|
||||||
description: "用于处理和分析视频数据的数据集",
|
description: "用于处理和分析视频数据的数据集",
|
||||||
},
|
},
|
||||||
@@ -193,14 +195,22 @@ export const dataSourceMap: Record<string, { label: string; value: string }> = {
|
|||||||
export const dataSourceOptions = Object.values(dataSourceMap);
|
export const dataSourceOptions = Object.values(dataSourceMap);
|
||||||
|
|
||||||
export function mapDataset(dataset: Dataset) {
|
export function mapDataset(dataset: Dataset) {
|
||||||
const IconComponent = datasetTypeMap[dataset?.datasetType]?.icon || null;
|
const { icon: IconComponent, iconColor } =
|
||||||
|
datasetTypeMap[dataset?.datasetType] || {};
|
||||||
return {
|
return {
|
||||||
...dataset,
|
...dataset,
|
||||||
type: datasetTypeMap[dataset.datasetType]?.label || "未知",
|
type: datasetTypeMap[dataset.datasetType]?.label || "未知",
|
||||||
size: formatBytes(dataset.totalSize || 0),
|
size: formatBytes(dataset.totalSize || 0),
|
||||||
createdAt: formatDateTime(dataset.createdAt) || "--",
|
createdAt: formatDateTime(dataset.createdAt) || "--",
|
||||||
updatedAt: formatDateTime(dataset?.updatedAt) || "--",
|
updatedAt: formatDateTime(dataset?.updatedAt) || "--",
|
||||||
icon: IconComponent ? <IconComponent className="w-4 h-4" /> : <Database />,
|
icon: IconComponent ? (
|
||||||
|
<IconComponent
|
||||||
|
className="w-5 h-5 text-gray-500"
|
||||||
|
// style={{ color: iconColor }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Database />
|
||||||
|
),
|
||||||
status: datasetStatusMap[dataset.status],
|
status: datasetStatusMap[dataset.status],
|
||||||
statistics: [
|
statistics: [
|
||||||
{ label: "文件数", value: dataset.fileCount || 0 },
|
{ label: "文件数", value: dataset.fileCount || 0 },
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const { TextArea } = Input;
|
|||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
const KnowledgeBaseCreatePage: React.FC = () => {
|
const KnowledgeBaseCreatePage: React.FC = () => {
|
||||||
return <DevelopmentInProgress />;
|
return <DevelopmentInProgress showTime="2025.10.30" />;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [knowledgeBases, setKnowledgeBases] =
|
const [knowledgeBases, setKnowledgeBases] =
|
||||||
|
|||||||
@@ -11,22 +11,12 @@ import {
|
|||||||
FileText,
|
FileText,
|
||||||
Download,
|
Download,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import {
|
import { Card, Button, Badge, Input, Tabs, Modal, Breadcrumb, Tag } from "antd";
|
||||||
Card,
|
import { mockChunks, mockQAPairs, sliceOperators } from "@/mock/knowledgeBase";
|
||||||
Button,
|
import type {
|
||||||
Badge,
|
KnowledgeBase,
|
||||||
Input,
|
KBFile,
|
||||||
Tabs,
|
} from "@/pages/KnowledgeGeneration/knowledge-base.model";
|
||||||
Modal,
|
|
||||||
Breadcrumb,
|
|
||||||
Tag,
|
|
||||||
} from "antd";
|
|
||||||
import {
|
|
||||||
mockChunks,
|
|
||||||
mockQAPairs,
|
|
||||||
sliceOperators,
|
|
||||||
} from "@/mock/knowledgeBase";
|
|
||||||
import type { KnowledgeBase, KBFile } from "@/pages/KnowledgeGeneration/knowledge-base.model";
|
|
||||||
import { Link, useNavigate } from "react-router";
|
import { Link, useNavigate } from "react-router";
|
||||||
import DetailHeader from "@/components/DetailHeader";
|
import DetailHeader from "@/components/DetailHeader";
|
||||||
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
||||||
@@ -59,7 +49,7 @@ const getStatusColor = (status: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const KnowledgeBaseFileDetail: React.FC = () => {
|
const KnowledgeBaseFileDetail: React.FC = () => {
|
||||||
return <DevelopmentInProgress />;
|
return <DevelopmentInProgress showTime="2025.10.30" />;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
// 假设通过 props 或路由参数获取 selectedFile/selectedKB
|
// 假设通过 props 或路由参数获取 selectedFile/selectedKB
|
||||||
const [selectedFile] = useState<KBFile>(
|
const [selectedFile] = useState<KBFile>(
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import CardView from "@/components/CardView";
|
|||||||
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
||||||
|
|
||||||
export default function KnowledgeGenerationPage() {
|
export default function KnowledgeGenerationPage() {
|
||||||
return <DevelopmentInProgress />;
|
return <DevelopmentInProgress showTime="2025.10.30" />;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [knowledgeBases, setKnowledgeBases] =
|
const [knowledgeBases, setKnowledgeBases] =
|
||||||
useState<KnowledgeBase[]>(mockKnowledgeBases);
|
useState<KnowledgeBase[]>(mockKnowledgeBases);
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ const MainLayout = () => {
|
|||||||
{/* Sidebar */}
|
{/* Sidebar */}
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
<div className="flex-1 flex flex-col overflow-auto p-6">
|
<div className="flex-overflow-auto p-6">
|
||||||
{/* Content Area */}
|
{/* Content Area */}
|
||||||
<div className="flex-1 flex flex-col overflow-auto">
|
<div className="flex-overflow-auto">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { memo, useEffect, useState } from "react";
|
import { memo, useEffect, useState } from "react";
|
||||||
import { Button, Menu, Popover } from "antd";
|
import { Button, Menu, Popover } from "antd";
|
||||||
import {
|
import {
|
||||||
CloseOutlined,
|
CloseOutlined,
|
||||||
@@ -105,7 +105,6 @@ const AsiderAndHeaderLayout = () => {
|
|||||||
defaultOpenKeys={["synthesis"]}
|
defaultOpenKeys={["synthesis"]}
|
||||||
onClick={({ key }) => {
|
onClick={({ key }) => {
|
||||||
setActiveItem(key);
|
setActiveItem(key);
|
||||||
console.log(`/data/${key}`);
|
|
||||||
navigate(`/data/${key}`);
|
navigate(`/data/${key}`);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -169,10 +168,7 @@ const AsiderAndHeaderLayout = () => {
|
|||||||
<div
|
<div
|
||||||
className="fixed inset-0 z-40"
|
className="fixed inset-0 z-40"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
console.log("clicked outside");
|
|
||||||
|
|
||||||
setTaskCenterVisible(false);
|
setTaskCenterVisible(false);
|
||||||
toggleShowTaskPopover(false);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export default function OperatorPluginCreate() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full flex flex-col overflow-auto bg-gray-50">
|
<div className="flex-overflow-auto bg-gray-50">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
@@ -167,8 +167,8 @@ export default function OperatorPluginCreate() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
<div className="h-full flex flex-col flex-1 overflow-y-auto p-6 mt-4 bg-white rounded-md shadow">
|
<div className="flex-overflow-auto p-6 mt-4 bg-white border-card">
|
||||||
<div className="h-full w-full flex flex-col flex-1 overflow-y-auto">
|
<div className="flex-overflow-auto">
|
||||||
{uploadStep === "upload" && (
|
{uploadStep === "upload" && (
|
||||||
<UploadStep onUpload={handleFileUpload} isUploading={isUploading} />
|
<UploadStep onUpload={handleFileUpload} isUploading={isUploading} />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -115,9 +115,9 @@ export default function OperatorMarketPage() {
|
|||||||
</div> */}
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
<div className="flex flex-1 overflow-auto h-full bg-white rounded-lg">
|
<div className="flex-overflow-auto flex-row border-card">
|
||||||
<div
|
<div
|
||||||
className={`border-r border-gray-200 transition-all duration-300 ${
|
className={`border-r border-gray-100 transition-all duration-300 ${
|
||||||
showFilters
|
showFilters
|
||||||
? "translate-x-0 w-56"
|
? "translate-x-0 w-56"
|
||||||
: "-translate-x-full w-0 opacity-0"
|
: "-translate-x-full w-0 opacity-0"
|
||||||
@@ -130,7 +130,7 @@ export default function OperatorMarketPage() {
|
|||||||
setSelectedFilters={setSelectedFilters}
|
setSelectedFilters={setSelectedFilters}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 bg-yellow flex flex-col px-4 my-4">
|
<div className="flex-overflow-auto p-6 ">
|
||||||
<div className="flex w-full items-top gap-4 border-b border-gray-200 mb-4">
|
<div className="flex w-full items-top gap-4 border-b border-gray-200 mb-4">
|
||||||
{!showFilters && (
|
{!showFilters && (
|
||||||
<Button
|
<Button
|
||||||
@@ -139,9 +139,8 @@ export default function OperatorMarketPage() {
|
|||||||
onClick={() => setShowFilters(true)}
|
onClick={() => setShowFilters(true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div className="flex-1">
|
<div className="flex-1 mb-4">
|
||||||
<SearchControls
|
<SearchControls
|
||||||
className="mb-4"
|
|
||||||
searchTerm={searchParams.keyword}
|
searchTerm={searchParams.keyword}
|
||||||
onSearchChange={(keyword) =>
|
onSearchChange={(keyword) =>
|
||||||
setSearchParams({ ...searchParams, keyword })
|
setSearchParams({ ...searchParams, keyword })
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ const Filters: React.FC<FiltersProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-4 space-y-4 h-full overflow-y-auto">
|
<div className="p-6 space-y-4 h-full overflow-y-auto">
|
||||||
{/* Filter Header */}
|
{/* Filter Header */}
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h3 className="text-sm font-medium text-gray-900 flex items-center gap-2">
|
<h3 className="text-sm font-medium text-gray-900 flex items-center gap-2">
|
||||||
@@ -142,7 +142,7 @@ const Filters: React.FC<FiltersProps> = ({
|
|||||||
className="cursor-pointer hover:text-blue-500"
|
className="cursor-pointer hover:text-blue-500"
|
||||||
></Button>
|
></Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
筛选器
|
<h4>筛选器</h4>
|
||||||
</h3>
|
</h3>
|
||||||
{hasActiveFilters && (
|
{hasActiveFilters && (
|
||||||
<span
|
<span
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Button, Avatar, List, Tag, Badge } from "antd";
|
import { Button, List, Tag, Badge } from "antd";
|
||||||
import { DeleteOutlined, EditOutlined, StarFilled } from "@ant-design/icons";
|
import { DeleteOutlined, EditOutlined, StarFilled } from "@ant-design/icons";
|
||||||
import { Brain, Code, Cpu, Package, Zap, Settings, X } from "lucide-react";
|
import { Zap, Settings, X } from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
import { Operator } from "../../operator.model";
|
import { Operator } from "../../operator.model";
|
||||||
@@ -49,20 +49,10 @@ export function ListView({ operators, pagination }) {
|
|||||||
statusConfig[status as keyof typeof statusConfig] || statusConfig.active
|
statusConfig[status as keyof typeof statusConfig] || statusConfig.active
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const getTypeIcon = (type: string) => {
|
|
||||||
const iconMap = {
|
|
||||||
preprocessing: Code,
|
|
||||||
training: Brain,
|
|
||||||
inference: Cpu,
|
|
||||||
postprocessing: Package,
|
|
||||||
};
|
|
||||||
const IconComponent = iconMap[type as keyof typeof iconMap] || Code;
|
|
||||||
return <IconComponent className="w-4 h-4" />;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<List
|
<List
|
||||||
className="p-4 overflow-auto mx-4"
|
className="p-4 flex-1 overflow-auto mx-4"
|
||||||
dataSource={operators}
|
dataSource={operators}
|
||||||
pagination={pagination}
|
pagination={pagination}
|
||||||
renderItem={(operator) => (
|
renderItem={(operator) => (
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const { TextArea } = Input;
|
|||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
export default function CreateRatioTask() {
|
export default function CreateRatioTask() {
|
||||||
return <DevelopmentInProgress />;
|
return <DevelopmentInProgress showTime="2025.11.30" />;
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import { SearchControls } from "@/components/SearchControls";
|
|||||||
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
||||||
|
|
||||||
export default function RatioTasksPage() {
|
export default function RatioTasksPage() {
|
||||||
return <DevelopmentInProgress />;
|
return <DevelopmentInProgress showTime="2025.11.30" />;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [searchQuery, setSearchQuery] = useState("");
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
const [filterStatus, setFilterStatus] = useState("all");
|
const [filterStatus, setFilterStatus] = useState("all");
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
|||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
|
|
||||||
export default function SynthesisTaskCreate() {
|
export default function SynthesisTaskCreate() {
|
||||||
return <DevelopmentInProgress />;
|
return <DevelopmentInProgress showTime="2025.11.30" />;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [searchQuery, setSearchQuery] = useState("");
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { useState, useRef } from "react";
|
import { useState, useRef } from "react";
|
||||||
import { Card, Select, Input, Button, Badge, Divider, Form, message } from "antd";
|
|
||||||
import {
|
import {
|
||||||
Plus,
|
Card,
|
||||||
ArrowLeft,
|
Select,
|
||||||
Play,
|
Input,
|
||||||
Save,
|
Button,
|
||||||
RefreshCw,
|
Badge,
|
||||||
FileText,
|
Divider,
|
||||||
Code,
|
Form,
|
||||||
X,
|
message,
|
||||||
} from "lucide-react";
|
} from "antd";
|
||||||
|
import { Plus, ArrowLeft, Play, Save, RefreshCw, Code, X } from "lucide-react";
|
||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
import { mockTemplates } from "@/mock/annotation";
|
import { mockTemplates } from "@/mock/annotation";
|
||||||
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
||||||
@@ -17,9 +17,11 @@ import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
|||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
|
|
||||||
export default function InstructionTemplateCreate() {
|
export default function InstructionTemplateCreate() {
|
||||||
return <DevelopmentInProgress />;
|
return <DevelopmentInProgress showTime="2025.11.30" />;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(null);
|
const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(
|
||||||
|
null
|
||||||
|
);
|
||||||
const [isTestingTemplate, setIsTestingTemplate] = useState(false);
|
const [isTestingTemplate, setIsTestingTemplate] = useState(false);
|
||||||
const [templates, setTemplates] = useState<Template[]>(mockTemplates);
|
const [templates, setTemplates] = useState<Template[]>(mockTemplates);
|
||||||
const [variables, setVariables] = useState<string[]>([]);
|
const [variables, setVariables] = useState<string[]>([]);
|
||||||
@@ -131,10 +133,7 @@ export default function InstructionTemplateCreate() {
|
|||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex items-center justify-between mb-2">
|
<div className="flex items-center justify-between mb-2">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Button
|
<Button onClick={() => navigate("/data/synthesis/task")} type="text">
|
||||||
onClick={() => navigate("/data/synthesis/task")}
|
|
||||||
type="text"
|
|
||||||
>
|
|
||||||
<ArrowLeft className="w-4 h-4 mr-2" />
|
<ArrowLeft className="w-4 h-4 mr-2" />
|
||||||
</Button>
|
</Button>
|
||||||
<h1 className="text-xl font-bold bg-clip-text">
|
<h1 className="text-xl font-bold bg-clip-text">
|
||||||
@@ -177,7 +176,9 @@ export default function InstructionTemplateCreate() {
|
|||||||
<Form.Item label="模板描述" name="description">
|
<Form.Item label="模板描述" name="description">
|
||||||
<Input placeholder="简要描述模板的用途和特点" />
|
<Input placeholder="简要描述模板的用途和特点" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<h2 className="font-medium text-gray-900 text-lg mt-6 mb-2">Prompt内容</h2>
|
<h2 className="font-medium text-gray-900 text-lg mt-6 mb-2">
|
||||||
|
Prompt内容
|
||||||
|
</h2>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="Prompt内容"
|
label="Prompt内容"
|
||||||
name="prompt"
|
name="prompt"
|
||||||
@@ -194,7 +195,9 @@ export default function InstructionTemplateCreate() {
|
|||||||
提示:使用 {"{变量名}"} 格式定义变量,例如 {"{text}"} 或 {"{input}"}
|
提示:使用 {"{变量名}"} 格式定义变量,例如 {"{text}"} 或 {"{input}"}
|
||||||
</p>
|
</p>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<span className="text-sm font-semibold text-gray-700">变量管理</span>
|
<span className="text-sm font-semibold text-gray-700">
|
||||||
|
变量管理
|
||||||
|
</span>
|
||||||
<div className="flex flex-wrap gap-2 min-h-[50px] p-3 border rounded-xl bg-gray-50 mt-2">
|
<div className="flex flex-wrap gap-2 min-h-[50px] p-3 border rounded-xl bg-gray-50 mt-2">
|
||||||
{variables.map((variable, index) => (
|
{variables.map((variable, index) => (
|
||||||
<Badge
|
<Badge
|
||||||
@@ -226,13 +229,19 @@ export default function InstructionTemplateCreate() {
|
|||||||
className="h-8 text-sm"
|
className="h-8 text-sm"
|
||||||
onPressEnter={handleAddVariable}
|
onPressEnter={handleAddVariable}
|
||||||
/>
|
/>
|
||||||
<Button onClick={handleAddVariable} type="default" className="px-4 text-sm">
|
<Button
|
||||||
|
onClick={handleAddVariable}
|
||||||
|
type="default"
|
||||||
|
className="px-4 text-sm"
|
||||||
|
>
|
||||||
<Plus className="w-3 h-3 mr-1" />
|
<Plus className="w-3 h-3 mr-1" />
|
||||||
添加
|
添加
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="font-medium text-gray-900 text-lg mb-2 pt-2">模板测试</h2>
|
<h2 className="font-medium text-gray-900 text-lg mb-2 pt-2">
|
||||||
|
模板测试
|
||||||
|
</h2>
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<Form.Item label="测试输入" name="testInput">
|
<Form.Item label="测试输入" name="testInput">
|
||||||
<TextArea
|
<TextArea
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Tabs, Button, Card } from "antd";
|
import { Tabs, Button } from "antd";
|
||||||
import { Plus, ArrowRight } from "lucide-react";
|
import { Plus, ArrowRight } from "lucide-react";
|
||||||
import DataAnnotation from "../DataAnnotation/Annotate/components/TextAnnotation";
|
import DataAnnotation from "../DataAnnotation/Annotate/components/TextAnnotation";
|
||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
@@ -8,7 +8,7 @@ import SynthesisTaskTab from "./components/SynthesisTaskTab";
|
|||||||
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
||||||
|
|
||||||
export default function DataSynthesisPage() {
|
export default function DataSynthesisPage() {
|
||||||
return <DevelopmentInProgress />;
|
return <DevelopmentInProgress showTime="2025.11.30" />;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [activeTab, setActiveTab] = useState("tasks");
|
const [activeTab, setActiveTab] = useState("tasks");
|
||||||
|
|||||||
Reference in New Issue
Block a user