You've already forked DataMate
update data synthesis page ui (#60)
* 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. * Refactor Knowledge Generation to Knowledge Base - Created new API service for Knowledge Base operations including querying, creating, updating, and deleting knowledge bases and files. - Added constants for Knowledge Base status and type mappings. - Defined models for Knowledge Base and related files. - Removed obsolete Knowledge Base creation and home components, replacing them with new implementations under the Knowledge Base structure. - Updated routing to reflect the new Knowledge Base paths. - Adjusted menu items to align with the new Knowledge Base terminology. - Modified ModelAccess interface to include modelName and type properties. * feat: Implement Knowledge Base Page with CRUD operations and data management - Added KnowledgeBasePage component for displaying and managing knowledge bases. - Integrated search and filter functionalities with SearchControls component. - Implemented CreateKnowledgeBase component for creating and editing knowledge bases. - Enhanced AddDataDialog for file uploads and dataset selections. - Introduced TableTransfer component for managing data transfers between tables. - Updated API functions for knowledge base operations, including file management. - Refactored knowledge base model to include file status and metadata. - Adjusted routing to point to the new KnowledgeBasePage. * feat: enhance OperatorPluginCreate and ConfigureStep for better upload handling and UI updates * refactor: remove unused components and clean up API logging in KnowledgeBase * feat: update icons in various components and improve styling for better UI consistency * fix: adjust upload step handling and improve error display in configuration step * feat: Add RatioTransfer component for dataset selection and configuration - Implemented RatioTransfer component to manage dataset selection and ratio configuration. - Integrated dataset fetching with search and filter capabilities. - Added RatioConfig component for displaying and updating selected datasets' configurations. - Enhanced SelectDataset component with improved UI and functionality for dataset selection. - Updated RatioTasksPage to utilize new ratio task status mapping and improved error handling for task deletion. - Refactored ratio model and constants for better type safety and clarity. - Changed Vite configuration to use local backend service for development.
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
import { useState } from "react";
|
||||
import { Button, Card, Form, Divider, message } from "antd";
|
||||
import { ArrowLeft, Play, BarChart3, Shuffle, PieChart } from "lucide-react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { Button, Form, message } from "antd";
|
||||
import { ArrowLeft, ChevronRight } from "lucide-react";
|
||||
import { createRatioTaskUsingPost } from "@/pages/RatioTask/ratio.api.ts";
|
||||
import type { Dataset } from "@/pages/DataManagement/dataset.model.ts";
|
||||
import { useNavigate } from "react-router";
|
||||
import SelectDataset from "@/pages/RatioTask/Create/components/SelectDataset.tsx";
|
||||
import BasicInformation from "@/pages/RatioTask/Create/components/BasicInformation.tsx";
|
||||
import RatioConfig from "@/pages/RatioTask/Create/components/RatioConfig.tsx";
|
||||
import RatioTransfer from "./components/RatioTransfer";
|
||||
|
||||
export default function CreateRatioTask() {
|
||||
|
||||
const navigate = useNavigate();
|
||||
const [form] = Form.useForm();
|
||||
// 配比任务相关状态
|
||||
@@ -25,8 +25,9 @@ export default function CreateRatioTask() {
|
||||
|
||||
const [datasets, setDatasets] = useState<Dataset[]>([]);
|
||||
const [creating, setCreating] = useState(false);
|
||||
const [distributions, setDistributions] = useState<Record<string, Record<string, number>>>({});
|
||||
|
||||
const [distributions, setDistributions] = useState<
|
||||
Record<string, Record<string, number>>
|
||||
>({});
|
||||
|
||||
const handleCreateRatioTask = async () => {
|
||||
try {
|
||||
@@ -36,7 +37,8 @@ export default function CreateRatioTask() {
|
||||
return;
|
||||
}
|
||||
// Build request payload
|
||||
const ratio_method = ratioTaskForm.ratioType === "dataset" ? "DATASET" : "TAG";
|
||||
const ratio_method =
|
||||
ratioTaskForm.ratioType === "dataset" ? "DATASET" : "TAG";
|
||||
const totals = String(values.totalTargetCount);
|
||||
const config = ratioTaskForm.ratioConfigs.map((c) => {
|
||||
if (ratio_method === "DATASET") {
|
||||
@@ -69,11 +71,19 @@ export default function CreateRatioTask() {
|
||||
message.success("配比任务创建成功");
|
||||
navigate("/data/synthesis/ratio-task");
|
||||
} catch {
|
||||
// 校验失败
|
||||
message.error("配比任务创建失败,请重试");
|
||||
} finally {
|
||||
setCreating(false);
|
||||
}
|
||||
};
|
||||
const totalConfigured = useMemo(
|
||||
() =>
|
||||
ratioTaskForm?.ratioConfigs?.reduce?.(
|
||||
(sum, c) => sum + (c.quantity || 0),
|
||||
0
|
||||
) || 0,
|
||||
[ratioTaskForm.ratioConfigs]
|
||||
);
|
||||
|
||||
// dataset selection is handled inside SelectDataset via onSelectedDatasetsChange
|
||||
|
||||
@@ -137,10 +147,16 @@ export default function CreateRatioTask() {
|
||||
};
|
||||
|
||||
// 标签模式下,更新某数据集的某个标签的数量
|
||||
const updateLabelRatioConfig = (datasetId: string, label: string, quantity: number) => {
|
||||
const updateLabelRatioConfig = (
|
||||
datasetId: string,
|
||||
label: string,
|
||||
quantity: number
|
||||
) => {
|
||||
const sourceKey = `${datasetId}_${label}`;
|
||||
setRatioTaskForm((prev) => {
|
||||
const existingIndex = prev.ratioConfigs.findIndex((c) => c.source === sourceKey);
|
||||
const existingIndex = prev.ratioConfigs.findIndex(
|
||||
(c) => c.source === sourceKey
|
||||
);
|
||||
const totalOtherQuantity = prev.ratioConfigs
|
||||
.filter((c) => c.source !== sourceKey)
|
||||
.reduce((sum, c) => sum + c.quantity, 0);
|
||||
@@ -176,9 +192,9 @@ export default function CreateRatioTask() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen">
|
||||
<div className="h-full flex flex-col gap-4">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<Button
|
||||
type="text"
|
||||
@@ -189,126 +205,85 @@ export default function CreateRatioTask() {
|
||||
<h1 className="text-xl font-bold bg-clip-text">创建配比任务</h1>
|
||||
</div>
|
||||
</div>
|
||||
<Card className="overflow-y-auto p-2">
|
||||
<Form
|
||||
form={form}
|
||||
initialValues={ratioTaskForm}
|
||||
onValuesChange={handleValuesChange}
|
||||
layout="vertical"
|
||||
>
|
||||
<div className="grid grid-cols-12 gap-6">
|
||||
{/* 左侧:数据集选择 */}
|
||||
<SelectDataset
|
||||
selectedDatasets={ratioTaskForm.selectedDatasets}
|
||||
ratioType={ratioTaskForm.ratioType}
|
||||
onRatioTypeChange={(value) => setRatioTaskForm({ ...ratioTaskForm, ratioType: value, ratioConfigs: [] })}
|
||||
onSelectedDatasetsChange={(next) => {
|
||||
setRatioTaskForm((prev) => ({
|
||||
...prev,
|
||||
selectedDatasets: next,
|
||||
ratioConfigs: prev.ratioConfigs.filter((c) => {
|
||||
const id = String(c.source);
|
||||
// keep only items whose dataset id remains selected
|
||||
const dsId = id.includes("_") ? id.split("_")[0] : id;
|
||||
return next.includes(dsId);
|
||||
}),
|
||||
}));
|
||||
}}
|
||||
onDistributionsChange={(next) => setDistributions(next)}
|
||||
onDatasetsChange={(list) => setDatasets(list)}
|
||||
<div className="h-full flex-overflow-auto border-card">
|
||||
<div className="h-full overflow-auto p-6">
|
||||
<Form
|
||||
form={form}
|
||||
initialValues={ratioTaskForm}
|
||||
onValuesChange={handleValuesChange}
|
||||
layout="vertical"
|
||||
className="h-full"
|
||||
>
|
||||
<BasicInformation
|
||||
totalTargetCount={ratioTaskForm.totalTargetCount}
|
||||
/>
|
||||
{/* 右侧:配比配置 */}
|
||||
<div className="col-span-7">
|
||||
<h2 className="font-medium text-gray-900 text-lg mb-2 flex items-center gap-2">
|
||||
<PieChart className="w-5 h-5" />
|
||||
配比配置
|
||||
</h2>
|
||||
<Card>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
<span className="flex items-center gap-2 font-semibold">
|
||||
<BarChart3 className="w-5 h-5" />
|
||||
配比设置
|
||||
</span>
|
||||
<div className="text-gray-500 text-xs">
|
||||
设置每个数据集的配比数量
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
icon={<Shuffle />}
|
||||
size="small"
|
||||
onClick={generateAutoRatio}
|
||||
disabled={ratioTaskForm.selectedDatasets.length === 0}
|
||||
>
|
||||
平均分配
|
||||
</Button>
|
||||
</div>
|
||||
<BasicInformation totalTargetCount={ratioTaskForm.totalTargetCount} />
|
||||
<RatioConfig
|
||||
ratioType={ratioTaskForm.ratioType}
|
||||
selectedDatasets={ratioTaskForm.selectedDatasets}
|
||||
datasets={datasets}
|
||||
ratioConfigs={ratioTaskForm.ratioConfigs as any}
|
||||
totalTargetCount={ratioTaskForm.totalTargetCount}
|
||||
distributions={distributions}
|
||||
onUpdateDatasetQuantity={(datasetId, quantity) => updateRatioConfig(datasetId, quantity)}
|
||||
onUpdateLabelQuantity={(datasetId, label, quantity) => updateLabelRatioConfig(datasetId, label, quantity)}
|
||||
/>
|
||||
{/* 配比预览 */}
|
||||
{ratioTaskForm.ratioConfigs.length > 0 && (
|
||||
<div className="mb-4">
|
||||
<span className="text-sm font-medium">配比预览</span>
|
||||
<div className="p-3 bg-gray-50 rounded-lg">
|
||||
<div className="grid grid-cols-2 gap-4 text-sm">
|
||||
<div>
|
||||
<span className="text-gray-500">总配比数量:</span>
|
||||
<span className="ml-2 font-medium">
|
||||
{ratioTaskForm.ratioConfigs
|
||||
.reduce((sum, config) => sum + config.quantity, 0)
|
||||
.toLocaleString()}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-gray-500">目标数量:</span>
|
||||
<span className="ml-2 font-medium">
|
||||
{ratioTaskForm.totalTargetCount.toLocaleString()}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-gray-500">配比项目:</span>
|
||||
<span className="ml-2 font-medium">
|
||||
{ratioTaskForm.ratioConfigs.length}个
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<Divider />
|
||||
<div className="flex justify-end gap-2">
|
||||
<Button
|
||||
onClick={() => navigate("/data/synthesis/ratio-task")}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={handleCreateRatioTask}
|
||||
loading={creating}
|
||||
disabled={
|
||||
!ratioTaskForm.name ||
|
||||
ratioTaskForm.ratioConfigs.length === 0
|
||||
}
|
||||
>
|
||||
<Play className="w-4 h-4 mr-2" />
|
||||
创建任务
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* <RatioTransfer
|
||||
ratioTaskForm={ratioTaskForm}
|
||||
distributions={distributions}
|
||||
updateRatioConfig={updateRatioConfig}
|
||||
updateLabelRatioConfig={updateLabelRatioConfig}
|
||||
/> */}
|
||||
|
||||
<div className="flex h-full">
|
||||
<SelectDataset
|
||||
selectedDatasets={ratioTaskForm.selectedDatasets}
|
||||
ratioType={ratioTaskForm.ratioType}
|
||||
onRatioTypeChange={(value) =>
|
||||
setRatioTaskForm({
|
||||
...ratioTaskForm,
|
||||
ratioType: value,
|
||||
ratioConfigs: [],
|
||||
})
|
||||
}
|
||||
onSelectedDatasetsChange={(next) => {
|
||||
setRatioTaskForm((prev) => ({
|
||||
...prev,
|
||||
selectedDatasets: next,
|
||||
ratioConfigs: prev.ratioConfigs.filter((c) => {
|
||||
const id = String(c.source);
|
||||
// keep only items whose dataset id remains selected
|
||||
const dsId = id.includes("_") ? id.split("_")[0] : id;
|
||||
return next.includes(dsId);
|
||||
}),
|
||||
}));
|
||||
}}
|
||||
onDistributionsChange={(next) => setDistributions(next)}
|
||||
onDatasetsChange={(list) => setDatasets(list)}
|
||||
/>
|
||||
<ChevronRight className="self-center" />
|
||||
<RatioConfig
|
||||
ratioType={ratioTaskForm.ratioType}
|
||||
selectedDatasets={ratioTaskForm.selectedDatasets}
|
||||
datasets={datasets}
|
||||
totalTargetCount={ratioTaskForm.totalTargetCount}
|
||||
distributions={distributions}
|
||||
onChange={(configs) =>
|
||||
setRatioTaskForm((prev) => ({
|
||||
...prev,
|
||||
ratioConfigs: configs,
|
||||
}))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</Card>
|
||||
</Form>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2 p-6">
|
||||
<Button onClick={() => navigate("/data/synthesis/ratio-task")}>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={handleCreateRatioTask}
|
||||
loading={creating}
|
||||
disabled={
|
||||
!ratioTaskForm.name || ratioTaskForm.ratioConfigs.length === 0
|
||||
}
|
||||
>
|
||||
创建
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user