From 9703633a57fdd8cead9e1efe3fd1d538d91d56c3 Mon Sep 17 00:00:00 2001 From: balibabu Date: Tue, 30 Apr 2024 18:43:26 +0800 Subject: [PATCH] fix: filter knowledge list by keywords and clear the selected file list after the file is uploaded successfully and add ellipsis pattern to chunk list (#628) ### What problem does this PR solve? #627 fix: filter knowledge list by keywords fix: clear the selected file list after the file is uploaded successfully feat: add ellipsis pattern to chunk list ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --- .../components/chunk-method-modal/index.tsx | 2 + .../components/file-upload-modal/index.tsx | 14 +- web/src/hooks/knowledgeHook.ts | 8 +- web/src/less/mixins.less | 14 ++ web/src/locales/en.ts | 3 + web/src/locales/zh-traditional.ts | 3 + web/src/locales/zh.ts | 3 + .../components/chunk-card/index.less | 4 + .../components/chunk-card/index.tsx | 14 +- .../components/chunk-toolbar/index.tsx | 19 ++- .../components/knowledge-chunk/constant.ts | 4 + .../components/knowledge-chunk/hooks.ts | 12 ++ .../components/knowledge-chunk/index.tsx | 19 ++- .../knowledge-file/document-toolbar.tsx | 3 - .../components/knowledge-file/index.less | 10 +- .../components/knowledge-file/index.tsx | 3 +- .../file-manager/file-upload-modal/index.less | 8 -- .../file-manager/file-upload-modal/index.tsx | 136 ------------------ web/src/pages/file-manager/index.tsx | 2 +- web/src/pages/knowledge/hooks.ts | 19 +++ web/src/pages/knowledge/index.tsx | 25 ++-- 21 files changed, 154 insertions(+), 171 deletions(-) create mode 100644 web/src/pages/add-knowledge/components/knowledge-chunk/constant.ts delete mode 100644 web/src/pages/file-manager/file-upload-modal/index.less delete mode 100644 web/src/pages/file-manager/file-upload-modal/index.tsx create mode 100644 web/src/pages/knowledge/hooks.ts diff --git a/web/src/components/chunk-method-modal/index.tsx b/web/src/components/chunk-method-modal/index.tsx index 7490b9b5d..ebb5e30cc 100644 --- a/web/src/components/chunk-method-modal/index.tsx +++ b/web/src/components/chunk-method-modal/index.tsx @@ -48,6 +48,7 @@ const ChunkMethodModal: React.FC = ({ visible, documentExtension, parserConfig, + loading, }) => { const { parserList, handleChange, selectedTag } = useFetchParserListOnMount( documentId, @@ -109,6 +110,7 @@ const ChunkMethodModal: React.FC = ({ onOk={handleOk} onCancel={hideModal} afterClose={afterClose} + confirmLoading={loading} > diff --git a/web/src/components/file-upload-modal/index.tsx b/web/src/components/file-upload-modal/index.tsx index 68e6655a4..1707724ea 100644 --- a/web/src/components/file-upload-modal/index.tsx +++ b/web/src/components/file-upload-modal/index.tsx @@ -68,15 +68,20 @@ const FileUploadModal = ({ const [fileList, setFileList] = useState([]); const [directoryFileList, setDirectoryFileList] = useState([]); + const clearFileList = () => { + setFileList([]); + setDirectoryFileList([]); + }; + const onOk = async () => { const ret = await onFileUploadOk?.([...fileList, ...directoryFileList]); - if (ret !== undefined && ret === 0) { - setFileList([]); - setDirectoryFileList([]); - } return ret; }; + const afterClose = () => { + clearFileList(); + }; + const items: TabsProps['items'] = [ { key: '1', @@ -110,6 +115,7 @@ const FileUploadModal = ({ onOk={onOk} onCancel={hideModal} confirmLoading={loading} + afterClose={afterClose} > { }, [fetchKnowledgeBaseConfiguration]); }; +export const useSelectKnowledgeList = () => { + const knowledgeModel = useSelector((state) => state.knowledgeModel); + const { data = [] } = knowledgeModel; + return data; +}; + export const useFetchKnowledgeList = ( shouldFilterListWithoutDocument: boolean = false, ) => { const dispatch = useDispatch(); const loading = useOneNamespaceEffectsLoading('knowledgeModel', ['getList']); - const knowledgeModel = useSelector((state: any) => state.knowledgeModel); + const knowledgeModel = useSelector((state) => state.knowledgeModel); const { data = [] } = knowledgeModel; const list: IKnowledge[] = useMemo(() => { return shouldFilterListWithoutDocument diff --git a/web/src/less/mixins.less b/web/src/less/mixins.less index ba363ec45..a80a06935 100644 --- a/web/src/less/mixins.less +++ b/web/src/less/mixins.less @@ -42,3 +42,17 @@ } } } + +.textEllipsis() { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.multipleLineEllipsis(@line) { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: @line; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index 8d824ab56..46ae5428d 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -64,6 +64,7 @@ export default { name: 'Name', namePlaceholder: 'Please input name!', doc: 'Docs', + searchKnowledgePlaceholder: 'Search', }, knowledgeDetails: { dataset: 'Dataset', @@ -278,6 +279,8 @@ export default { keyword: 'Keyword', function: 'Function', chunkMessage: 'Please input value!', + full: 'Full text', + ellipse: 'Ellipse', }, chat: { createAssistant: 'Create an Assistant', diff --git a/web/src/locales/zh-traditional.ts b/web/src/locales/zh-traditional.ts index 467afb754..1f6a73c1d 100644 --- a/web/src/locales/zh-traditional.ts +++ b/web/src/locales/zh-traditional.ts @@ -64,6 +64,7 @@ export default { name: '名稱', namePlaceholder: '請輸入名稱', doc: '文件', + searchKnowledgePlaceholder: '搜索', }, knowledgeDetails: { dataset: '數據集', @@ -251,6 +252,8 @@ export default { keyword: '關鍵詞', function: '函數', chunkMessage: '請輸入值!', + full: '全文', + ellipse: '省略', }, chat: { createAssistant: '新建助理', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 1a44c34cf..ab0a0fbc7 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -64,6 +64,7 @@ export default { name: '名称', namePlaceholder: '请输入名称', doc: '文档', + searchKnowledgePlaceholder: '搜索', }, knowledgeDetails: { dataset: '数据集', @@ -268,6 +269,8 @@ export default { keyword: '关键词', function: '函数', chunkMessage: '请输入值!', + full: '全文', + ellipse: '省略', }, chat: { createAssistant: '新建助理', diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.less b/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.less index 9bb4f5b4a..101aa5665 100644 --- a/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.less +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.less @@ -14,6 +14,10 @@ .chunkText; } +.contentEllipsis { + .multipleLineEllipsis(3); +} + .chunkCard { width: 100%; } diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.tsx b/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.tsx index d1d9106da..9a00b359c 100644 --- a/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.tsx @@ -4,6 +4,7 @@ import { Card, Checkbox, CheckboxProps, Flex, Popover, Switch } from 'antd'; import classNames from 'classnames'; import { useState } from 'react'; +import { ChunkTextMode } from '../../constant'; import styles from './index.less'; interface IProps { @@ -14,6 +15,7 @@ interface IProps { handleCheckboxClick: (chunkId: string, checked: boolean) => void; selected: boolean; clickChunkCard: (chunkId: string) => void; + textMode: ChunkTextMode; } const ChunkCard = ({ @@ -24,6 +26,7 @@ const ChunkCard = ({ switchChunk, selected, clickChunkCard, + textMode, }: IProps) => { const available = Number(item.available_int); const [enabled, setEnabled] = useState(available === 1); @@ -68,8 +71,15 @@ const ChunkCard = ({ onDoubleClick={handleContentDoubleClick} onClick={handleContentClick} className={styles.content} - dangerouslySetInnerHTML={{ __html: item.content_with_weight }} - > + > +
+ +
diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-toolbar/index.tsx b/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-toolbar/index.tsx index ead23c48c..590910259 100644 --- a/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-toolbar/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-toolbar/index.tsx @@ -22,12 +22,18 @@ import { Popover, Radio, RadioChangeEvent, + Segmented, + SegmentedProps, Space, + Typography, } from 'antd'; import { ChangeEventHandler, useCallback, useMemo, useState } from 'react'; import { Link, useDispatch, useSelector } from 'umi'; +import { ChunkTextMode } from '../../constant'; import { ChunkModelState } from '../../model'; +const { Text } = Typography; + interface IProps { checked: boolean; getChunkList: () => void; @@ -35,6 +41,7 @@ interface IProps { createChunk: () => void; removeChunk: () => void; switchChunk: (available: number) => void; + changeChunkTextMode(mode: ChunkTextMode): void; } const ChunkToolBar = ({ @@ -44,6 +51,7 @@ const ChunkToolBar = ({ createChunk, removeChunk, switchChunk, + changeChunkTextMode, }: IProps) => { const { documentInfo, available, searchString }: ChunkModelState = useSelector((state: any) => state.chunkModel); @@ -170,9 +178,18 @@ const ChunkToolBar = ({ - {documentInfo.name} + + {documentInfo.name} +
+ ), - // disabled: true, }, ]; }, [showDocumentUploadModal, showCreateModal, t]); diff --git a/web/src/pages/add-knowledge/components/knowledge-file/index.less b/web/src/pages/add-knowledge/components/knowledge-file/index.less index 6440b2ea3..fa817e1a8 100644 --- a/web/src/pages/add-knowledge/components/knowledge-file/index.less +++ b/web/src/pages/add-knowledge/components/knowledge-file/index.less @@ -1,6 +1,12 @@ .datasetWrapper { - padding: 30px; - flex: 1; + padding: 30px 30px 0; + height: 100%; +} + +.documentTable { + tbody { + // height: calc(100vh - 508px); + } } .filter { diff --git a/web/src/pages/add-knowledge/components/knowledge-file/index.tsx b/web/src/pages/add-knowledge/components/knowledge-file/index.tsx index 4b8b7b3c1..47a63cc30 100644 --- a/web/src/pages/add-knowledge/components/knowledge-file/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-file/index.tsx @@ -179,7 +179,8 @@ const KnowledgeFile = () => { // loading={loading} pagination={pagination} rowSelection={rowSelection} - scroll={{ scrollToFirstRowOnChange: true, x: 1300, y: 'fill' }} + className={styles.documentTable} + scroll={{ scrollToFirstRowOnChange: true, x: 1300 }} /> >; -}) => { - const { t } = useTranslate('fileManager'); - const props: UploadProps = { - multiple: true, - onRemove: (file) => { - const index = fileList.indexOf(file); - const newFileList = fileList.slice(); - newFileList.splice(index, 1); - setFileList(newFileList); - }, - beforeUpload: (file) => { - setFileList((pre) => { - return [...pre, file]; - }); - - return false; - }, - directory, - fileList, - }; - - return ( - -

- -

-

{t('uploadTitle')}

-

{t('uploadDescription')}

-
- ); -}; - -const FileUploadModal = ({ - visible, - hideModal, - loading, - onOk: onFileUploadOk, -}: IModalProps) => { - const { t } = useTranslate('fileManager'); - const [value, setValue] = useState('local'); - const [fileList, setFileList] = useState([]); - const [directoryFileList, setDirectoryFileList] = useState([]); - - const onOk = async () => { - const ret = await onFileUploadOk?.([...fileList, ...directoryFileList]); - console.info(ret); - if (ret !== undefined && ret === 0) { - setFileList([]); - setDirectoryFileList([]); - } - return ret; - }; - - const items: TabsProps['items'] = [ - { - key: '1', - label: t('file'), - children: ( - - ), - }, - { - key: '2', - label: t('directory'), - children: ( - - ), - }, - ]; - - return ( - <> - - - - {value === 'local' ? ( - - ) : ( - t('comingSoon', { keyPrefix: 'common' }) - )} - - - - ); -}; - -export default FileUploadModal; diff --git a/web/src/pages/file-manager/index.tsx b/web/src/pages/file-manager/index.tsx index ebeff5481..e934f0136 100644 --- a/web/src/pages/file-manager/index.tsx +++ b/web/src/pages/file-manager/index.tsx @@ -16,13 +16,13 @@ import { useSelectFileListLoading, } from './hooks'; +import FileUploadModal from '@/components/file-upload-modal'; import RenameModal from '@/components/rename-modal'; import SvgIcon from '@/components/svg-icon'; import { useTranslate } from '@/hooks/commonHooks'; import { formatNumberWithThousandsSeparator } from '@/utils/commonUtil'; import { getExtension } from '@/utils/documentUtils'; import ConnectToKnowledgeModal from './connect-to-knowledge-modal'; -import FileUploadModal from './file-upload-modal'; import FolderCreateModal from './folder-create-modal'; import styles from './index.less'; diff --git a/web/src/pages/knowledge/hooks.ts b/web/src/pages/knowledge/hooks.ts new file mode 100644 index 000000000..b752fb34d --- /dev/null +++ b/web/src/pages/knowledge/hooks.ts @@ -0,0 +1,19 @@ +import { useSelectKnowledgeList } from '@/hooks/knowledgeHook'; +import { useState } from 'react'; + +export const useSearchKnowledge = () => { + const [searchString, setSearchString] = useState(''); + + const handleInputChange = (e: React.ChangeEvent) => { + setSearchString(e.target.value); + }; + return { + searchString, + handleInputChange, + }; +}; + +export const useSelectKnowledgeListByKeywords = (keywords: string) => { + const list = useSelectKnowledgeList(); + return list.filter((x) => x.name.includes(keywords)); +}; diff --git a/web/src/pages/knowledge/index.tsx b/web/src/pages/knowledge/index.tsx index 9206c2202..12fa6cf52 100644 --- a/web/src/pages/knowledge/index.tsx +++ b/web/src/pages/knowledge/index.tsx @@ -1,16 +1,19 @@ import ModalManager from '@/components/modal-manager'; import { useFetchKnowledgeList } from '@/hooks/knowledgeHook'; import { useSelectUserInfo } from '@/hooks/userSettingHook'; -import { PlusOutlined } from '@ant-design/icons'; -import { Button, Empty, Flex, Space, Spin } from 'antd'; +import { PlusOutlined, SearchOutlined } from '@ant-design/icons'; +import { Button, Empty, Flex, Input, Space, Spin } from 'antd'; import KnowledgeCard from './knowledge-card'; import KnowledgeCreatingModal from './knowledge-creating-modal'; import { useTranslation } from 'react-i18next'; +import { useSearchKnowledge, useSelectKnowledgeListByKeywords } from './hooks'; import styles from './index.less'; -const Knowledge = () => { - const { list, loading } = useFetchKnowledgeList(); +const KnowledgeList = () => { + const { searchString, handleInputChange } = useSearchKnowledge(); + const { loading } = useFetchKnowledgeList(); + const list = useSelectKnowledgeListByKeywords(searchString); const userInfo = useSelectUserInfo(); const { t } = useTranslation('translation', { keyPrefix: 'knowledgeList' }); @@ -24,9 +27,15 @@ const Knowledge = () => {

{t('description')}

- {/* */} + } + /> + {({ visible, hideModal, showModal }) => ( <> @@ -70,4 +79,4 @@ const Knowledge = () => { ); }; -export default Knowledge; +export default KnowledgeList;