ui: replace session sidebar emoji icons with antd icons
parent
3d60016d87
commit
b333600245
|
|
@ -1,5 +1,6 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Button, List, Popconfirm, Input, App as AntApp, Tooltip, Empty, Segmented, Tag, Spin, Dropdown, Modal } from 'antd';
|
import { Button, List, Popconfirm, Input, App as AntApp, Tooltip, Empty, Segmented, Tag, Spin, Dropdown, Modal } from 'antd';
|
||||||
|
import { DeleteOutlined, DownloadOutlined, InboxOutlined, EditOutlined, MessageOutlined, RollbackOutlined, ShareAltOutlined } from '@ant-design/icons';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { ChatSession, SearchHit, SessionAPI } from '../api';
|
import { ChatSession, SearchHit, SessionAPI } from '../api';
|
||||||
|
|
||||||
|
|
@ -9,10 +10,10 @@ interface Props {
|
||||||
onChange: (sessionId: string, options?: { highlightMessageId?: string }) => void;
|
onChange: (sessionId: string, options?: { highlightMessageId?: string }) => void;
|
||||||
refreshTick?: number;
|
refreshTick?: number;
|
||||||
theme?: 'light' | 'dark';
|
theme?: 'light' | 'dark';
|
||||||
showNewButton?: boolean;
|
showNewButton?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function SessionSidebar({ agentId, activeSessionId, onChange, refreshTick, theme = 'light', showNewButton = true }: Props) {
|
export default function SessionSidebar({ agentId, activeSessionId, onChange, refreshTick, theme = 'light', showNewButton = true }: Props) {
|
||||||
const { message } = AntApp.useApp();
|
const { message } = AntApp.useApp();
|
||||||
const [tab, setTab] = useState<'active' | 'archived'>('active');
|
const [tab, setTab] = useState<'active' | 'archived'>('active');
|
||||||
const [active, setActive] = useState<ChatSession[]>([]);
|
const [active, setActive] = useState<ChatSession[]>([]);
|
||||||
|
|
@ -218,25 +219,27 @@ export default function SessionSidebar({ agentId, activeSessionId, onChange, ref
|
||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
size="small"
|
size="small"
|
||||||
|
icon={<EditOutlined />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setEditingId(s.id);
|
setEditingId(s.id);
|
||||||
setEditingTitle(s.title);
|
setEditingTitle(s.title);
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
✏️
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={tab === 'active' ? '归档' : '恢复'}>
|
<Tooltip title={tab === 'active' ? '归档' : '恢复'}>
|
||||||
<Button type="text" size="small" onClick={() => handleArchive(s, tab === 'active')}>
|
<Button
|
||||||
{tab === 'active' ? '📦' : '↩️'}
|
type="text"
|
||||||
</Button>
|
size="small"
|
||||||
|
icon={tab === 'active' ? <InboxOutlined /> : <RollbackOutlined />}
|
||||||
|
onClick={() => handleArchive(s, tab === 'active')}
|
||||||
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
trigger={['click']}
|
trigger={['click']}
|
||||||
menu={{
|
menu={{
|
||||||
items: [
|
items: [
|
||||||
{ key: 'md', label: '⬇️ Markdown (.md)' },
|
{ key: 'md', label: 'Markdown (.md)' },
|
||||||
{ key: 'json', label: '⬇️ JSON (.json)' }
|
{ key: 'json', label: 'JSON (.json)' }
|
||||||
],
|
],
|
||||||
onClick: ({ key }) => {
|
onClick: ({ key }) => {
|
||||||
SessionAPI.exportSession(agentId, s.id, key as 'md' | 'json');
|
SessionAPI.exportSession(agentId, s.id, key as 'md' | 'json');
|
||||||
|
|
@ -245,20 +248,14 @@ export default function SessionSidebar({ agentId, activeSessionId, onChange, ref
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tooltip title="导出会话">
|
<Tooltip title="导出会话">
|
||||||
<Button type="text" size="small">
|
<Button type="text" size="small" icon={<DownloadOutlined />} />
|
||||||
⬇️
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Tooltip title="分享公开链接(任何人都可只读访问)">
|
<Tooltip title="分享公开链接(任何人都可只读访问)">
|
||||||
<Button type="text" size="small" onClick={() => handleShare(s)}>
|
<Button type="text" size="small" icon={<ShareAltOutlined />} onClick={() => handleShare(s)} />
|
||||||
🔗
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Popconfirm title="删除此会话(不可恢复)?" onConfirm={() => handleDelete(s.id)} okText="删除" cancelText="取消">
|
<Popconfirm title="删除此会话(不可恢复)?" onConfirm={() => handleDelete(s.id)} okText="删除" cancelText="取消">
|
||||||
<Button type="text" size="small" danger>
|
<Button type="text" size="small" danger icon={<DeleteOutlined />} />
|
||||||
🗑
|
|
||||||
</Button>
|
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -270,11 +267,11 @@ export default function SessionSidebar({ agentId, activeSessionId, onChange, ref
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
|
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
|
||||||
{showNewButton && (
|
{showNewButton && (
|
||||||
<Button type="primary" onClick={handleNew} style={{ marginBottom: 8, background: c.primaryBtn }} block>
|
<Button type="primary" onClick={handleNew} style={{ marginBottom: 8, background: c.primaryBtn }} block>
|
||||||
➕ 新对话
|
➕ 新对话
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Input.Search
|
<Input.Search
|
||||||
placeholder="搜索会话与消息…"
|
placeholder="搜索会话与消息…"
|
||||||
|
|
@ -364,8 +361,22 @@ export default function SessionSidebar({ agentId, activeSessionId, onChange, ref
|
||||||
value={tab}
|
value={tab}
|
||||||
onChange={(v) => setTab(v as any)}
|
onChange={(v) => setTab(v as any)}
|
||||||
options={[
|
options={[
|
||||||
{ value: 'active', label: `💬 活跃 (${active.length})` },
|
{
|
||||||
{ value: 'archived', label: `📦 归档 (${archived.length})` }
|
value: 'active',
|
||||||
|
label: (
|
||||||
|
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
|
||||||
|
<MessageOutlined /> 活跃 ({active.length})
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'archived',
|
||||||
|
label: (
|
||||||
|
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
|
||||||
|
<InboxOutlined /> 归档 ({archived.length})
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
]}
|
]}
|
||||||
style={{ marginBottom: 8 }}
|
style={{ marginBottom: 8 }}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue