Files
DataMate/frontend/src/pages/SynthesisTask/components/InstructionTemplateTab.tsx
chenghh-9609 955ffff6cd add select dataset files component (#94)
* feat: Refactor AddDataDialog and introduce DatasetFileTransfer component for improved file selection and management

* feat: Refactor SynthesisTask and InstructionTemplate components for improved UI and functionality; integrate DatasetFileTransfer for file management

* feat: Enhance CollectionTaskCreate form with additional fields for MYSQL configuration and prefix input
2025-11-20 14:12:59 +08:00

191 lines
5.8 KiB
TypeScript

import { useState } from "react";
import { Card, Table, Badge, Button } from "antd";
import { EditOutlined, DeleteOutlined } from "@ant-design/icons";
import { Plus, FileText } from "lucide-react";
import type { Template } from "@/pages/SynthesisTask/synthesis";
import { useNavigate } from "react-router";
import { mockTemplates } from "@/mock/synthesis";
import { SearchControls } from "@/components/SearchControls";
export default function InstructionTemplateTab() {
const navigate = useNavigate();
const [searchQuery, setSearchQuery] = useState("");
const [templates, setTemplates] = useState<Template[]>(mockTemplates);
const [filterTemplateType, setFilterTemplateType] = useState("all");
// 过滤模板
const filteredTemplates = templates.filter((template) => {
const matchesSearch =
template.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
template.description.toLowerCase().includes(searchQuery.toLowerCase());
const matchesType =
filterTemplateType === "all" || template.type === filterTemplateType;
return matchesSearch && matchesType;
});
const getQualityColor = (quality: number) => {
if (quality >= 90) return "text-green-600 bg-green-50 border-green-200";
if (quality >= 80) return "text-blue-600 bg-blue-50 border-blue-200";
if (quality >= 70) return "text-yellow-600 bg-yellow-50 border-yellow-200";
return "text-red-600 bg-red-50 border-red-200";
};
// 模板表格列
const templateColumns = [
{
title: "模板名称",
dataIndex: "name",
key: "name",
fixed: "left",
render: (text: string, template: Template) => (
<div className="flex items-center gap-3">
<div className="w-8 h-8 bg-purple-500 rounded-lg flex items-center justify-center shadow-sm">
<FileText className="w-4 h-4 text-white" />
</div>
<div>
<div className="font-medium text-gray-900 text-sm">
{template.name}
</div>
<div className="text-xs text-gray-500 line-clamp-1">
{template.description}
</div>
</div>
</div>
),
},
{
title: "类型",
dataIndex: "type",
key: "type",
render: (type: string) => (
<Badge className="text-xs">
{type === "preset" ? "预置" : "自定义"}
</Badge>
),
},
{
title: "分类",
dataIndex: "category",
key: "category",
render: (category: string) => (
<Badge className="bg-purple-50 text-purple-700 border-purple-200 text-xs">
{category}
</Badge>
),
},
{
title: "变量数量",
dataIndex: "variables",
key: "variables",
render: (variables: string[]) => (
<div className="text-sm font-medium text-gray-900">
{variables.length}
</div>
),
},
{
title: "使用次数",
dataIndex: "usageCount",
key: "usageCount",
render: (usageCount: number) => (
<div className="text-sm font-medium text-gray-900">{usageCount}</div>
),
},
{
title: "质量评分",
dataIndex: "quality",
key: "quality",
render: (quality: number) => (quality ? `${quality}%` : "-"),
},
{
title: "最后使用",
dataIndex: "lastUsed",
key: "lastUsed",
render: (lastUsed: string) => (
<div className="text-sm text-gray-600">{lastUsed || "-"}</div>
),
},
{
title: "操作",
key: "actions",
fixed: "right",
render: (_: any, template: Template) => (
<div className="flex items-center justify-center">
<Button type="text">
<EditOutlined />
</Button>
<Button type="text" danger>
<DeleteOutlined />
</Button>
</div>
),
},
];
return (
<div className="space-y-4">
<SearchControls
searchTerm={searchQuery}
onSearchChange={setSearchQuery}
searchPlaceholder="搜索模板名称或描述..."
filters={[
{
key: "type",
label: "类型",
options: [
{ label: "全部类型", value: "all" },
{ label: "预置模板", value: "preset" },
{ label: "自定义模板", value: "custom" },
],
},
]}
selectedFilters={{ type: [filterTemplateType] }}
onFiltersChange={(filters) => {
setFilterTemplateType(filters.type?.[0] || "all");
}}
showFilters
showViewToggle={false}
/>
{/* 模板表格 */}
<Card className="shadow-sm border-0 bg-white">
<Table
scroll={{ x: "max-content" }}
columns={templateColumns}
dataSource={filteredTemplates}
rowKey="id"
pagination={false}
locale={{
emptyText: (
<div className="text-center py-12">
<FileText className="w-12 h-12 text-gray-400 mx-auto mb-3" />
<h3 className="text-base font-semibold text-gray-900 mb-2">
</h3>
<p className="text-gray-500 mb-4 text-sm">
{searchQuery
? "没有找到匹配的模板"
: "开始创建您的第一个指令模板"}
</p>
{!searchQuery && (
<Button
onClick={() =>
navigate("/data/synthesis/task/create-template")
}
className="px-6 py-2 text-sm font-semibold bg-purple-600 hover:bg-purple-700 shadow-lg"
>
<Plus className="w-3 h-3 mr-1" />
</Button>
)}
</div>
),
}}
/>
</Card>
</div>
);
}