feat: Added configurable Droppable component props to DragableList, updated translations and implemented search functionality.

- Added support for configurable Droppable component props to the DragableList component.
- Updated translations for multiple components and languages.
- Implemented search functionality in the Assistants page.
This commit is contained in:
kangfenmao 2024-09-11 16:14:06 +08:00
parent 6bf98f6db3
commit 11b2cd88b7
3 changed files with 66 additions and 17 deletions

View File

@ -2,6 +2,7 @@ import {
DragDropContext, DragDropContext,
Draggable, Draggable,
Droppable, Droppable,
DroppableProps,
DropResult, DropResult,
OnDragEndResponder, OnDragEndResponder,
OnDragStartResponder, OnDragStartResponder,
@ -18,9 +19,19 @@ interface Props<T> {
onUpdate: (list: T[]) => void onUpdate: (list: T[]) => void
onDragStart?: OnDragStartResponder onDragStart?: OnDragStartResponder
onDragEnd?: OnDragEndResponder onDragEnd?: OnDragEndResponder
droppableProps?: Partial<DroppableProps>
} }
const DragableList: FC<Props<any>> = ({ children, list, style, listStyle, onDragStart, onUpdate, onDragEnd }) => { const DragableList: FC<Props<any>> = ({
children,
list,
style,
listStyle,
droppableProps,
onDragStart,
onUpdate,
onDragEnd
}) => {
const _onDragEnd = (result: DropResult, provided: ResponderProvided) => { const _onDragEnd = (result: DropResult, provided: ResponderProvided) => {
onDragEnd?.(result, provided) onDragEnd?.(result, provided)
if (result.destination) { if (result.destination) {
@ -33,11 +44,11 @@ const DragableList: FC<Props<any>> = ({ children, list, style, listStyle, onDrag
return ( return (
<DragDropContext onDragStart={onDragStart} onDragEnd={_onDragEnd}> <DragDropContext onDragStart={onDragStart} onDragEnd={_onDragEnd}>
<Droppable droppableId="droppable"> <Droppable droppableId="droppable" {...droppableProps}>
{(provided) => ( {(provided) => (
<div {...provided.droppableProps} ref={provided.innerRef} style={{ ...style }}> <div {...provided.droppableProps} ref={provided.innerRef} style={{ ...style }}>
{list.map((item, index) => ( {list.map((item, index) => (
<Draggable key={`draggable_${item.id}_${index}`} draggableId={item.id} index={index}> <Draggable key={`draggable_${item.id}_${index}`} draggableId={item.id} index={index} {...droppableProps}>
{(provided) => ( {(provided) => (
<div <div
ref={provided.innerRef} ref={provided.innerRef}

View File

@ -73,7 +73,7 @@ const resources = {
'topics.list': 'Topic List', 'topics.list': 'Topic List',
'input.new_topic': 'New Topic', 'input.new_topic': 'New Topic',
'input.topics': ' Topics ', 'input.topics': ' Topics ',
'input.clear': 'Clear Messages', 'input.clear': 'Clear',
'input.new.context': 'Clear Context', 'input.new.context': 'Clear Context',
'input.expand': 'Expand', 'input.expand': 'Expand',
'input.collapse': 'Collapse', 'input.collapse': 'Collapse',
@ -99,7 +99,8 @@ const resources = {
'settings.max': 'Max', 'settings.max': 'Max',
'suggestions.title': 'Suggested Questions', 'suggestions.title': 'Suggested Questions',
'add.assistant.title': 'Add Assistant', 'add.assistant.title': 'Add Assistant',
'message.new.context': 'New Context' 'message.new.context': 'New Context',
'assistant.search.placeholder': 'Search Assistants'
}, },
agents: { agents: {
title: 'Assistants', title: 'Assistants',
@ -353,7 +354,8 @@ const resources = {
'settings.max': '不限', 'settings.max': '不限',
'suggestions.title': '建议的问题', 'suggestions.title': '建议的问题',
'add.assistant.title': '添加智能体', 'add.assistant.title': '添加智能体',
'message.new.context': '清除上下文' 'message.new.context': '清除上下文',
'assistant.search.placeholder': '搜索智能体'
}, },
agents: { agents: {
title: '智能体', title: '智能体',

View File

@ -1,4 +1,4 @@
import { DeleteOutlined, EditOutlined, MinusCircleOutlined } from '@ant-design/icons' import { DeleteOutlined, EditOutlined, MinusCircleOutlined, SearchOutlined } from '@ant-design/icons'
import DragableList from '@renderer/components/DragableList' import DragableList from '@renderer/components/DragableList'
import CopyIcon from '@renderer/components/Icons/CopyIcon' import CopyIcon from '@renderer/components/Icons/CopyIcon'
import AssistantSettingPopup from '@renderer/components/Popups/AssistantSettingPopup' import AssistantSettingPopup from '@renderer/components/Popups/AssistantSettingPopup'
@ -8,10 +8,10 @@ import { EVENT_NAMES, EventEmitter } from '@renderer/services/event'
import { useAppSelector } from '@renderer/store' import { useAppSelector } from '@renderer/store'
import { Assistant } from '@renderer/types' import { Assistant } from '@renderer/types'
import { uuid } from '@renderer/utils' import { uuid } from '@renderer/utils'
import { Dropdown } from 'antd' import { Dropdown, Input } from 'antd'
import { ItemType } from 'antd/es/menu/interface' import { ItemType } from 'antd/es/menu/interface'
import { last } from 'lodash' import { isEmpty, last } from 'lodash'
import { FC, useCallback } from 'react' import { FC, useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
@ -24,6 +24,7 @@ interface Props {
const Assistants: FC<Props> = ({ activeAssistant, setActiveAssistant, onCreateAssistant }) => { const Assistants: FC<Props> = ({ activeAssistant, setActiveAssistant, onCreateAssistant }) => {
const { assistants, removeAssistant, addAssistant, updateAssistants } = useAssistants() const { assistants, removeAssistant, addAssistant, updateAssistants } = useAssistants()
const generating = useAppSelector((state) => state.runtime.generating) const generating = useAppSelector((state) => state.runtime.generating)
const [search, setSearch] = useState('')
const { updateAssistant, removeAllTopics } = useAssistant(activeAssistant.id) const { updateAssistant, removeAllTopics } = useAssistant(activeAssistant.id)
const { t } = useTranslation() const { t } = useTranslation()
@ -104,9 +105,35 @@ const Assistants: FC<Props> = ({ activeAssistant, setActiveAssistant, onCreateAs
[generating, setActiveAssistant, t] [generating, setActiveAssistant, t]
) )
const list = assistants.filter((assistant) => assistant.name?.toLowerCase().includes(search.toLowerCase().trim()))
const onSearch = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
if (list.length === 1) {
onSwitchAssistant(list[0])
setSearch('')
}
}
}
return ( return (
<Container> <Container>
<DragableList list={assistants} onUpdate={updateAssistants}> {assistants.length >= 10 && (
<SearchContainer>
<Input
placeholder={t('chat.assistant.search.placeholder')}
variant="filled"
prefix={<SearchOutlined style={{ color: 'var(--color-icon)' }} />}
suffix={<CommandKey>+K</CommandKey>}
value={search}
onChange={(e) => setSearch(e.target.value)}
style={{ borderRadius: 4 }}
onKeyDown={onSearch}
allowClear
/>
</SearchContainer>
)}
<DragableList list={list} onUpdate={updateAssistants} droppableProps={{ isDropDisabled: !isEmpty(search) }}>
{(assistant) => { {(assistant) => {
const isCurrent = assistant.id === activeAssistant?.id const isCurrent = assistant.id === activeAssistant?.id
return ( return (
@ -187,17 +214,12 @@ const ArrowRightButton = styled.div`
min-height: 22px; min-height: 22px;
border-radius: 4px; border-radius: 4px;
position: absolute; position: absolute;
background-color: var(--color-background);
right: 9px; right: 9px;
top: 6px; top: 6px;
.anticon { .anticon {
font-size: 14px; font-size: 14px;
} }
&:hover {
background-color: var(--color-background);
}
&.active {
background-color: var(--color-background);
}
` `
const TopicCount = styled.div` const TopicCount = styled.div`
@ -215,4 +237,18 @@ const TopicCount = styled.div`
align-items: center; align-items: center;
` `
const SearchContainer = styled.div`
margin: 0 10px;
margin-bottom: 10px;
`
const CommandKey = styled.div`
color: var(--color-text-3);
font-size: 11px;
padding: 2px 5px;
border-radius: 4px;
background-color: var(--color-background-mute);
margin-right: -4px;
`
export default Assistants export default Assistants