mirror of
https://github.com/tencentmusic/supersonic.git
synced 2026-04-28 20:04:27 +08:00
(feature)(webapp) agent defaults to list mode, supports switching to card mode (#362)
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
import { DeleteOutlined, EditOutlined, PlusOutlined, UserOutlined } from '@ant-design/icons';
|
||||
import { Button, Input, Popconfirm, Switch } from 'antd';
|
||||
import { Button, Popconfirm, Switch, Table } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import moment from 'moment';
|
||||
import { useEffect, useState } from 'react';
|
||||
import styles from './style.less';
|
||||
import { AgentType } from './type';
|
||||
|
||||
const { Search } = Input;
|
||||
|
||||
type Props = {
|
||||
agents: AgentType[];
|
||||
currentAgent?: AgentType;
|
||||
@@ -25,33 +24,108 @@ const AgentsSection: React.FC<Props> = ({
|
||||
onEditAgent,
|
||||
onSaveAgent,
|
||||
}) => {
|
||||
// const [searchName, setSearchName] = useState('');
|
||||
const [showAgents, setShowAgents] = useState<AgentType[]>([]);
|
||||
const [showType, setShowType] = useState(localStorage.getItem('AGENT_SHOW_TYPE') || 'list');
|
||||
|
||||
useEffect(() => {
|
||||
setShowAgents(agents);
|
||||
}, [agents]);
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '助理名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
render: (value: string, agent: AgentType) => {
|
||||
return (
|
||||
<a
|
||||
onClick={() => {
|
||||
onSelectAgent(agent);
|
||||
}}
|
||||
>
|
||||
{value}
|
||||
</a>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
render: (status: number, agent: AgentType) => {
|
||||
return (
|
||||
<div className={styles.toggleStatus}>
|
||||
{status === 0 ? '已禁用' : <span className={styles.online}>已启用</span>}
|
||||
<span
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<Switch
|
||||
size="small"
|
||||
defaultChecked={status === 1}
|
||||
onChange={(value) => {
|
||||
onSaveAgent({ ...agent, status: value ? 1 : 0 }, true);
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '更新人',
|
||||
dataIndex: 'updatedBy',
|
||||
key: 'updatedBy',
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
dataIndex: 'updatedAt',
|
||||
key: 'updatedAt',
|
||||
render: (value: string) => {
|
||||
return moment(value).format('YYYY-MM-DD HH:mm:ss');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'x',
|
||||
key: 'x',
|
||||
render: (_: any, agent: AgentType) => {
|
||||
return (
|
||||
<div className={styles.operateIcons}>
|
||||
<a
|
||||
onClick={() => {
|
||||
onSelectAgent(agent);
|
||||
}}
|
||||
>
|
||||
编辑
|
||||
</a>
|
||||
<Popconfirm
|
||||
title="确定删除吗?"
|
||||
onCancel={(e) => {
|
||||
e?.stopPropagation();
|
||||
}}
|
||||
onConfirm={() => {
|
||||
onDeleteAgent(agent.id!);
|
||||
}}
|
||||
>
|
||||
<a>删除</a>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className={styles.agentsSection}>
|
||||
{/* <div className={styles.sectionTitle}>问答助理</div> */}
|
||||
<div className={styles.content}>
|
||||
<div className={styles.searchBar}>
|
||||
{/* <Search
|
||||
placeholder="请输入助理名称搜索"
|
||||
className={styles.searchControl}
|
||||
value={searchName}
|
||||
onChange={(e) => {
|
||||
setSearchName(e.target.value);
|
||||
}}
|
||||
onSearch={(value) => {
|
||||
setShowAgents(
|
||||
agents.filter((agent) =>
|
||||
agent.name?.trim().toLowerCase().includes(value.trim().toLowerCase()),
|
||||
),
|
||||
);
|
||||
}}
|
||||
/> */}
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
@@ -61,81 +135,97 @@ const AgentsSection: React.FC<Props> = ({
|
||||
<PlusOutlined />
|
||||
新建助理
|
||||
</Button>
|
||||
<div className={styles.switchShowType}>
|
||||
<span className={styles.switchShowTypeLabel}>切换为卡片</span>
|
||||
<Switch
|
||||
size="small"
|
||||
checked={showType === 'card'}
|
||||
onChange={(value) => {
|
||||
const showTypeValue = value ? 'card' : 'list';
|
||||
setShowType(showTypeValue);
|
||||
localStorage.setItem('AGENT_SHOW_TYPE', showTypeValue);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.agentsContainer}>
|
||||
{showAgents.map((agent) => {
|
||||
const agentItemClass = classNames(styles.agentItem, {
|
||||
[styles.agentActive]: agent.id === currentAgent?.id,
|
||||
});
|
||||
return (
|
||||
<div
|
||||
className={agentItemClass}
|
||||
key={agent.id}
|
||||
onClick={() => {
|
||||
onSelectAgent(agent);
|
||||
}}
|
||||
>
|
||||
<UserOutlined className={styles.agentIcon} />
|
||||
<div className={styles.agentContent}>
|
||||
<div className={styles.agentNameBar}>
|
||||
<div className={styles.agentName}>{agent.name}</div>
|
||||
<div className={styles.operateIcons}>
|
||||
<EditOutlined
|
||||
className={styles.operateIcon}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onEditAgent(agent);
|
||||
}}
|
||||
/>
|
||||
<Popconfirm
|
||||
title="确定删除吗?"
|
||||
onCancel={(e) => {
|
||||
e?.stopPropagation();
|
||||
}}
|
||||
onConfirm={(e) => {
|
||||
e?.stopPropagation();
|
||||
onDeleteAgent(agent.id!);
|
||||
}}
|
||||
>
|
||||
<DeleteOutlined
|
||||
{showType === 'list' ? (
|
||||
<Table columns={columns} dataSource={showAgents} />
|
||||
) : (
|
||||
<div className={styles.agentsContainer}>
|
||||
{showAgents.map((agent) => {
|
||||
const agentItemClass = classNames(styles.agentItem, {
|
||||
[styles.agentActive]: agent.id === currentAgent?.id,
|
||||
});
|
||||
return (
|
||||
<div
|
||||
className={agentItemClass}
|
||||
key={agent.id}
|
||||
onClick={() => {
|
||||
onSelectAgent(agent);
|
||||
}}
|
||||
>
|
||||
<UserOutlined className={styles.agentIcon} />
|
||||
<div className={styles.agentContent}>
|
||||
<div className={styles.agentNameBar}>
|
||||
<div className={styles.agentName}>{agent.name}</div>
|
||||
<div className={styles.operateIcons}>
|
||||
<EditOutlined
|
||||
className={styles.operateIcon}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onEditAgent(agent);
|
||||
}}
|
||||
/>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.bottomBar}>
|
||||
<div className={styles.agentDescription} title={agent.description}>
|
||||
{agent.description}
|
||||
</div>
|
||||
<div className={styles.toggleStatus}>
|
||||
{agent.status === 0 ? (
|
||||
'已禁用'
|
||||
) : (
|
||||
<span className={styles.online}>已启用</span>
|
||||
)}
|
||||
<span
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<Switch
|
||||
size="small"
|
||||
defaultChecked={agent.status === 1}
|
||||
onChange={(value) => {
|
||||
onSaveAgent({ ...agent, status: value ? 1 : 0 }, true);
|
||||
<Popconfirm
|
||||
title="确定删除吗?"
|
||||
onCancel={(e) => {
|
||||
e?.stopPropagation();
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
onConfirm={(e) => {
|
||||
e?.stopPropagation();
|
||||
onDeleteAgent(agent.id!);
|
||||
}}
|
||||
>
|
||||
<DeleteOutlined
|
||||
className={styles.operateIcon}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
/>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.bottomBar}>
|
||||
<div className={styles.agentDescription} title={agent.description}>
|
||||
{agent.description}
|
||||
</div>
|
||||
<div className={styles.toggleStatus}>
|
||||
{agent.status === 0 ? (
|
||||
'已禁用'
|
||||
) : (
|
||||
<span className={styles.online}>已启用</span>
|
||||
)}
|
||||
<span
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<Switch
|
||||
size="small"
|
||||
defaultChecked={agent.status === 1}
|
||||
onChange={(value) => {
|
||||
onSaveAgent({ ...agent, status: value ? 1 : 0 }, true);
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
.agent {
|
||||
// background: #fff;
|
||||
height: calc(100vh - 48px);
|
||||
}
|
||||
|
||||
@@ -20,7 +19,7 @@
|
||||
.searchBar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 20px;
|
||||
column-gap: 30px;
|
||||
margin-bottom: 40px;
|
||||
|
||||
.searchControl {
|
||||
@@ -290,3 +289,16 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.switchShowTypeLabel {
|
||||
color: #999;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.operateIcons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 12px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user