chore: 更新智能体列表展示
parent
6f4f232e80
commit
85090899e6
|
|
@ -8,39 +8,39 @@ import {
|
|||
RobotOutlined
|
||||
} from '@ant-design/icons';
|
||||
import { Button, Col, Row, Empty, Popconfirm, App as AntApp, Tag, Space } from 'antd';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import dayjs from 'dayjs';
|
||||
import { Agent, AgentAPI } from '../api';
|
||||
|
||||
export default function AgentList() {
|
||||
const [list, setList] = useState<Agent[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const { message } = AntApp.useApp();
|
||||
|
||||
const load = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
setList(await AgentAPI.list());
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
load();
|
||||
}, []);
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
await AgentAPI.remove(id);
|
||||
message.success('已删除');
|
||||
load();
|
||||
};
|
||||
|
||||
const isImageUrl = (url: string) => url?.startsWith('http') || url?.startsWith('/');
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import dayjs from 'dayjs';
|
||||
import { Agent, AgentAPI } from '../api';
|
||||
|
||||
export default function AgentList() {
|
||||
const [list, setList] = useState<Agent[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const { message } = AntApp.useApp();
|
||||
|
||||
const load = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
setList(await AgentAPI.list());
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
load();
|
||||
}, []);
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
await AgentAPI.remove(id);
|
||||
message.success('已删除');
|
||||
load();
|
||||
};
|
||||
|
||||
const isImageUrl = (url: string) => url?.startsWith('http') || url?.startsWith('/');
|
||||
const publicCount = useMemo(() => list.filter((a) => a.visibility === 'public').length, [list]);
|
||||
const teamCount = useMemo(() => list.filter((a) => a.visibility === 'team').length, [list]);
|
||||
|
||||
return (
|
||||
|
||||
return (
|
||||
<div className="page-container">
|
||||
<div
|
||||
style={{
|
||||
|
|
@ -89,7 +89,7 @@ export default function AgentList() {
|
|||
<div className="page-subtitle" style={{ marginTop: 0, fontSize: 15, lineHeight: 1.75 }}>
|
||||
把你的 AI 助手沉淀成一组可管理、可协作、可持续进化的能力单元。创建入口统一在智能体广场,这里负责查看、进入和运营它们。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
type="primary"
|
||||
size="large"
|
||||
|
|
@ -99,7 +99,7 @@ export default function AgentList() {
|
|||
>
|
||||
前往智能体广场
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, minmax(0, 1fr))', gap: 14 }}>
|
||||
{[
|
||||
|
|
@ -135,20 +135,20 @@ export default function AgentList() {
|
|||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!loading && list.length === 0 ? (
|
||||
<div className="empty-state">
|
||||
<Empty description="你还没有任何智能体">
|
||||
</div>
|
||||
|
||||
{!loading && list.length === 0 ? (
|
||||
<div className="empty-state">
|
||||
<Empty description="你还没有任何智能体">
|
||||
<Button type="primary" onClick={() => navigate('/marketplace')} style={{ borderRadius: 10 }}>
|
||||
前往广场创建
|
||||
</Button>
|
||||
</Empty>
|
||||
</div>
|
||||
) : (
|
||||
前往广场创建
|
||||
</Button>
|
||||
</Empty>
|
||||
</div>
|
||||
) : (
|
||||
<Row gutter={[18, 18]}>
|
||||
{list.map((a) => (
|
||||
<Col xs={24} sm={12} md={8} lg={6} key={a.id}>
|
||||
{list.map((a) => (
|
||||
<Col xs={24} sm={12} md={8} lg={6} key={a.id}>
|
||||
<div
|
||||
className="agent-card"
|
||||
style={{
|
||||
|
|
@ -164,19 +164,19 @@ export default function AgentList() {
|
|||
className="avatar"
|
||||
style={{ background: a.avatar || 'var(--gradient-brand)', borderRadius: '50%', overflow: 'hidden', width: 54, height: 54 }}
|
||||
>
|
||||
{isImageUrl(a.avatar) ? (
|
||||
<img src={a.avatar} className="w-full h-full object-cover" alt="avatar" />
|
||||
) : (
|
||||
(a.name?.charAt(0) || '?').toUpperCase()
|
||||
)}
|
||||
</div>
|
||||
<div style={{ flex: 1, minWidth: 0 }}>
|
||||
{isImageUrl(a.avatar) ? (
|
||||
<img src={a.avatar} className="w-full h-full object-cover" alt="avatar" />
|
||||
) : (
|
||||
(a.name?.charAt(0) || '?').toUpperCase()
|
||||
)}
|
||||
</div>
|
||||
<div style={{ flex: 1, minWidth: 0 }}>
|
||||
<div style={{ fontWeight: 700, fontSize: 17, color: 'var(--color-text)', marginBottom: 4 }}>{a.name}</div>
|
||||
<div style={{ fontSize: 12.5, color: 'var(--color-text-tertiary)' }}>
|
||||
最近更新于 {dayjs(a.updated_at).format('YYYY-MM-DD')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
|
|
@ -215,42 +215,39 @@ export default function AgentList() {
|
|||
</span>
|
||||
</Tag>
|
||||
)}
|
||||
<Tag bordered={false} style={{ background: 'var(--color-surface-2)', color: 'var(--color-text-secondary)', borderRadius: 999, margin: 0 }}>
|
||||
T={a.temperature}
|
||||
</Tag>
|
||||
{(a.fork_count ?? 0) > 0 && (
|
||||
<Tag bordered={false} style={{ background: 'var(--color-surface-2)', color: 'var(--color-text-secondary)', borderRadius: 999, margin: 0 }}>
|
||||
Fork {a.fork_count}
|
||||
</Tag>
|
||||
)}
|
||||
</Space>
|
||||
</Space>
|
||||
|
||||
<div style={{ display: 'flex', gap: 8, marginTop: 'auto', paddingTop: 16, borderTop: '1px solid var(--color-border)' }}>
|
||||
<Link to={`/chat/${a.id}`} style={{ flex: 1 }}>
|
||||
<Button type="primary" block icon={<MessageOutlined />} style={{ borderRadius: 12, height: 40, fontWeight: 600 }}>
|
||||
聊天
|
||||
</Button>
|
||||
</Link>
|
||||
<Link to={`/agents/${a.id}`} style={{ flex: 1 }}>
|
||||
</Link>
|
||||
<Link to={`/agents/${a.id}`} style={{ flex: 1 }}>
|
||||
<Button block icon={<EditOutlined />} style={{ borderRadius: 12, height: 40 }}>
|
||||
管理
|
||||
</Button>
|
||||
</Link>
|
||||
<Popconfirm
|
||||
title="确定删除该智能体?"
|
||||
description="将删除其知识库与对话记录"
|
||||
onConfirm={() => handleDelete(a.id)}
|
||||
okText="删除"
|
||||
cancelText="取消"
|
||||
>
|
||||
</Link>
|
||||
<Popconfirm
|
||||
title="确定删除该智能体?"
|
||||
description="将删除其知识库与对话记录"
|
||||
onConfirm={() => handleDelete(a.id)}
|
||||
okText="删除"
|
||||
cancelText="取消"
|
||||
>
|
||||
<Button danger icon={<DeleteOutlined />} style={{ borderRadius: 12, width: 40, height: 40 }} />
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
)}
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
)}
|
||||
|
||||
{list.length > 0 && (
|
||||
<div
|
||||
|
|
@ -280,6 +277,6 @@ export default function AgentList() {
|
|||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue