diff --git a/web/src/components/file-icon/index.less b/web/src/components/file-icon/index.less
new file mode 100644
index 000000000..a549a0615
--- /dev/null
+++ b/web/src/components/file-icon/index.less
@@ -0,0 +1,3 @@
+.thumbnailImg {
+ max-width: 20px;
+}
diff --git a/web/src/components/file-icon/index.tsx b/web/src/components/file-icon/index.tsx
new file mode 100644
index 000000000..6a84fc78e
--- /dev/null
+++ b/web/src/components/file-icon/index.tsx
@@ -0,0 +1,25 @@
+import { getExtension } from '@/utils/document-util';
+import SvgIcon from '../svg-icon';
+
+import { useSelectFileThumbnails } from '@/hooks/knowledge-hooks';
+import styles from './index.less';
+
+interface IProps {
+ name: string;
+ id: string;
+}
+
+const FileIcon = ({ name, id }: IProps) => {
+ const fileExtension = getExtension(name);
+ // TODO: replace this line with react query
+ const fileThumbnails = useSelectFileThumbnails();
+ const fileThumbnail = fileThumbnails[id];
+
+ return fileThumbnail ? (
+
+ ) : (
+
+ );
+};
+
+export default FileIcon;
diff --git a/web/src/components/message-input/index.less b/web/src/components/message-input/index.less
new file mode 100644
index 000000000..5b203d69e
--- /dev/null
+++ b/web/src/components/message-input/index.less
@@ -0,0 +1,15 @@
+.messageInputWrapper {
+ margin-right: 20px;
+ .documentCard {
+ :global(.ant-card-body) {
+ padding: 10px;
+ position: relative;
+ }
+ }
+ .deleteIcon {
+ position: absolute;
+ right: -4px;
+ top: -4px;
+ color: #d92d20;
+ }
+}
diff --git a/web/src/components/message-input/index.tsx b/web/src/components/message-input/index.tsx
index 7885f49ae..2b86c50fa 100644
--- a/web/src/components/message-input/index.tsx
+++ b/web/src/components/message-input/index.tsx
@@ -2,13 +2,36 @@ import { Authorization } from '@/constants/authorization';
import { useTranslate } from '@/hooks/common-hooks';
import { useRemoveNextDocument } from '@/hooks/document-hooks';
import { getAuthorization } from '@/utils/authorization-util';
-import { PlusOutlined } from '@ant-design/icons';
+import { getExtension } from '@/utils/document-util';
+import {
+ CloseCircleOutlined,
+ LoadingOutlined,
+ PlusOutlined,
+ UploadOutlined,
+} from '@ant-design/icons';
import type { GetProp, UploadFile } from 'antd';
-import { Button, Flex, Input, Upload, UploadProps } from 'antd';
+import {
+ Button,
+ Card,
+ Flex,
+ Input,
+ List,
+ Space,
+ Spin,
+ Typography,
+ Upload,
+ UploadProps,
+} from 'antd';
import get from 'lodash/get';
import { ChangeEventHandler, useCallback, useState } from 'react';
+import FileIcon from '../file-icon';
+
+import styles from './index.less';
type FileType = Parameters>[0];
+const { Text } = Typography;
+
+const getFileId = (file: UploadFile) => get(file, 'response.data.0');
interface IProps {
disabled: boolean;
@@ -49,7 +72,6 @@ const MessageInput = ({
};
const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
- console.log('🚀 ~ newFileList:', newFileList);
setFileList(newFileList);
};
const isUploadingFile = fileList.some((x) => x.status === 'uploading');
@@ -65,10 +87,13 @@ const MessageInput = ({
}, [fileList, onPressEnter, isUploadingFile]);
const handleRemove = useCallback(
- (file: UploadFile) => {
+ async (file: UploadFile) => {
const ids = get(file, 'response.data', []);
if (ids.length) {
- removeDocument(ids[0]);
+ await removeDocument(ids[0]);
+ setFileList((preList) => {
+ return preList.filter((x) => getFileId(x) !== ids[0]);
+ });
}
},
[removeDocument],
@@ -82,26 +107,43 @@ const MessageInput = ({
);
return (
-
+
- {t('send')}
-
+
+
+ }>
+
+
+
}
onPressEnter={handlePressEnter}
onChange={onInputChange}
/>
-
{fileList.length >= 8 ? null : uploadButton}
-
+ */}
+ {fileList.length > 0 && (
+ {
+ const fileExtension = getExtension(item.name);
+
+ return (
+
+
+ <>
+
+ {item.status === 'uploading' || !item.response ? (
+
+ }
+ />
+ ) : (
+
+ )}
+
+
+ {item.name}
+
+ {item.percent !== 100 ? (
+ '上传中'
+ ) : !item.response ? (
+ '解析中'
+ ) : (
+
+ {fileExtension?.toUpperCase()},
+
+ )}
+
+
+ >
+
+ {item.status !== 'uploading' && (
+ handleRemove(item)}
+ />
+ )}
+
+
+ );
+ }}
+ />
+ )}
);
};
diff --git a/web/src/components/message-item/index.tsx b/web/src/components/message-item/index.tsx
index c0bc4a9b1..89e0a7ede 100644
--- a/web/src/components/message-item/index.tsx
+++ b/web/src/components/message-item/index.tsx
@@ -14,9 +14,9 @@ import {
import MarkdownContent from '@/pages/chat/markdown-content';
import { getExtension, isImage } from '@/utils/document-util';
import { Avatar, Button, Flex, List, Typography } from 'antd';
+import FileIcon from '../file-icon';
import IndentedTreeModal from '../indented-tree/modal';
import NewDocumentLink from '../new-document-link';
-import SvgIcon from '../svg-icon';
import styles from './index.less';
const { Text } = Typography;
@@ -126,23 +126,13 @@ const MessageItem = ({
bordered
dataSource={referenceDocumentList}
renderItem={(item) => {
- const fileThumbnail = fileThumbnails[item.doc_id];
-
- const fileExtension = getExtension(item.doc_name);
return (
- {fileThumbnail ? (
-
- ) : (
-
- )}
+
{
+ // TODO:
const fileThumbnail =
documentThumbnails[item.id] || fileThumbnails[item.id];
const fileExtension = getExtension(item.name);
return (
- {fileThumbnail ? (
-
- ) : (
-
- )}
+
{isImage(fileExtension) ? (