mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-07-25 13:06:53 +00:00
Co-authored-by: Fangyin Cheng <staneyffer@gmail.com> Co-authored-by: 谨欣 <echo.cmy@antgroup.com> Co-authored-by: 严志勇 <yanzhiyong@tiansuixiansheng.com> Co-authored-by: yanzhiyong <932374019@qq.com>
113 lines
3.1 KiB
TypeScript
113 lines
3.1 KiB
TypeScript
import { ChatContext } from '@/app/chat-context';
|
|
import { apiInterceptors, getDocumentList } from '@/client/api';
|
|
import { IDocument } from '@/types/knowledge';
|
|
import { SendOutlined } from '@ant-design/icons';
|
|
import { Button, Input } from 'antd';
|
|
import { PropsWithChildren, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
import DocList from '../chat/doc-list';
|
|
import DocUpload from '../chat/doc-upload';
|
|
import PromptBot from './prompt-bot';
|
|
|
|
type TextAreaProps = Omit<Parameters<typeof Input.TextArea>[0], 'value' | 'onPressEnter' | 'onChange' | 'onSubmit'>;
|
|
|
|
interface Props {
|
|
onSubmit: (val: string) => void;
|
|
handleFinish?: (val: boolean) => void;
|
|
loading?: boolean;
|
|
placeholder?: string;
|
|
}
|
|
|
|
function CompletionInput({
|
|
children,
|
|
loading,
|
|
onSubmit,
|
|
handleFinish,
|
|
placeholder,
|
|
...props
|
|
}: PropsWithChildren<Props & TextAreaProps>) {
|
|
const { dbParam, scene } = useContext(ChatContext);
|
|
|
|
const [userInput, setUserInput] = useState('');
|
|
const showUpload = useMemo(() => scene === 'chat_knowledge', [scene]);
|
|
const [documents, setDocuments] = useState<IDocument[]>([]);
|
|
const uploadCountRef = useRef(0);
|
|
|
|
useEffect(() => {
|
|
showUpload && fetchDocuments();
|
|
}, [dbParam]);
|
|
|
|
async function fetchDocuments() {
|
|
if (!dbParam) {
|
|
return null;
|
|
}
|
|
const [_, data] = await apiInterceptors(
|
|
getDocumentList(dbParam, {
|
|
page: 1,
|
|
page_size: uploadCountRef.current,
|
|
}),
|
|
);
|
|
setDocuments(data?.data || []);
|
|
}
|
|
|
|
const onUploadFinish = async () => {
|
|
uploadCountRef.current += 1;
|
|
await fetchDocuments();
|
|
};
|
|
|
|
return (
|
|
<div className='flex-1 relative'>
|
|
<DocList documents={documents} dbParam={dbParam} />
|
|
{showUpload && (
|
|
<DocUpload handleFinish={handleFinish} onUploadFinish={onUploadFinish} className='absolute z-10 top-2 left-2' />
|
|
)}
|
|
<Input.TextArea
|
|
className={`flex-1 ${showUpload ? 'pl-10' : ''} pr-10`}
|
|
size='large'
|
|
value={userInput}
|
|
autoSize={{ minRows: 1, maxRows: 4 }}
|
|
{...props}
|
|
onPressEnter={e => {
|
|
if (!userInput.trim()) return;
|
|
if (e.keyCode === 13) {
|
|
if (e.shiftKey) {
|
|
e.preventDefault();
|
|
setUserInput(state => state + '\n');
|
|
return;
|
|
}
|
|
onSubmit(userInput);
|
|
setTimeout(() => {
|
|
setUserInput('');
|
|
}, 0);
|
|
}
|
|
}}
|
|
onChange={e => {
|
|
if (typeof props.maxLength === 'number') {
|
|
setUserInput(e.target.value.substring(0, props.maxLength));
|
|
return;
|
|
}
|
|
setUserInput(e.target.value);
|
|
}}
|
|
placeholder={placeholder}
|
|
/>
|
|
<Button
|
|
className='ml-2 flex items-center justify-center absolute right-0 bottom-0'
|
|
size='large'
|
|
type='text'
|
|
loading={loading}
|
|
icon={<SendOutlined />}
|
|
onClick={() => {
|
|
onSubmit(userInput);
|
|
}}
|
|
/>
|
|
<PromptBot
|
|
submit={prompt => {
|
|
setUserInput(userInput + prompt);
|
|
}}
|
|
/>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default CompletionInput;
|