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:
chenghh-9609
2025-10-30 16:30:01 +08:00
committed by GitHub
parent e0884ab048
commit 5612c7cd91
22 changed files with 640 additions and 979 deletions

View File

@@ -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}
/>
)}
</>
)}

View File

@@ -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
);

View File

@@ -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>
}
/>