feat: added sorting functionality and updated translations
This commit is contained in:
parent
0d2ad2e4c3
commit
21243579b3
@ -196,7 +196,8 @@
|
||||
"edit.message.empty.content": "Conversation input content cannot be empty",
|
||||
"edit.model.select.title": "Select Model",
|
||||
"edit.settings.hide_preset_messages": "Hide Preset Message",
|
||||
"search.no_results": "No results found"
|
||||
"search.no_results": "No results found",
|
||||
"sorting.title": "Sorting"
|
||||
},
|
||||
"minapp": {
|
||||
"title": "MinApp"
|
||||
|
||||
@ -196,7 +196,8 @@
|
||||
"edit.message.empty.content": "会话输入内容不能为空",
|
||||
"edit.model.select.title": "选择模型",
|
||||
"edit.settings.hide_preset_messages": "隐藏预设消息",
|
||||
"search.no_results": "没有找到相关智能体"
|
||||
"search.no_results": "没有找到相关智能体",
|
||||
"sorting.title": "排序"
|
||||
},
|
||||
"minapp": {
|
||||
"title": "小程序"
|
||||
|
||||
@ -196,7 +196,8 @@
|
||||
"edit.message.empty.content": "會話輸入內容不能為空",
|
||||
"edit.model.select.title": "選擇模型",
|
||||
"edit.settings.hide_preset_messages": "隱藏預設消息",
|
||||
"search.no_results": "沒有找到相關智能體"
|
||||
"search.no_results": "沒有找到相關智能體",
|
||||
"sorting.title": "排序"
|
||||
},
|
||||
"minapp": {
|
||||
"title": "小程序"
|
||||
|
||||
@ -13,10 +13,8 @@ import ReactMarkdown from 'react-markdown'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { groupTranslations } from './agentGroupTranslations'
|
||||
import Agents from './Agents'
|
||||
import AddAgentCard from './components/AddAgentCard'
|
||||
import AddAgentPopup from './components/AddAgentPopup'
|
||||
import AgentCard from './components/AgentCard'
|
||||
import MyAgents from './components/MyAgents'
|
||||
|
||||
const { Title } = Typography
|
||||
|
||||
@ -131,12 +129,7 @@ const AgentsPage: FC = () => {
|
||||
</Title>
|
||||
<Row gutter={[20, 20]}>
|
||||
{group === '我的' ? (
|
||||
<>
|
||||
<Col span={6}>
|
||||
<AddAgentCard onClick={() => AddAgentPopup.show()} />
|
||||
</Col>
|
||||
<Agents onClick={onAddAgentConfirm} />
|
||||
</>
|
||||
<MyAgents onClick={onAddAgentConfirm} search={search} />
|
||||
) : (
|
||||
filteredAgentGroups[group]?.map((agent, index) => (
|
||||
<Col span={6} key={group + index}>
|
||||
@ -149,7 +142,7 @@ const AgentsPage: FC = () => {
|
||||
)
|
||||
}
|
||||
})
|
||||
}, [filteredAgentGroups, getLocalizedGroupName, onAddAgentConfirm])
|
||||
}, [filteredAgentGroups, getLocalizedGroupName, onAddAgentConfirm, search])
|
||||
|
||||
return (
|
||||
<Container>
|
||||
@ -214,6 +207,7 @@ const TabContent = styled(Scrollbar)`
|
||||
height: calc(100vh - var(--navbar-height));
|
||||
padding: 10px 10px 10px 15px;
|
||||
margin-right: -4px;
|
||||
padding-bottom: 20px !important;
|
||||
overflow-x: hidden;
|
||||
`
|
||||
|
||||
@ -240,8 +234,8 @@ const Tabs = styled(TabsAntd)`
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
.ant-tabs-nav {
|
||||
min-width: 120px;
|
||||
max-width: 120px;
|
||||
min-width: 140px;
|
||||
max-width: 140px;
|
||||
}
|
||||
.ant-tabs-nav-list {
|
||||
padding: 10px 8px;
|
||||
@ -253,8 +247,9 @@ const Tabs = styled(TabsAntd)`
|
||||
margin: 0 !important;
|
||||
border-radius: 20px;
|
||||
margin-bottom: 5px !important;
|
||||
font-size: 14px;
|
||||
justify-content: center;
|
||||
font-size: 13px;
|
||||
justify-content: left;
|
||||
padding: 7px 12px !important;
|
||||
&:hover {
|
||||
color: var(--color-text) !important;
|
||||
background-color: var(--color-background-soft);
|
||||
|
||||
@ -22,7 +22,7 @@ const AgentCard: React.FC<Props> = ({ agent, onClick, contextMenu, menuItems })
|
||||
const prompt = (agent.description || agent.prompt).substring(0, 100).replace(/\\n/g, '')
|
||||
const content = (
|
||||
<Container onClick={onClick}>
|
||||
{agent.emoji && <BannerBackground className="banner-background">{agent.emoji}</BannerBackground>}
|
||||
{emoji && <BannerBackground className="banner-background">{emoji}</BannerBackground>}
|
||||
<EmojiContainer className="emoji-container">{emoji}</EmojiContainer>
|
||||
{menuItems && (
|
||||
<MenuContainer onClick={(e) => e.stopPropagation()}>
|
||||
@ -41,7 +41,7 @@ const AgentCard: React.FC<Props> = ({ agent, onClick, contextMenu, menuItems })
|
||||
}}
|
||||
trigger={['click']}
|
||||
placement="bottomRight">
|
||||
<EllipsisOutlined style={{ cursor: 'pointer' }} />
|
||||
<EllipsisOutlined style={{ cursor: 'pointer', fontSize: 20 }} />
|
||||
</Dropdown>
|
||||
</MenuContainer>
|
||||
)}
|
||||
@ -112,14 +112,14 @@ const Container = styled.div`
|
||||
`
|
||||
|
||||
const EmojiContainer = styled.div`
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
min-width: 60px;
|
||||
min-height: 60px;
|
||||
width: 55px;
|
||||
height: 55px;
|
||||
min-width: 55px;
|
||||
min-height: 55px;
|
||||
background-color: var(--color-background);
|
||||
border-radius: 50%;
|
||||
border: 4px solid var(--color-border);
|
||||
margin-top: 5px;
|
||||
margin-top: 8px;
|
||||
transition: all 0.5s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -131,7 +131,7 @@ const CardInfo = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: 5px;
|
||||
transition: all 0.5s ease;
|
||||
padding: 0 15px;
|
||||
width: 100%;
|
||||
@ -177,7 +177,7 @@ const BannerBackground = styled.div`
|
||||
align-items: center;
|
||||
font-size: 500px;
|
||||
opacity: 0.1;
|
||||
filter: blur(10px);
|
||||
filter: blur(8px);
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
transition: all 0.5s ease;
|
||||
|
||||
100
src/renderer/src/pages/agents/components/ManageAgentsPopup.tsx
Normal file
100
src/renderer/src/pages/agents/components/ManageAgentsPopup.tsx
Normal file
@ -0,0 +1,100 @@
|
||||
import { MenuOutlined } from '@ant-design/icons'
|
||||
import DragableList from '@renderer/components/DragableList'
|
||||
import { Box, HStack } from '@renderer/components/Layout'
|
||||
import { TopView } from '@renderer/components/TopView'
|
||||
import { useAgents } from '@renderer/hooks/useAgents'
|
||||
import { Empty, Modal } from 'antd'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const PopupContainer: React.FC = () => {
|
||||
const [open, setOpen] = useState(true)
|
||||
const { t } = useTranslation()
|
||||
const { agents, updateAgents } = useAgents()
|
||||
|
||||
const onOk = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
const onCancel = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
const onClose = async () => {
|
||||
ManageAgentsPopup.hide()
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (agents.length === 0) {
|
||||
setOpen(false)
|
||||
}
|
||||
}, [agents])
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={t('agents.manage.title')}
|
||||
open={open}
|
||||
onOk={onOk}
|
||||
onCancel={onCancel}
|
||||
afterClose={onClose}
|
||||
footer={null}
|
||||
centered>
|
||||
<Container>
|
||||
{agents.length > 0 && (
|
||||
<DragableList list={agents} onUpdate={updateAgents}>
|
||||
{(item) => (
|
||||
<AgentItem>
|
||||
<Box mr={8}>
|
||||
{item.emoji} {item.name}
|
||||
</Box>
|
||||
<HStack gap="15px">
|
||||
<MenuOutlined style={{ cursor: 'move' }} />
|
||||
</HStack>
|
||||
</AgentItem>
|
||||
)}
|
||||
</DragableList>
|
||||
)}
|
||||
{agents.length === 0 && <Empty description="" />}
|
||||
</Container>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
const Container = styled.div`
|
||||
padding: 12px 0;
|
||||
height: 50vh;
|
||||
overflow-y: auto;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
|
||||
const AgentItem = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
user-select: none;
|
||||
background-color: var(--color-background-soft);
|
||||
margin-bottom: 8px;
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
color: var(--color-icon);
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--color-background-mute);
|
||||
}
|
||||
`
|
||||
|
||||
export default class ManageAgentsPopup {
|
||||
static topviewId = 0
|
||||
static hide() {
|
||||
TopView.hide('ManageAgentsPopup')
|
||||
}
|
||||
static show() {
|
||||
TopView.show(<PopupContainer />, 'ManageAgentsPopup')
|
||||
}
|
||||
}
|
||||
@ -1,23 +1,36 @@
|
||||
import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons'
|
||||
import { DeleteOutlined, EditOutlined, PlusOutlined, SortAscendingOutlined } from '@ant-design/icons'
|
||||
import AssistantSettingsPopup from '@renderer/components/AssistantSettings'
|
||||
import { useAgents } from '@renderer/hooks/useAgents'
|
||||
import { createAssistantFromAgent } from '@renderer/services/AssistantService'
|
||||
import { Agent } from '@renderer/types'
|
||||
import { Col } from 'antd'
|
||||
import { useCallback } from 'react'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import AgentCard from './components/AgentCard'
|
||||
import AddAgentCard from './AddAgentCard'
|
||||
import AddAgentPopup from './AddAgentPopup'
|
||||
import AgentCard from './AgentCard'
|
||||
import ManageAgentsPopup from './ManageAgentsPopup'
|
||||
|
||||
interface Props {
|
||||
onClick?: (agent: Agent) => void
|
||||
search?: string
|
||||
}
|
||||
|
||||
const Agents: React.FC<Props> = ({ onClick }) => {
|
||||
const MyAgents: React.FC<Props> = ({ onClick, search }) => {
|
||||
const { t } = useTranslation()
|
||||
const { agents, removeAgent } = useAgents()
|
||||
|
||||
const filteredAgents = useMemo(() => {
|
||||
if (!search?.trim()) return agents
|
||||
|
||||
return agents.filter(
|
||||
(agent) =>
|
||||
agent.name.toLowerCase().includes(search.toLowerCase()) ||
|
||||
agent.description?.toLowerCase().includes(search.toLowerCase())
|
||||
)
|
||||
}, [agents, search])
|
||||
|
||||
const handleDelete = useCallback(
|
||||
(agent: Agent) => {
|
||||
window.modal.confirm({
|
||||
@ -31,7 +44,7 @@ const Agents: React.FC<Props> = ({ onClick }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{agents.map((agent) => {
|
||||
{filteredAgents.map((agent) => {
|
||||
const dropdownMenuItems = [
|
||||
{
|
||||
key: 'edit',
|
||||
@ -45,6 +58,12 @@ const Agents: React.FC<Props> = ({ onClick }) => {
|
||||
icon: <PlusOutlined />,
|
||||
onClick: () => createAssistantFromAgent(agent)
|
||||
},
|
||||
{
|
||||
key: 'sort',
|
||||
label: t('agents.sorting.title'),
|
||||
icon: <SortAscendingOutlined />,
|
||||
onClick: () => ManageAgentsPopup.show()
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
label: t('common.delete'),
|
||||
@ -80,39 +99,11 @@ const Agents: React.FC<Props> = ({ onClick }) => {
|
||||
</Col>
|
||||
)
|
||||
})}
|
||||
<Col span={6}>
|
||||
<AddAgentCard onClick={() => AddAgentPopup.show()} />
|
||||
</Col>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const Container = styled.div`
|
||||
padding: 10px 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: calc(100vh - var(--navbar-height));
|
||||
min-width: var(--assistants-width);
|
||||
max-width: var(--assistants-width);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
border-radius: 3px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 3px;
|
||||
background: var(--color-scrollbar-thumb);
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
&:hover::-webkit-scrollbar-thumb {
|
||||
background: var(--color-scrollbar-thumb);
|
||||
}
|
||||
`
|
||||
|
||||
export default Agents
|
||||
export default MyAgents
|
||||
Loading…
x
Reference in New Issue
Block a user