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:
parent
6bf98f6db3
commit
11b2cd88b7
@ -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}
|
||||||
|
|||||||
@ -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: '智能体',
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user