Skip to content

Commit c52702b

Browse files
authored
feat:修复下载数据集问题、删除数据确认框、修改标题、添加列表轮询刷新 (#16)
* refactor: clean up tag management and dataset handling, update API endpoints * feat: add showTime prop to DevelopmentInProgress component across multiple pages * refactor: update component styles and improve layout with new utility classes * feat: enhance useFetchData hook with polling functionality and improve task progress tracking * feat: enhance dataset management features with improved tag handling, download functionality, and UI updates * feat: Enhance DatasetDetail component with delete functionality and improved download handling feat: Add automatic data refresh and improved user feedback in DatasetManagementPage fix: Update dataset API to streamline download functionality and improve error handling * feat: Clear new tag input after successful addition in TagManager
1 parent c998de2 commit c52702b

28 files changed

+712
-1213
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { Dropdown, Popconfirm, Button, Space } from "antd";
2+
import { EllipsisOutlined } from "@ant-design/icons";
3+
import { useState } from "react";
4+
5+
interface ActionItem {
6+
key: string;
7+
label: string;
8+
icon?: React.ReactNode;
9+
danger?: boolean;
10+
confirm?: {
11+
title: string;
12+
description?: string;
13+
okText?: string;
14+
cancelText?: string;
15+
};
16+
}
17+
18+
interface ActionDropdownProps {
19+
actions?: ActionItem[];
20+
onAction?: (key: string, action: ActionItem) => void;
21+
placement?:
22+
| "bottomRight"
23+
| "topLeft"
24+
| "topCenter"
25+
| "topRight"
26+
| "bottomLeft"
27+
| "bottomCenter"
28+
| "top"
29+
| "bottom";
30+
}
31+
32+
const ActionDropdown = ({
33+
actions = [],
34+
onAction,
35+
placement = "bottomRight",
36+
}: ActionDropdownProps) => {
37+
const [open, setOpen] = useState(false);
38+
const handleActionClick = (action: ActionItem) => {
39+
if (action.confirm) {
40+
// 如果有确认框,不立即执行,等待确认
41+
return;
42+
}
43+
// 执行操作
44+
onAction?.(action.key, action);
45+
// 如果没有确认框,则立即关闭 Dropdown
46+
setOpen(false);
47+
};
48+
49+
const dropdownContent = (
50+
<div className="bg-white p-2 rounded shadow-md">
51+
<Space direction="vertical" className="w-full">
52+
{actions.map((action) => {
53+
if (action.confirm) {
54+
return (
55+
<Popconfirm
56+
key={action.key}
57+
title={action.confirm.title}
58+
description={action.confirm.description}
59+
onConfirm={() => {
60+
onAction?.(action.key, action);
61+
setOpen(false);
62+
}}
63+
okText={action.confirm.okText || "确定"}
64+
cancelText={action.confirm.cancelText || "取消"}
65+
okType={action.danger ? "danger" : "primary"}
66+
styles={{ root: { zIndex: 9999 } }}
67+
>
68+
<Button
69+
type="text"
70+
size="small"
71+
className="w-full text-left"
72+
danger={action.danger}
73+
icon={action.icon}
74+
>
75+
{action.label}
76+
</Button>
77+
</Popconfirm>
78+
);
79+
}
80+
81+
return (
82+
<Button
83+
key={action.key}
84+
className="w-full"
85+
size="small"
86+
type="text"
87+
danger={action.danger}
88+
icon={action.icon}
89+
onClick={() => handleActionClick(action)}
90+
>
91+
{action.label}
92+
</Button>
93+
);
94+
})}
95+
</Space>
96+
</div>
97+
);
98+
99+
return (
100+
<Dropdown
101+
overlay={dropdownContent}
102+
trigger={["click"]}
103+
placement={placement}
104+
open={open}
105+
onOpenChange={setOpen}
106+
>
107+
<Button
108+
type="text"
109+
icon={<EllipsisOutlined style={{ fontSize: 24 }} />}
110+
/>
111+
</Dropdown>
112+
);
113+
};
114+
115+
export default ActionDropdown;

frontend/src/components/AddTagPopover.tsx

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Button, Input, Popover, theme, Tag } from "antd";
1+
import { Button, Input, Popover, theme, Tag, Empty } from "antd";
22
import { PlusOutlined } from "@ant-design/icons";
33
import { useEffect, useMemo, useState } from "react";
44

@@ -64,30 +64,35 @@ export default function AddTagPopover({
6464
open={showPopover}
6565
trigger="click"
6666
placement="bottom"
67+
onOpenChange={setShowPopover}
6768
content={
6869
<div className="space-y-4 w-[300px]">
6970
<h4 className="font-medium border-b pb-2 border-gray-100">
7071
添加标签
7172
</h4>
7273
{/* Available Tags */}
73-
<div className="space-y-2">
74-
<h5 className="text-sm">选择现有标签</h5>
75-
<div className="max-h-32 overflow-y-auto space-y-1">
76-
{availableTags.map((tag) => (
77-
<span
78-
key={tag.id}
79-
className="h-7 w-full justify-start text-xs cursor-pointer flex items-center px-2 rounded hover:bg-gray-100"
80-
onClick={() => {
81-
onAddTag?.(tag.name);
82-
setShowPopover(false);
83-
}}
84-
>
85-
<PlusOutlined className="w-3 h-3 mr-1" />
86-
{tag.name}
87-
</span>
88-
))}
74+
{availableTags?.length ? (
75+
<div className="space-y-2">
76+
<h5 className="text-sm">选择现有标签</h5>
77+
<div className="max-h-32 overflow-y-auto space-y-1">
78+
{availableTags.map((tag) => (
79+
<span
80+
key={tag.id}
81+
className="h-7 w-full justify-start text-xs cursor-pointer flex items-center px-2 rounded hover:bg-gray-100"
82+
onClick={() => {
83+
onAddTag?.(tag.name);
84+
setShowPopover(false);
85+
}}
86+
>
87+
<PlusOutlined className="w-3 h-3 mr-1" />
88+
{tag.name}
89+
</span>
90+
))}
91+
</div>
8992
</div>
90-
</div>
93+
) : (
94+
<Empty description="没有可用标签,请先创建标签。" />
95+
)}
9196

9297
{/* Create New Tag */}
9398
<div className="space-y-2 border-t border-gray-100 pt-3">

0 commit comments

Comments
 (0)