You've already forked DataMate
add operator create page (#38)
* feat: Update site name to DataMate and refine text for AI data processing * feat: Refactor settings page and implement model access functionality - Created a new ModelAccess component for managing model configurations. - Removed the old Settings component and replaced it with a new SettingsPage component that integrates ModelAccess, SystemConfig, and WebhookConfig. - Added SystemConfig component for managing system settings. - Implemented WebhookConfig component for managing webhook configurations. - Updated API functions for model management in settings.apis.ts. - Adjusted routing to point to the new SettingsPage component. * feat: Implement Data Collection Page with Task Management and Execution Log - Created DataCollectionPage component to manage data collection tasks. - Added TaskManagement and ExecutionLog components for task handling and logging. - Integrated task operations including start, stop, edit, and delete functionalities. - Implemented filtering and searching capabilities in task management. - Introduced SimpleCronScheduler for scheduling tasks with cron expressions. - Updated CreateTask component to utilize new scheduling and template features. - Enhanced BasicInformation component to conditionally render fields based on visibility settings. - Refactored ImportConfiguration component to remove NAS import section. * feat: Update task creation API endpoint and enhance task creation form with new fields and validation * Refactor file upload and operator management components - Removed unnecessary console logs from file download and export functions. - Added size property to TaskItem interface for better task management. - Simplified TaskUpload component by utilizing useFileSliceUpload hook for file upload logic. - Enhanced OperatorPluginCreate component to handle file uploads and parsing more efficiently. - Updated ConfigureStep component to use Ant Design Form for better data handling and validation. - Improved PreviewStep component to navigate back to the operator market. - Added support for additional file types in UploadStep component. - Implemented delete operator functionality in OperatorMarketPage with confirmation prompts. - Cleaned up unused API functions in operator.api.ts to streamline the codebase. - Fixed number formatting utility to handle zero values correctly.
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Button } from "antd";
|
||||
import { FilterOutlined, PlusOutlined } from "@ant-design/icons";
|
||||
import { Boxes } from "lucide-react";
|
||||
import { Button, message } from "antd";
|
||||
import {
|
||||
DeleteOutlined,
|
||||
EditOutlined,
|
||||
FilterOutlined,
|
||||
PlusOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { Boxes, Edit } from "lucide-react";
|
||||
import { SearchControls } from "@/components/SearchControls";
|
||||
import CardView from "@/components/CardView";
|
||||
import { useNavigate } from "react-router";
|
||||
@@ -14,6 +19,7 @@ import TagManagement from "@/components/TagManagement";
|
||||
import { ListView } from "./components/List";
|
||||
import useFetchData from "@/hooks/useFetchData";
|
||||
import {
|
||||
deleteOperatorByIdUsingDelete,
|
||||
queryCategoryTreeUsingGet,
|
||||
queryOperatorsUsingPost,
|
||||
} from "../operator.api";
|
||||
@@ -23,8 +29,6 @@ export default function OperatorMarketPage() {
|
||||
const navigate = useNavigate();
|
||||
const [viewMode, setViewMode] = useState<"card" | "list">("card");
|
||||
|
||||
const filterOptions = [];
|
||||
|
||||
const [selectedFilters, setSelectedFilters] = useState<
|
||||
Record<string, string[]>
|
||||
>({});
|
||||
@@ -50,33 +54,44 @@ export default function OperatorMarketPage() {
|
||||
handleFiltersChange,
|
||||
} = useFetchData(queryOperatorsUsingPost, mapOperator);
|
||||
|
||||
const handleViewOperator = (operator: OperatorI) => {
|
||||
navigate(`/data/operator-market/plugin-detail/${operator.id}`);
|
||||
};
|
||||
|
||||
const handleUploadOperator = () => {
|
||||
navigate(`/data/operator-market/create`);
|
||||
};
|
||||
|
||||
const handleUpdateOperator = (operator: OperatorI) => {
|
||||
navigate(`/data/operator-market/edit/${operator.id}`);
|
||||
navigate(`/data/operator-market/create/${operator.id}`);
|
||||
};
|
||||
|
||||
const handleDeleteTag = (operator: OperatorI) => {
|
||||
// 删除算子逻辑
|
||||
console.log("删除算子", operator);
|
||||
const handleDeleteOperator = async (operator: OperatorI) => {
|
||||
try {
|
||||
await deleteOperatorByIdUsingDelete(operator.id);
|
||||
message.success("算子删除成功");
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
message.error("算子删除失败");
|
||||
}
|
||||
};
|
||||
|
||||
const operations = [
|
||||
{
|
||||
key: "edit",
|
||||
label: "更新算子",
|
||||
label: "更新",
|
||||
icon: <EditOutlined />,
|
||||
onClick: handleUpdateOperator,
|
||||
},
|
||||
{
|
||||
key: "delete",
|
||||
label: "删除算子",
|
||||
onClick: handleDeleteTag,
|
||||
label: "删除",
|
||||
danger: true,
|
||||
icon: <DeleteOutlined />,
|
||||
confirm: {
|
||||
title: "确认删除",
|
||||
description: "此操作不可撤销,是否继续?",
|
||||
okText: "删除",
|
||||
okType: "danger",
|
||||
cancelText: "取消",
|
||||
},
|
||||
onClick: handleDeleteOperator,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -87,14 +102,14 @@ export default function OperatorMarketPage() {
|
||||
const filteredIds = Object.values(selectedFilters).reduce(
|
||||
(acc, filter: string[]) => {
|
||||
if (filter.length) {
|
||||
acc.push(...filter.map(Number));
|
||||
acc.push(...filter);
|
||||
}
|
||||
|
||||
return acc;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
|
||||
fetchData({ categories: filteredIds?.length ? filteredIds : undefined });
|
||||
}, [selectedFilters]);
|
||||
|
||||
@@ -103,7 +118,7 @@ export default function OperatorMarketPage() {
|
||||
{/* Header */}
|
||||
<div className="flex justify-between">
|
||||
<h1 className="text-xl font-bold text-gray-900">算子市场</h1>
|
||||
{/* <div className="flex gap-2">
|
||||
<div className="flex gap-2">
|
||||
<TagManagement />
|
||||
<Button
|
||||
type="primary"
|
||||
@@ -112,7 +127,7 @@ export default function OperatorMarketPage() {
|
||||
>
|
||||
上传算子
|
||||
</Button>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
{/* Main Content */}
|
||||
<div className="flex-overflow-auto flex-row border-card">
|
||||
@@ -146,7 +161,7 @@ export default function OperatorMarketPage() {
|
||||
setSearchParams({ ...searchParams, keyword })
|
||||
}
|
||||
searchPlaceholder="搜索算子名称、描述..."
|
||||
filters={filterOptions}
|
||||
filters={[]}
|
||||
onFiltersChange={handleFiltersChange}
|
||||
viewMode={viewMode}
|
||||
onViewModeChange={setViewMode}
|
||||
@@ -167,9 +182,17 @@ export default function OperatorMarketPage() {
|
||||
) : (
|
||||
<>
|
||||
{viewMode === "card" ? (
|
||||
<CardView data={tableData} pagination={pagination} />
|
||||
<CardView
|
||||
data={tableData}
|
||||
pagination={pagination}
|
||||
operations={operations}
|
||||
/>
|
||||
) : (
|
||||
<ListView operators={tableData} pagination={pagination} />
|
||||
<ListView
|
||||
operators={tableData}
|
||||
operations={operations}
|
||||
pagination={pagination}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -122,8 +122,6 @@ const Filters: React.FC<FiltersProps> = ({
|
||||
setSelectedFilters(newFilters);
|
||||
};
|
||||
|
||||
console.log(categoriesTree);
|
||||
|
||||
const hasActiveFilters = Object.values(selectedFilters).some(
|
||||
(filters) => Array.isArray(filters) && filters.length > 0
|
||||
);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Button, List, Tag, Badge } from "antd";
|
||||
import { DeleteOutlined, EditOutlined, StarFilled } from "@ant-design/icons";
|
||||
import { StarFilled } from "@ant-design/icons";
|
||||
import { Zap, Settings, X } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useNavigate } from "react-router";
|
||||
import { Operator } from "../../operator.model";
|
||||
|
||||
export function ListView({ operators, pagination }) {
|
||||
export function ListView({ operators = [], pagination, operations }) {
|
||||
const navigate = useNavigate();
|
||||
const [favoriteOperators, setFavoriteOperators] = useState<Set<number>>(
|
||||
new Set([1, 3, 6])
|
||||
@@ -59,46 +59,39 @@ export function ListView({ operators, pagination }) {
|
||||
<List.Item
|
||||
className="hover:bg-gray-50 transition-colors px-6 py-4"
|
||||
actions={[
|
||||
<Button
|
||||
key="edit"
|
||||
type="text"
|
||||
size="small"
|
||||
onClick={() => handleUpdateOperator(operator)}
|
||||
icon={<EditOutlined className="w-4 h-4" />}
|
||||
title="更新算子"
|
||||
/>,
|
||||
<Button
|
||||
key="favorite"
|
||||
type="text"
|
||||
size="small"
|
||||
onClick={() => handleToggleFavorite(operator.id)}
|
||||
className={
|
||||
favoriteOperators.has(operator.id)
|
||||
? "text-yellow-500 hover:text-yellow-600"
|
||||
: "text-gray-400 hover:text-yellow-500"
|
||||
}
|
||||
icon={
|
||||
<StarFilled
|
||||
style={{
|
||||
fontSize: "16px",
|
||||
color: favoriteOperators.has(operator.id)
|
||||
? "#ffcc00ff"
|
||||
: "#d1d5db",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => handleToggleFavorite(operator.id)}
|
||||
/>
|
||||
}
|
||||
title="收藏"
|
||||
/>,
|
||||
<Button
|
||||
key="delete"
|
||||
type="text"
|
||||
size="small"
|
||||
danger
|
||||
icon={<DeleteOutlined className="w-4 h-4" />}
|
||||
title="删除算子"
|
||||
/>,
|
||||
// <Button
|
||||
// key="favorite"
|
||||
// type="text"
|
||||
// size="small"
|
||||
// onClick={() => handleToggleFavorite(operator.id)}
|
||||
// className={
|
||||
// favoriteOperators.has(operator.id)
|
||||
// ? "text-yellow-500 hover:text-yellow-600"
|
||||
// : "text-gray-400 hover:text-yellow-500"
|
||||
// }
|
||||
// icon={
|
||||
// <StarFilled
|
||||
// style={{
|
||||
// fontSize: "16px",
|
||||
// color: favoriteOperators.has(operator.id)
|
||||
// ? "#ffcc00ff"
|
||||
// : "#d1d5db",
|
||||
// cursor: "pointer",
|
||||
// }}
|
||||
// onClick={() => handleToggleFavorite(operator.id)}
|
||||
// />
|
||||
// }
|
||||
// title="收藏"
|
||||
// />,
|
||||
...operations.map((operation) => (
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
title={operation.label}
|
||||
icon={operation.icon}
|
||||
onClick={() => operation.onClick(operator)}
|
||||
/>
|
||||
)),
|
||||
]}
|
||||
>
|
||||
<List.Item.Meta
|
||||
@@ -124,12 +117,12 @@ export function ListView({ operators, pagination }) {
|
||||
description={
|
||||
<div className="space-y-2">
|
||||
<div className="text-gray-600 ">{operator.description}</div>
|
||||
{/* <div className="flex items-center gap-4 text-xs text-gray-500">
|
||||
<div className="flex items-center gap-4 text-xs text-gray-500">
|
||||
<span>作者: {operator.author}</span>
|
||||
<span>类型: {operator.type}</span>
|
||||
<span>框架: {operator.framework}</span>
|
||||
<span>使用次数: {operator?.usage?.toLocaleString()}</span>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user