You've already forked DataMate
feat: fix the problem in the Operator Market frontend pages
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
import React, { memo } from "react";
|
||||
import { Outlet } from "react-router";
|
||||
import Sidebar from "./Sidebar";
|
||||
|
||||
const MainLayout = () => {
|
||||
return (
|
||||
<div className="w-full h-screen flex flex-col bg-gray-50 min-w-6xl">
|
||||
<div className="w-full h-full flex">
|
||||
{/* Sidebar */}
|
||||
<Sidebar />
|
||||
{/* Main Content */}
|
||||
<div className="flex-overflow-auto p-6">
|
||||
{/* Content Area */}
|
||||
<div className="flex-overflow-auto">
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(MainLayout);
|
||||
import React, { memo } from "react";
|
||||
import { Outlet } from "react-router";
|
||||
import Sidebar from "./Sidebar";
|
||||
|
||||
const MainLayout = () => {
|
||||
return (
|
||||
<div className="w-full h-screen flex flex-col bg-gray-50 min-w-6xl">
|
||||
<div className="w-full h-full flex">
|
||||
{/* Sidebar */}
|
||||
<Sidebar />
|
||||
{/* Main Content */}
|
||||
<div className="flex-overflow-auto p-6">
|
||||
{/* Content Area */}
|
||||
<div className="flex-overflow-auto">
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(MainLayout);
|
||||
|
||||
@@ -1,206 +1,206 @@
|
||||
import { memo, useEffect, useState } from "react";
|
||||
import { Button, Drawer, Menu, Popover } from "antd";
|
||||
import {
|
||||
CloseOutlined,
|
||||
MenuOutlined,
|
||||
SettingOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { ClipboardList, Sparkles, X } from "lucide-react";
|
||||
import { menuItems } from "@/pages/Layout/menu";
|
||||
import { NavLink, useLocation, useNavigate } from "react-router";
|
||||
import TaskUpload from "./TaskUpload";
|
||||
import SettingsPage from "../SettingsPage/SettingsPage";
|
||||
import { useAppSelector, useAppDispatch } from "@/store/hooks";
|
||||
import { showSettings, hideSettings } from "@/store/slices/settingsSlice";
|
||||
|
||||
const AsiderAndHeaderLayout = () => {
|
||||
const { pathname } = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const [activeItem, setActiveItem] = useState<string>("");
|
||||
const [sidebarOpen, setSidebarOpen] = useState(true);
|
||||
const [taskCenterVisible, setTaskCenterVisible] = useState(false);
|
||||
const settingVisible = useAppSelector((state) => state.settings.visible);
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
// Initialize active item based on current pathname
|
||||
const initActiveItem = () => {
|
||||
for (let index = 0; index < menuItems.length; index++) {
|
||||
const element = menuItems[index];
|
||||
if (element.children) {
|
||||
element.children.forEach((subItem) => {
|
||||
if (pathname.includes(subItem.id)) {
|
||||
setActiveItem(subItem.id);
|
||||
return;
|
||||
}
|
||||
});
|
||||
} else if (pathname.includes(element.id)) {
|
||||
setActiveItem(element.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log(pathname);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
initActiveItem();
|
||||
}, [pathname]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleShowTaskPopover = (event: CustomEvent) => {
|
||||
const { show } = event.detail;
|
||||
setTaskCenterVisible(show);
|
||||
};
|
||||
|
||||
window.addEventListener(
|
||||
"show:task-popover",
|
||||
handleShowTaskPopover as EventListener
|
||||
);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener(
|
||||
"show:task-popover",
|
||||
handleShowTaskPopover as EventListener
|
||||
);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${
|
||||
sidebarOpen ? "w-64" : "w-20"
|
||||
} bg-white border-r border-gray-200 transition-all duration-300 flex flex-col relative`}
|
||||
>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between p-4 border-b border-gray-200">
|
||||
{sidebarOpen && (
|
||||
<NavLink to="/" className="flex items-center gap-2 cursor-pointer">
|
||||
<div className="w-8 h-8 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-lg flex items-center justify-center">
|
||||
<Sparkles className="w-5 h-5 text-white" />
|
||||
</div>
|
||||
<span className="text-lg font-bold text-gray-900">DataMate</span>
|
||||
</NavLink>
|
||||
)}
|
||||
<span
|
||||
className="cursor-pointer hover:text-blue-500"
|
||||
onClick={() => setSidebarOpen(!sidebarOpen)}
|
||||
>
|
||||
{sidebarOpen ? <CloseOutlined /> : <MenuOutlined className="ml-4" />}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Navigation */}
|
||||
<div className="flex-1">
|
||||
<Menu
|
||||
mode="inline"
|
||||
inlineCollapsed={!sidebarOpen}
|
||||
items={menuItems.map((item) => ({
|
||||
key: item.id,
|
||||
label: item.title,
|
||||
icon: item.icon ? <item.icon className="w-4 h-4" /> : null,
|
||||
children: item.children
|
||||
? item.children.map((subItem) => ({
|
||||
key: subItem.id,
|
||||
label: subItem.title,
|
||||
icon: subItem.icon ? (
|
||||
<subItem.icon className="w-4 h-4" />
|
||||
) : null,
|
||||
}))
|
||||
: undefined,
|
||||
}))}
|
||||
selectedKeys={[activeItem]}
|
||||
defaultOpenKeys={["synthesis"]}
|
||||
onClick={({ key }) => {
|
||||
setActiveItem(key);
|
||||
navigate(`/data/${key}`);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div className="p-4 border-t border-gray-200">
|
||||
{sidebarOpen ? (
|
||||
<div className="space-y-2">
|
||||
<Popover
|
||||
forceRender
|
||||
title={
|
||||
<div className="flex items-center justify-between gap-2 border-b border-gray-200 pb-2 mb-2">
|
||||
<h4 className="font-bold">任务中心</h4>
|
||||
<X
|
||||
onClick={() => setTaskCenterVisible(false)}
|
||||
className="cursor-pointer w-4 h-4 text-gray-500 hover:text-gray-900"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
open={taskCenterVisible}
|
||||
content={<TaskUpload />}
|
||||
trigger="click"
|
||||
destroyOnHidden={false}
|
||||
>
|
||||
<Button block onClick={() => setTaskCenterVisible(true)}>
|
||||
任务中心
|
||||
</Button>
|
||||
</Popover>
|
||||
<Button
|
||||
block
|
||||
onClick={() => {
|
||||
dispatch(showSettings());
|
||||
}}
|
||||
>
|
||||
设置
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
<div className="relative">
|
||||
<Popover
|
||||
forceRender
|
||||
title="任务中心"
|
||||
open={taskCenterVisible}
|
||||
content={<TaskUpload />}
|
||||
trigger="click"
|
||||
destroyOnHidden={false}
|
||||
>
|
||||
<Button
|
||||
block
|
||||
onClick={() => setTaskCenterVisible(true)}
|
||||
icon={<ClipboardList className="w-4 h-4" />}
|
||||
></Button>
|
||||
</Popover>
|
||||
</div>
|
||||
<Button
|
||||
block
|
||||
onClick={() => {
|
||||
dispatch(showSettings());
|
||||
}}
|
||||
>
|
||||
<SettingOutlined />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Drawer
|
||||
title="设置"
|
||||
placement="bottom"
|
||||
width="100%"
|
||||
height="100%"
|
||||
open={settingVisible}
|
||||
onClose={() => dispatch(hideSettings())}
|
||||
bodyStyle={{ padding: 0 }}
|
||||
destroyOnHidden={true}
|
||||
>
|
||||
<SettingsPage></SettingsPage>
|
||||
</Drawer>
|
||||
{/* 添加遮罩层,点击外部区域时关闭 */}
|
||||
{taskCenterVisible && (
|
||||
<div
|
||||
className="fixed inset-0 z-40"
|
||||
onClick={() => {
|
||||
setTaskCenterVisible(false);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(AsiderAndHeaderLayout);
|
||||
import { memo, useEffect, useState } from "react";
|
||||
import { Button, Drawer, Menu, Popover } from "antd";
|
||||
import {
|
||||
CloseOutlined,
|
||||
MenuOutlined,
|
||||
SettingOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { ClipboardList, Sparkles, X } from "lucide-react";
|
||||
import { menuItems } from "@/pages/Layout/menu";
|
||||
import { NavLink, useLocation, useNavigate } from "react-router";
|
||||
import TaskUpload from "./TaskUpload";
|
||||
import SettingsPage from "../SettingsPage/SettingsPage";
|
||||
import { useAppSelector, useAppDispatch } from "@/store/hooks";
|
||||
import { showSettings, hideSettings } from "@/store/slices/settingsSlice";
|
||||
|
||||
const AsiderAndHeaderLayout = () => {
|
||||
const { pathname } = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const [activeItem, setActiveItem] = useState<string>("");
|
||||
const [sidebarOpen, setSidebarOpen] = useState(true);
|
||||
const [taskCenterVisible, setTaskCenterVisible] = useState(false);
|
||||
const settingVisible = useAppSelector((state) => state.settings.visible);
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
// Initialize active item based on current pathname
|
||||
const initActiveItem = () => {
|
||||
for (let index = 0; index < menuItems.length; index++) {
|
||||
const element = menuItems[index];
|
||||
if (element.children) {
|
||||
element.children.forEach((subItem) => {
|
||||
if (pathname.includes(subItem.id)) {
|
||||
setActiveItem(subItem.id);
|
||||
return;
|
||||
}
|
||||
});
|
||||
} else if (pathname.includes(element.id)) {
|
||||
setActiveItem(element.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log(pathname);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
initActiveItem();
|
||||
}, [pathname]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleShowTaskPopover = (event: CustomEvent) => {
|
||||
const { show } = event.detail;
|
||||
setTaskCenterVisible(show);
|
||||
};
|
||||
|
||||
window.addEventListener(
|
||||
"show:task-popover",
|
||||
handleShowTaskPopover as EventListener
|
||||
);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener(
|
||||
"show:task-popover",
|
||||
handleShowTaskPopover as EventListener
|
||||
);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${
|
||||
sidebarOpen ? "w-64" : "w-20"
|
||||
} bg-white border-r border-gray-200 transition-all duration-300 flex flex-col relative`}
|
||||
>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between p-4 border-b border-gray-200">
|
||||
{sidebarOpen && (
|
||||
<NavLink to="/" className="flex items-center gap-2 cursor-pointer">
|
||||
<div className="w-8 h-8 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-lg flex items-center justify-center">
|
||||
<Sparkles className="w-5 h-5 text-white" />
|
||||
</div>
|
||||
<span className="text-lg font-bold text-gray-900">DataMate</span>
|
||||
</NavLink>
|
||||
)}
|
||||
<span
|
||||
className="cursor-pointer hover:text-blue-500"
|
||||
onClick={() => setSidebarOpen(!sidebarOpen)}
|
||||
>
|
||||
{sidebarOpen ? <CloseOutlined /> : <MenuOutlined className="ml-4" />}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Navigation */}
|
||||
<div className="flex-1">
|
||||
<Menu
|
||||
mode="inline"
|
||||
inlineCollapsed={!sidebarOpen}
|
||||
items={menuItems.map((item) => ({
|
||||
key: item.id,
|
||||
label: item.title,
|
||||
icon: item.icon ? <item.icon className="w-4 h-4" /> : null,
|
||||
children: item.children
|
||||
? item.children.map((subItem) => ({
|
||||
key: subItem.id,
|
||||
label: subItem.title,
|
||||
icon: subItem.icon ? (
|
||||
<subItem.icon className="w-4 h-4" />
|
||||
) : null,
|
||||
}))
|
||||
: undefined,
|
||||
}))}
|
||||
selectedKeys={[activeItem]}
|
||||
defaultOpenKeys={["synthesis"]}
|
||||
onClick={({ key }) => {
|
||||
setActiveItem(key);
|
||||
navigate(`/data/${key}`);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div className="p-4 border-t border-gray-200">
|
||||
{sidebarOpen ? (
|
||||
<div className="space-y-2">
|
||||
<Popover
|
||||
forceRender
|
||||
title={
|
||||
<div className="flex items-center justify-between gap-2 border-b border-gray-200 pb-2 mb-2">
|
||||
<h4 className="font-bold">任务中心</h4>
|
||||
<X
|
||||
onClick={() => setTaskCenterVisible(false)}
|
||||
className="cursor-pointer w-4 h-4 text-gray-500 hover:text-gray-900"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
open={taskCenterVisible}
|
||||
content={<TaskUpload />}
|
||||
trigger="click"
|
||||
destroyOnHidden={false}
|
||||
>
|
||||
<Button block onClick={() => setTaskCenterVisible(true)}>
|
||||
任务中心
|
||||
</Button>
|
||||
</Popover>
|
||||
<Button
|
||||
block
|
||||
onClick={() => {
|
||||
dispatch(showSettings());
|
||||
}}
|
||||
>
|
||||
设置
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
<div className="relative">
|
||||
<Popover
|
||||
forceRender
|
||||
title="任务中心"
|
||||
open={taskCenterVisible}
|
||||
content={<TaskUpload />}
|
||||
trigger="click"
|
||||
destroyOnHidden={false}
|
||||
>
|
||||
<Button
|
||||
block
|
||||
onClick={() => setTaskCenterVisible(true)}
|
||||
icon={<ClipboardList className="w-4 h-4" />}
|
||||
></Button>
|
||||
</Popover>
|
||||
</div>
|
||||
<Button
|
||||
block
|
||||
onClick={() => {
|
||||
dispatch(showSettings());
|
||||
}}
|
||||
>
|
||||
<SettingOutlined />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Drawer
|
||||
title="设置"
|
||||
placement="bottom"
|
||||
width="100%"
|
||||
height="100%"
|
||||
open={settingVisible}
|
||||
onClose={() => dispatch(hideSettings())}
|
||||
bodyStyle={{ padding: 0 }}
|
||||
destroyOnHidden={true}
|
||||
>
|
||||
<SettingsPage></SettingsPage>
|
||||
</Drawer>
|
||||
{/* 添加遮罩层,点击外部区域时关闭 */}
|
||||
{taskCenterVisible && (
|
||||
<div
|
||||
className="fixed inset-0 z-40"
|
||||
onClick={() => {
|
||||
setTaskCenterVisible(false);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(AsiderAndHeaderLayout);
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
import {
|
||||
cancelUploadUsingPut,
|
||||
preUploadUsingPost,
|
||||
uploadFileChunkUsingPost,
|
||||
} from "@/pages/DataManagement/dataset.api";
|
||||
import { Button, Empty, Progress } from "antd";
|
||||
import { DeleteOutlined } from "@ant-design/icons";
|
||||
import { useEffect } from "react";
|
||||
import { useFileSliceUpload } from "@/hooks/useSliceUpload";
|
||||
|
||||
export default function TaskUpload() {
|
||||
const { createTask, taskList, removeTask, handleUpload } = useFileSliceUpload(
|
||||
{
|
||||
preUpload: preUploadUsingPost,
|
||||
uploadChunk: uploadFileChunkUsingPost,
|
||||
cancelUpload: cancelUploadUsingPut,
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const uploadHandler = (e: any) => {
|
||||
const { files } = e.detail;
|
||||
const task = createTask(e.detail);
|
||||
handleUpload({ task, files });
|
||||
};
|
||||
window.addEventListener("upload:dataset", uploadHandler);
|
||||
return () => {
|
||||
window.removeEventListener("upload:dataset", uploadHandler);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-90 max-w-90 max-h-96 overflow-y-auto p-2"
|
||||
id="header-task-popover"
|
||||
>
|
||||
{taskList.length > 0 &&
|
||||
taskList.map((task) => (
|
||||
<div key={task.key} className="border-b border-gray-200 pb-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>{task.title}</div>
|
||||
<Button
|
||||
type="text"
|
||||
danger
|
||||
disabled={!task?.cancelFn}
|
||||
onClick={() =>
|
||||
removeTask({
|
||||
...task,
|
||||
isCancel: true,
|
||||
})
|
||||
}
|
||||
icon={<DeleteOutlined />}
|
||||
></Button>
|
||||
</div>
|
||||
|
||||
<Progress size="small" percent={task.percent} />
|
||||
</div>
|
||||
))}
|
||||
{taskList.length === 0 && (
|
||||
<Empty
|
||||
image={Empty.PRESENTED_IMAGE_SIMPLE}
|
||||
description="暂无上传任务"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
import {
|
||||
cancelUploadUsingPut,
|
||||
preUploadUsingPost,
|
||||
uploadFileChunkUsingPost,
|
||||
} from "@/pages/DataManagement/dataset.api";
|
||||
import { Button, Empty, Progress } from "antd";
|
||||
import { DeleteOutlined } from "@ant-design/icons";
|
||||
import { useEffect } from "react";
|
||||
import { useFileSliceUpload } from "@/hooks/useSliceUpload";
|
||||
|
||||
export default function TaskUpload() {
|
||||
const { createTask, taskList, removeTask, handleUpload } = useFileSliceUpload(
|
||||
{
|
||||
preUpload: preUploadUsingPost,
|
||||
uploadChunk: uploadFileChunkUsingPost,
|
||||
cancelUpload: cancelUploadUsingPut,
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const uploadHandler = (e: any) => {
|
||||
const { files } = e.detail;
|
||||
const task = createTask(e.detail);
|
||||
handleUpload({ task, files });
|
||||
};
|
||||
window.addEventListener("upload:dataset", uploadHandler);
|
||||
return () => {
|
||||
window.removeEventListener("upload:dataset", uploadHandler);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-90 max-w-90 max-h-96 overflow-y-auto p-2"
|
||||
id="header-task-popover"
|
||||
>
|
||||
{taskList.length > 0 &&
|
||||
taskList.map((task) => (
|
||||
<div key={task.key} className="border-b border-gray-200 pb-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>{task.title}</div>
|
||||
<Button
|
||||
type="text"
|
||||
danger
|
||||
disabled={!task?.cancelFn}
|
||||
onClick={() =>
|
||||
removeTask({
|
||||
...task,
|
||||
isCancel: true,
|
||||
})
|
||||
}
|
||||
icon={<DeleteOutlined />}
|
||||
></Button>
|
||||
</div>
|
||||
|
||||
<Progress size="small" percent={task.percent} />
|
||||
</div>
|
||||
))}
|
||||
{taskList.length === 0 && (
|
||||
<Empty
|
||||
image={Empty.PRESENTED_IMAGE_SIMPLE}
|
||||
description="暂无上传任务"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,115 +1,115 @@
|
||||
import {
|
||||
FolderOpen,
|
||||
Tag,
|
||||
Target,
|
||||
BookOpen,
|
||||
Shuffle,
|
||||
BarChart3,
|
||||
MessageSquare,
|
||||
GitBranch,
|
||||
Zap,
|
||||
Shield,
|
||||
Database,
|
||||
Store,
|
||||
Merge,
|
||||
} from "lucide-react";
|
||||
|
||||
export const menuItems = [
|
||||
{
|
||||
id: "collection",
|
||||
title: "数据归集",
|
||||
icon: Database,
|
||||
description: "创建、导入和管理数据集",
|
||||
color: "bg-orange-500",
|
||||
},
|
||||
{
|
||||
id: "management",
|
||||
title: "数据管理",
|
||||
icon: FolderOpen,
|
||||
description: "创建、导入和管理数据集",
|
||||
color: "bg-blue-500",
|
||||
},
|
||||
{
|
||||
id: "cleansing",
|
||||
title: "数据清洗",
|
||||
icon: GitBranch,
|
||||
description: "数据清洗和预处理",
|
||||
color: "bg-purple-500",
|
||||
},
|
||||
{
|
||||
id: "annotation",
|
||||
title: "数据标注",
|
||||
icon: Tag,
|
||||
description: "对数据进行标注和标记",
|
||||
color: "bg-green-500",
|
||||
},
|
||||
{
|
||||
id: "synthesis",
|
||||
title: "数据合成",
|
||||
icon: Shuffle,
|
||||
description: "智能数据合成和配比",
|
||||
color: "bg-pink-500",
|
||||
children: [
|
||||
{
|
||||
id: "synthesis/task",
|
||||
title: "合成任务",
|
||||
icon: Merge,
|
||||
},
|
||||
{
|
||||
id: "synthesis/ratio-task",
|
||||
title: "配比任务",
|
||||
icon: BarChart3,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "evaluation",
|
||||
title: "数据评估",
|
||||
icon: Target,
|
||||
badge: 4,
|
||||
description: "质量分析、性能评估和偏见检测",
|
||||
color: "bg-indigo-500",
|
||||
},
|
||||
{
|
||||
id: "knowledge-base",
|
||||
title: "知识生成",
|
||||
icon: BookOpen,
|
||||
description: "面向RAG的知识库构建",
|
||||
color: "bg-teal-500",
|
||||
},
|
||||
{
|
||||
id: "operator-market",
|
||||
title: "算子市场",
|
||||
icon: Store,
|
||||
description: "算子上传与管理",
|
||||
color: "bg-yellow-500",
|
||||
},
|
||||
];
|
||||
|
||||
export const features = [
|
||||
{
|
||||
icon: GitBranch,
|
||||
title: "智能编排",
|
||||
description: "可视化数据清洗流程编排,拖拽式设计复杂的数据清洗管道",
|
||||
},
|
||||
{
|
||||
icon: MessageSquare,
|
||||
title: "对话助手",
|
||||
description: "通过自然语言对话完成复杂的数据集操作和业务流程",
|
||||
},
|
||||
{
|
||||
icon: Target,
|
||||
title: "全面评估",
|
||||
description: "多维度数据质量评估,包含统计分析、性能测试和偏见检测",
|
||||
},
|
||||
{
|
||||
icon: Zap,
|
||||
title: "高效处理",
|
||||
description: "完整的数据清洗流水线,从原始数据到可用数据集",
|
||||
},
|
||||
{
|
||||
icon: Shield,
|
||||
title: "知识管理",
|
||||
description: "构建面向RAG的知识库,支持智能问答和检索",
|
||||
},
|
||||
];
|
||||
import {
|
||||
FolderOpen,
|
||||
Tag,
|
||||
Target,
|
||||
BookOpen,
|
||||
Shuffle,
|
||||
BarChart3,
|
||||
MessageSquare,
|
||||
GitBranch,
|
||||
Zap,
|
||||
Shield,
|
||||
Database,
|
||||
Store,
|
||||
Merge,
|
||||
} from "lucide-react";
|
||||
|
||||
export const menuItems = [
|
||||
{
|
||||
id: "collection",
|
||||
title: "数据归集",
|
||||
icon: Database,
|
||||
description: "创建、导入和管理数据集",
|
||||
color: "bg-orange-500",
|
||||
},
|
||||
{
|
||||
id: "management",
|
||||
title: "数据管理",
|
||||
icon: FolderOpen,
|
||||
description: "创建、导入和管理数据集",
|
||||
color: "bg-blue-500",
|
||||
},
|
||||
{
|
||||
id: "cleansing",
|
||||
title: "数据清洗",
|
||||
icon: GitBranch,
|
||||
description: "数据清洗和预处理",
|
||||
color: "bg-purple-500",
|
||||
},
|
||||
{
|
||||
id: "annotation",
|
||||
title: "数据标注",
|
||||
icon: Tag,
|
||||
description: "对数据进行标注和标记",
|
||||
color: "bg-green-500",
|
||||
},
|
||||
{
|
||||
id: "synthesis",
|
||||
title: "数据合成",
|
||||
icon: Shuffle,
|
||||
description: "智能数据合成和配比",
|
||||
color: "bg-pink-500",
|
||||
children: [
|
||||
{
|
||||
id: "synthesis/task",
|
||||
title: "合成任务",
|
||||
icon: Merge,
|
||||
},
|
||||
{
|
||||
id: "synthesis/ratio-task",
|
||||
title: "配比任务",
|
||||
icon: BarChart3,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "evaluation",
|
||||
title: "数据评估",
|
||||
icon: Target,
|
||||
badge: 4,
|
||||
description: "质量分析、性能评估和偏见检测",
|
||||
color: "bg-indigo-500",
|
||||
},
|
||||
{
|
||||
id: "knowledge-base",
|
||||
title: "知识生成",
|
||||
icon: BookOpen,
|
||||
description: "面向RAG的知识库构建",
|
||||
color: "bg-teal-500",
|
||||
},
|
||||
{
|
||||
id: "operator-market",
|
||||
title: "算子市场",
|
||||
icon: Store,
|
||||
description: "算子上传与管理",
|
||||
color: "bg-yellow-500",
|
||||
},
|
||||
];
|
||||
|
||||
export const features = [
|
||||
{
|
||||
icon: GitBranch,
|
||||
title: "智能编排",
|
||||
description: "可视化数据清洗流程编排,拖拽式设计复杂的数据清洗管道",
|
||||
},
|
||||
{
|
||||
icon: MessageSquare,
|
||||
title: "对话助手",
|
||||
description: "通过自然语言对话完成复杂的数据集操作和业务流程",
|
||||
},
|
||||
{
|
||||
icon: Target,
|
||||
title: "全面评估",
|
||||
description: "多维度数据质量评估,包含统计分析、性能测试和偏见检测",
|
||||
},
|
||||
{
|
||||
icon: Zap,
|
||||
title: "高效处理",
|
||||
description: "完整的数据清洗流水线,从原始数据到可用数据集",
|
||||
},
|
||||
{
|
||||
icon: Shield,
|
||||
title: "知识管理",
|
||||
description: "构建面向RAG的知识库,支持智能问答和检索",
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user