Spaces:
Sleeping
Sleeping
Upload index.tsx
Browse files
aworld/cmd/web/webui/src/pages/components/BubbleItem/cardDefault/index.tsx
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import React, { useState, useCallback } from 'react';
|
2 |
+
import { Collapse, Space, message } from 'antd';
|
3 |
+
import type { ToolCardData } from '../utils';
|
4 |
+
import './index.less';
|
5 |
+
|
6 |
+
const { Panel } = Collapse;
|
7 |
+
|
8 |
+
interface PanelContent {
|
9 |
+
arguments: string;
|
10 |
+
results: string;
|
11 |
+
}
|
12 |
+
|
13 |
+
interface DownloadData extends PanelContent {
|
14 |
+
timestamp: string;
|
15 |
+
}
|
16 |
+
|
17 |
+
interface Props {
|
18 |
+
data: ToolCardData;
|
19 |
+
}
|
20 |
+
|
21 |
+
//下载JSON文件工具函数
|
22 |
+
const downloadJsonFile = (data: DownloadData) => {
|
23 |
+
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
|
24 |
+
const url = URL.createObjectURL(blob);
|
25 |
+
const a = document.createElement('a');
|
26 |
+
a.href = url;
|
27 |
+
a.download = `tool_data_${new Date().getTime()}.json`;
|
28 |
+
document.body.appendChild(a);
|
29 |
+
a.click();
|
30 |
+
document.body.removeChild(a);
|
31 |
+
URL.revokeObjectURL(url);
|
32 |
+
};
|
33 |
+
|
34 |
+
const CardDefault: React.FC<Props> = ({ data }) => {
|
35 |
+
// 当前展开的面板keys
|
36 |
+
const [activeKeys, setActiveKeys] = useState<string[]>(['1']);
|
37 |
+
const togglePanel = useCallback((panelKey: string) => {
|
38 |
+
setActiveKeys(
|
39 |
+
(prev) =>
|
40 |
+
prev.includes(panelKey)
|
41 |
+
? prev.filter((key) => key !== panelKey) // 如果已展开则折叠
|
42 |
+
: [...prev, panelKey] // 如果已折叠则展开
|
43 |
+
);
|
44 |
+
}, []);
|
45 |
+
|
46 |
+
// 处理下载操作
|
47 |
+
const handleDownload = useCallback(() => {
|
48 |
+
try {
|
49 |
+
downloadJsonFile({
|
50 |
+
arguments: data.arguments,
|
51 |
+
results: data.results,
|
52 |
+
timestamp: new Date().toISOString()
|
53 |
+
});
|
54 |
+
message.success('Download Successful');
|
55 |
+
} catch (error) {
|
56 |
+
message.error('Download Failed');
|
57 |
+
}
|
58 |
+
}, [data]);
|
59 |
+
|
60 |
+
// 处理复制
|
61 |
+
const handleCopy = useCallback(
|
62 |
+
async (panelKey: string) => {
|
63 |
+
try {
|
64 |
+
const content = panelKey === '1' ? data.arguments : data.results;
|
65 |
+
await navigator.clipboard.writeText(content);
|
66 |
+
message.success('Copy Successful');
|
67 |
+
} catch (error) {
|
68 |
+
message.error('Copy Failed');
|
69 |
+
}
|
70 |
+
},
|
71 |
+
[data]
|
72 |
+
);
|
73 |
+
|
74 |
+
//操作按钮
|
75 |
+
const renderExtra = useCallback(
|
76 |
+
(panelKey: string) => (
|
77 |
+
<Space size="small" onClick={(e) => e.stopPropagation()}>
|
78 |
+
<span className="action-btn" onClick={() => togglePanel(panelKey)}>
|
79 |
+
{activeKeys.includes(panelKey) ? 'Collapsed' : 'Expanded'}
|
80 |
+
</span>
|
81 |
+
<span className="action-btn" onClick={handleDownload}>
|
82 |
+
Save
|
83 |
+
</span>
|
84 |
+
<span className="action-btn" onClick={() => handleCopy(panelKey)}>
|
85 |
+
Copy
|
86 |
+
</span>
|
87 |
+
</Space>
|
88 |
+
),
|
89 |
+
[activeKeys, togglePanel, handleDownload, handleCopy]
|
90 |
+
);
|
91 |
+
|
92 |
+
return (
|
93 |
+
<div className="defaultbox">
|
94 |
+
<Collapse activeKey={activeKeys} onChange={(keys) => setActiveKeys(Array.isArray(keys) ? keys : [keys])}>
|
95 |
+
<Panel header="tool_call_arguments" key="1" extra={renderExtra('1')}>
|
96 |
+
<pre className="pre-wrap">
|
97 |
+
<code>{data.arguments}</code>
|
98 |
+
</pre>
|
99 |
+
</Panel>
|
100 |
+
<Panel header="tool_call_result" key="2" extra={renderExtra('2')}>
|
101 |
+
<pre className="pre-wrap">
|
102 |
+
<code>{data.results}</code>
|
103 |
+
</pre>
|
104 |
+
</Panel>
|
105 |
+
</Collapse>
|
106 |
+
</div>
|
107 |
+
);
|
108 |
+
};
|
109 |
+
|
110 |
+
export default React.memo(CardDefault);
|