mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-08-13 21:56:02 +08:00
feat: add batch operations for document list (#302)
### What problem does this PR solve? document list needs to be batch operated Issue link: #301 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
1ff5d9d55b
commit
533ac3b534
9
web/src/assets/svg/cancel.svg
Normal file
9
web/src/assets/svg/cancel.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M0.5 11C0.5 5.20101 5.20101 0.5 11 0.5C16.799 0.5 21.5 5.20101 21.5 11C21.5 16.799 16.799 21.5 11 21.5C5.20101 21.5 0.5 16.799 0.5 11Z"
|
||||
fill="#FEF3F2" />
|
||||
<path
|
||||
d="M0.5 11C0.5 5.20101 5.20101 0.5 11 0.5C16.799 0.5 21.5 5.20101 21.5 11C21.5 16.799 16.799 21.5 11 21.5C5.20101 21.5 0.5 16.799 0.5 11Z"
|
||||
stroke="#FECDCA" />
|
||||
<path d="M14 8L8 14M8 8L14 14" stroke="#F04438" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
After Width: | Height: | Size: 591 B |
5
web/src/assets/svg/delete.svg
Normal file
5
web/src/assets/svg/delete.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M13.3333 5.00002V4.33335C13.3333 3.39993 13.3333 2.93322 13.1517 2.5767C12.9919 2.2631 12.7369 2.00813 12.4233 1.84834C12.0668 1.66669 11.6001 1.66669 10.6667 1.66669H9.33333C8.39991 1.66669 7.9332 1.66669 7.57668 1.84834C7.26308 2.00813 7.00811 2.2631 6.84832 2.5767C6.66667 2.93322 6.66667 3.39993 6.66667 4.33335V5.00002M8.33333 9.58335V13.75M11.6667 9.58335V13.75M2.5 5.00002H17.5M15.8333 5.00002V14.3334C15.8333 15.7335 15.8333 16.4336 15.5608 16.9683C15.3212 17.4387 14.9387 17.8212 14.4683 18.0609C13.9335 18.3334 13.2335 18.3334 11.8333 18.3334H8.16667C6.76654 18.3334 6.06647 18.3334 5.53169 18.0609C5.06129 17.8212 4.67883 17.4387 4.43915 16.9683C4.16667 16.4336 4.16667 15.7335 4.16667 14.3334V5.00002"
|
||||
stroke="#475467" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
After Width: | Height: | Size: 935 B |
6
web/src/assets/svg/disable.svg
Normal file
6
web/src/assets/svg/disable.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg t="1712735718884" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8042"
|
||||
id="mx_n_1712735718887" width="22" height="22">
|
||||
<path
|
||||
d="M222.634667 272.298667A382.4 382.4 0 0 0 138.666667 512c0 212.117333 171.904 384 384 384 90.666667 0 174.016-31.424 239.701333-83.968l-539.733333-539.733333z m60.330666-60.330667l539.733334 539.733333A382.4 382.4 0 0 0 906.666667 512c0-212.117333-171.904-384-384-384-90.666667 0-174.016 31.424-239.701334 83.968zM53.333333 512c0-259.221333 210.090667-469.333333 469.333334-469.333333 259.221333 0 469.333333 210.090667 469.333333 469.333333 0 259.221333-210.090667 469.333333-469.333333 469.333333-259.221333 0-469.333333-210.090667-469.333334-469.333333z"
|
||||
fill="#F04438" p-id="8043"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 800 B |
10
web/src/assets/svg/enable.svg
Normal file
10
web/src/assets/svg/enable.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg t="1712735583481" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6804"
|
||||
width="22" height="22">
|
||||
<path
|
||||
d="M512 0a512 512 0 1 0 0 1024A512 512 0 0 0 512 0z m0 910.222222A398.222222 398.222222 0 1 1 512 113.777778a398.222222 398.222222 0 0 1 0 796.444444z"
|
||||
fill="#ABEFC6" p-id="6805"></path>
|
||||
|
||||
<path
|
||||
d="M448.056889 584.305778L322.389333 458.638222 243.541333 537.543111l205.596445 205.539556h0.056889l0.512 0.512 325.859555-325.859556-80.440889-80.440889z"
|
||||
fill="#17B26A" p-id="6806"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 587 B |
@ -1,15 +1,11 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_490_5128)">
|
||||
<path
|
||||
d="M10.0001 18.3334C14.6025 18.3334 18.3334 14.6025 18.3334 10.0001C18.3334 5.39771 14.6025 1.66675 10.0001 1.66675C5.39771 1.66675 1.66675 5.39771 1.66675 10.0001C1.66675 14.6025 5.39771 18.3334 10.0001 18.3334Z"
|
||||
stroke="#17B26A" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path
|
||||
d="M7.91675 7.47119C7.91675 7.07345 7.91675 6.87459 7.99987 6.76356C8.0723 6.66681 8.18318 6.60628 8.30373 6.59767C8.44207 6.58779 8.60935 6.69533 8.94392 6.91041L12.8777 9.4393C13.1681 9.62593 13.3132 9.71925 13.3634 9.83791C13.4072 9.94159 13.4072 10.0586 13.3634 10.1623C13.3132 10.2809 13.1681 10.3742 12.8777 10.5609L8.94392 13.0898C8.60935 13.3048 8.44207 13.4124 8.30373 13.4025C8.18318 13.3939 8.0723 13.3334 7.99987 13.2366C7.91675 13.1256 7.91675 12.9267 7.91675 12.529V7.47119Z"
|
||||
stroke="#17B26A" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_490_5128">
|
||||
<rect width="20" height="20" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M11 21.5C5.20101 21.5 0.5 16.799 0.5 11C0.5 5.20101 5.20101 0.5 11 0.5C16.799 0.5 21.5 5.20101 21.5 11C21.5 16.799 16.799 21.5 11 21.5Z"
|
||||
fill="#ECFDF3" />
|
||||
<path
|
||||
d="M11 21.5C5.20101 21.5 0.5 16.799 0.5 11C0.5 5.20101 5.20101 0.5 11 0.5C16.799 0.5 21.5 5.20101 21.5 11C21.5 16.799 16.799 21.5 11 21.5Z"
|
||||
stroke="#ABEFC6" />
|
||||
<path
|
||||
d="M7.5 7.49482C7.5 7.00924 7.5 6.76644 7.60125 6.63261C7.68945 6.51601 7.82426 6.44386 7.9702 6.43515C8.13772 6.42515 8.33973 6.55982 8.74376 6.82918L14.0015 10.3344C14.3354 10.5569 14.5023 10.6682 14.5605 10.8085C14.6113 10.9311 14.6113 11.0689 14.5605 11.1915C14.5023 11.3318 14.3354 11.4431 14.0015 11.6656L8.74376 15.1708C8.33973 15.4402 8.13772 15.5749 7.9702 15.5649C7.82426 15.5561 7.68945 15.484 7.60125 15.3674C7.5 15.2336 7.5 14.9908 7.5 14.5052V7.49482Z"
|
||||
stroke="#17B26A" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.0 KiB |
@ -155,23 +155,26 @@ export const useSetDocumentParser = () => {
|
||||
return setDocumentParser;
|
||||
};
|
||||
|
||||
export const useRemoveDocument = (documentId: string) => {
|
||||
export const useRemoveDocument = () => {
|
||||
const dispatch = useDispatch();
|
||||
const { knowledgeId } = useGetKnowledgeSearchParams();
|
||||
|
||||
const removeDocument = useCallback(() => {
|
||||
try {
|
||||
return dispatch<any>({
|
||||
type: 'kFModel/document_rm',
|
||||
payload: {
|
||||
doc_id: documentId,
|
||||
kb_id: knowledgeId,
|
||||
},
|
||||
});
|
||||
} catch (errorInfo) {
|
||||
console.log('Failed:', errorInfo);
|
||||
}
|
||||
}, [dispatch, knowledgeId, documentId]);
|
||||
const removeDocument = useCallback(
|
||||
(documentId: string) => {
|
||||
try {
|
||||
return dispatch<any>({
|
||||
type: 'kFModel/document_rm',
|
||||
payload: {
|
||||
doc_id: documentId,
|
||||
kb_id: knowledgeId,
|
||||
},
|
||||
});
|
||||
} catch (errorInfo) {
|
||||
console.log('Failed:', errorInfo);
|
||||
}
|
||||
},
|
||||
[dispatch, knowledgeId],
|
||||
);
|
||||
|
||||
return removeDocument;
|
||||
};
|
||||
@ -204,11 +207,11 @@ export const useRunDocument = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const runDocumentByIds = useCallback(
|
||||
(ids: string[]) => {
|
||||
(payload: any) => {
|
||||
try {
|
||||
return dispatch<any>({
|
||||
type: 'kFModel/document_run',
|
||||
payload: { doc_ids: ids, run: 1 },
|
||||
payload,
|
||||
});
|
||||
} catch (errorInfo) {
|
||||
console.log('Failed:', errorInfo);
|
||||
|
@ -75,7 +75,8 @@ export default {
|
||||
chunkNumber: 'Chunk Number',
|
||||
uploadDate: 'Upload Date',
|
||||
chunkMethod: 'Chunk Method',
|
||||
enabled: 'Enabled',
|
||||
enabled: 'Enable',
|
||||
disabled: 'Disable',
|
||||
action: 'Action',
|
||||
parsingStatus: 'Parsing Status',
|
||||
processBeginAt: 'Process Begin At',
|
||||
@ -102,6 +103,7 @@ export default {
|
||||
view: 'View',
|
||||
filesSelected: 'Files Selected',
|
||||
upload: 'Upload',
|
||||
run: 'Run',
|
||||
runningStatus0: 'UNSTART',
|
||||
runningStatus1: 'Parsing',
|
||||
runningStatus2: 'CANCEL',
|
||||
@ -130,6 +132,8 @@ export default {
|
||||
uploadDescription:
|
||||
'Support for a single or bulk upload. Strictly prohibited from uploading company data or other banned files.',
|
||||
chunk: 'Chunk',
|
||||
bulk: 'Bulk',
|
||||
cancel: 'Cancel',
|
||||
},
|
||||
knowledgeConfiguration: {
|
||||
titleDescription:
|
||||
|
@ -75,6 +75,7 @@ export default {
|
||||
uploadDate: '上传日期',
|
||||
chunkMethod: '解析方法',
|
||||
enabled: '启用',
|
||||
disabled: '禁用',
|
||||
action: '动作',
|
||||
parsingStatus: '解析状态',
|
||||
processBeginAt: '流程开始于',
|
||||
@ -100,6 +101,7 @@ export default {
|
||||
view: '看法',
|
||||
filesSelected: '选定的文件',
|
||||
upload: '上传',
|
||||
run: '启动',
|
||||
runningStatus0: '未启动',
|
||||
runningStatus1: '解析中',
|
||||
runningStatus2: '取消',
|
||||
@ -127,6 +129,8 @@ export default {
|
||||
uploadDescription:
|
||||
'支持单次或批量上传。 严禁上传公司数据或其他违禁文件。',
|
||||
chunk: '解析块',
|
||||
bulk: '批量',
|
||||
cancel: '取消',
|
||||
},
|
||||
knowledgeConfiguration: {
|
||||
titleDescription: '在这里更新您的知识库详细信息,尤其是解析方法。',
|
||||
|
@ -219,7 +219,7 @@ const KnowledgeUploadFile = () => {
|
||||
|
||||
const runSelectedDocument = () => {
|
||||
const ids = fileListRef.current.map((x) => x.response.id);
|
||||
runDocumentByIds(ids);
|
||||
runDocumentByIds({ doc_ids: ids, run: 1 });
|
||||
};
|
||||
|
||||
const handleNextClick = () => {
|
||||
|
@ -0,0 +1,222 @@
|
||||
import { ReactComponent as CancelIcon } from '@/assets/svg/cancel.svg';
|
||||
import { ReactComponent as DeleteIcon } from '@/assets/svg/delete.svg';
|
||||
import { ReactComponent as DisableIcon } from '@/assets/svg/disable.svg';
|
||||
import { ReactComponent as EnableIcon } from '@/assets/svg/enable.svg';
|
||||
import { ReactComponent as RunIcon } from '@/assets/svg/run.svg';
|
||||
import { useShowDeleteConfirm, useTranslate } from '@/hooks/commonHooks';
|
||||
import {
|
||||
useRemoveDocument,
|
||||
useRunDocument,
|
||||
useSetDocumentStatus,
|
||||
} from '@/hooks/documentHooks';
|
||||
import { useGetKnowledgeSearchParams } from '@/hooks/routeHook';
|
||||
import {
|
||||
DownOutlined,
|
||||
FileOutlined,
|
||||
FileTextOutlined,
|
||||
PlusOutlined,
|
||||
SearchOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Button, Dropdown, Flex, Input, MenuProps, Space } from 'antd';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import {
|
||||
useFetchDocumentListOnMount,
|
||||
useGetPagination,
|
||||
useHandleSearchChange,
|
||||
useNavigateToOtherPage,
|
||||
} from './hooks';
|
||||
import styles from './index.less';
|
||||
|
||||
interface IProps {
|
||||
selectedRowKeys: string[];
|
||||
showCreateModal(): void;
|
||||
}
|
||||
|
||||
const DocumentToolbar = ({ selectedRowKeys, showCreateModal }: IProps) => {
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
const { fetchDocumentList } = useFetchDocumentListOnMount();
|
||||
const { setPagination, searchString } = useGetPagination(fetchDocumentList);
|
||||
const { handleInputChange } = useHandleSearchChange(setPagination);
|
||||
const removeDocument = useRemoveDocument();
|
||||
const showDeleteConfirm = useShowDeleteConfirm();
|
||||
const { linkToUploadPage } = useNavigateToOtherPage();
|
||||
const runDocumentByIds = useRunDocument();
|
||||
const { knowledgeId } = useGetKnowledgeSearchParams();
|
||||
const changeStatus = useSetDocumentStatus();
|
||||
|
||||
const actionItems: MenuProps['items'] = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
key: '1',
|
||||
onClick: linkToUploadPage,
|
||||
label: (
|
||||
<div>
|
||||
<Button type="link">
|
||||
<Space>
|
||||
<FileTextOutlined />
|
||||
{t('localFiles')}
|
||||
</Space>
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{
|
||||
key: '2',
|
||||
onClick: showCreateModal,
|
||||
label: (
|
||||
<div>
|
||||
<Button type="link">
|
||||
<FileOutlined />
|
||||
{t('emptyFiles')}
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
// disabled: true,
|
||||
},
|
||||
];
|
||||
}, [linkToUploadPage, showCreateModal, t]);
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
showDeleteConfirm({
|
||||
onOk: () => {
|
||||
selectedRowKeys.forEach((id) => {
|
||||
removeDocument(id);
|
||||
});
|
||||
},
|
||||
});
|
||||
}, [removeDocument, showDeleteConfirm, selectedRowKeys]);
|
||||
|
||||
const runDocument = useCallback(
|
||||
(run: number) => {
|
||||
runDocumentByIds({
|
||||
doc_ids: selectedRowKeys,
|
||||
run,
|
||||
knowledgeBaseId: knowledgeId,
|
||||
});
|
||||
},
|
||||
[runDocumentByIds, selectedRowKeys, knowledgeId],
|
||||
);
|
||||
|
||||
const handleRunClick = useCallback(() => {
|
||||
runDocument(1);
|
||||
}, [runDocument]);
|
||||
|
||||
const handleCancelClick = useCallback(() => {
|
||||
runDocument(2);
|
||||
}, [runDocument]);
|
||||
|
||||
const onChangeStatus = useCallback(
|
||||
(enabled: boolean) => {
|
||||
selectedRowKeys.forEach((id) => {
|
||||
changeStatus(enabled, id);
|
||||
});
|
||||
},
|
||||
[selectedRowKeys, changeStatus],
|
||||
);
|
||||
|
||||
const handleEnableClick = useCallback(() => {
|
||||
onChangeStatus(true);
|
||||
}, [onChangeStatus]);
|
||||
|
||||
const handleDisableClick = useCallback(() => {
|
||||
onChangeStatus(false);
|
||||
}, [onChangeStatus]);
|
||||
|
||||
const disabled = selectedRowKeys.length === 0;
|
||||
|
||||
const items: MenuProps['items'] = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
key: '0',
|
||||
onClick: handleEnableClick,
|
||||
label: (
|
||||
<Flex gap={10}>
|
||||
<EnableIcon></EnableIcon>
|
||||
<b>{t('enabled')}</b>
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
onClick: handleDisableClick,
|
||||
label: (
|
||||
<Flex gap={10}>
|
||||
<DisableIcon></DisableIcon>
|
||||
<b>{t('disabled')}</b>
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{
|
||||
key: '2',
|
||||
onClick: handleRunClick,
|
||||
label: (
|
||||
<Flex gap={10}>
|
||||
<RunIcon></RunIcon>
|
||||
<b>{t('run')}</b>
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
onClick: handleCancelClick,
|
||||
label: (
|
||||
<Flex gap={10}>
|
||||
<CancelIcon />
|
||||
<b>{t('cancel')}</b>
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{
|
||||
key: '4',
|
||||
onClick: handleDelete,
|
||||
label: (
|
||||
<Flex gap={10}>
|
||||
<span className={styles.deleteIconWrapper}>
|
||||
<DeleteIcon width={18} />
|
||||
</span>
|
||||
<b>{t('delete', { keyPrefix: 'common' })}</b>
|
||||
</Flex>
|
||||
),
|
||||
},
|
||||
];
|
||||
}, [handleDelete, handleRunClick, handleCancelClick, t]);
|
||||
|
||||
return (
|
||||
<div className={styles.filter}>
|
||||
<Dropdown
|
||||
menu={{ items }}
|
||||
placement="bottom"
|
||||
arrow={false}
|
||||
disabled={disabled}
|
||||
>
|
||||
<Button>
|
||||
<Space>
|
||||
<b> {t('bulk')}</b>
|
||||
<DownOutlined />
|
||||
</Space>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
<Space>
|
||||
<Input
|
||||
placeholder={t('searchFiles')}
|
||||
value={searchString}
|
||||
style={{ width: 220 }}
|
||||
allowClear
|
||||
onChange={handleInputChange}
|
||||
prefix={<SearchOutlined />}
|
||||
/>
|
||||
|
||||
<Dropdown menu={{ items: actionItems }} trigger={['click']}>
|
||||
<Button type="primary" icon={<PlusOutlined />}>
|
||||
{t('addFile')}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</Space>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DocumentToolbar;
|
@ -1,4 +1,4 @@
|
||||
import { useSetModalState } from '@/hooks/commonHooks';
|
||||
import { useSetModalState, useTranslate } from '@/hooks/commonHooks';
|
||||
import {
|
||||
useCreateDocument,
|
||||
useFetchDocumentList,
|
||||
@ -11,7 +11,7 @@ import { useFetchTenantInfo } from '@/hooks/userSettingHook';
|
||||
import { Pagination } from '@/interfaces/common';
|
||||
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
||||
import { PaginationProps } from 'antd';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useDispatch, useNavigate, useSelector } from 'umi';
|
||||
import { KnowledgeRouteKey } from './constant';
|
||||
|
||||
@ -43,6 +43,7 @@ export const useFetchDocumentListOnMount = () => {
|
||||
export const useGetPagination = (fetchDocumentList: () => void) => {
|
||||
const dispatch = useDispatch();
|
||||
const kFModel = useSelector((state: any) => state.kFModel);
|
||||
const { t } = useTranslate('common');
|
||||
|
||||
const setPagination = useCallback(
|
||||
(pageNumber = 1, pageSize?: number) => {
|
||||
@ -77,8 +78,9 @@ export const useGetPagination = (fetchDocumentList: () => void) => {
|
||||
pageSize: kFModel.pagination.pageSize,
|
||||
pageSizeOptions: [1, 2, 10, 20, 50, 100],
|
||||
onChange: onPageChange,
|
||||
showTotal: (total) => `${t('total')} ${total}`,
|
||||
};
|
||||
}, [kFModel, onPageChange]);
|
||||
}, [kFModel, onPageChange, t]);
|
||||
|
||||
return {
|
||||
pagination,
|
||||
@ -227,3 +229,16 @@ export const useChangeDocumentParser = (documentId: string) => {
|
||||
showChangeParserModal,
|
||||
};
|
||||
};
|
||||
|
||||
export const useGetRowSelection = () => {
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
||||
|
||||
const rowSelection = {
|
||||
selectedRowKeys,
|
||||
onChange: (newSelectedRowKeys: React.Key[]) => {
|
||||
setSelectedRowKeys(newSelectedRowKeys);
|
||||
},
|
||||
};
|
||||
|
||||
return rowSelection;
|
||||
};
|
||||
|
@ -8,15 +8,13 @@
|
||||
display: flex;
|
||||
margin: 10px 0;
|
||||
justify-content: space-between;
|
||||
padding: 24px 20px;
|
||||
padding: 24px 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// .search {
|
||||
// flex: 1;
|
||||
// }
|
||||
|
||||
// .operate {
|
||||
// width: 200px;
|
||||
// }
|
||||
.deleteIconWrapper {
|
||||
width: 22px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.img {
|
||||
|
@ -4,36 +4,21 @@ import {
|
||||
useSelectDocumentList,
|
||||
useSetDocumentStatus,
|
||||
} from '@/hooks/documentHooks';
|
||||
import { useSetSelectedRecord } from '@/hooks/logicHooks';
|
||||
import { useSelectParserList } from '@/hooks/userSettingHook';
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import { getExtension } from '@/utils/documentUtils';
|
||||
import {
|
||||
FileOutlined,
|
||||
FileTextOutlined,
|
||||
PlusOutlined,
|
||||
SearchOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import type { MenuProps } from 'antd';
|
||||
import {
|
||||
Button,
|
||||
Divider,
|
||||
Dropdown,
|
||||
Flex,
|
||||
Input,
|
||||
Space,
|
||||
Switch,
|
||||
Table,
|
||||
Tag,
|
||||
} from 'antd';
|
||||
import { Divider, Flex, Switch, Table } from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import CreateFileModal from './create-file-modal';
|
||||
import DocumentToolbar from './document-toolbar';
|
||||
import {
|
||||
useChangeDocumentParser,
|
||||
useCreateEmptyDocument,
|
||||
useFetchDocumentListOnMount,
|
||||
useGetPagination,
|
||||
useHandleSearchChange,
|
||||
useGetRowSelection,
|
||||
useNavigateToOtherPage,
|
||||
useRenameDocument,
|
||||
} from './hooks';
|
||||
@ -41,20 +26,15 @@ import ParsingActionCell from './parsing-action-cell';
|
||||
import ParsingStatusCell from './parsing-status-cell';
|
||||
import RenameModal from './rename-modal';
|
||||
|
||||
import { useSetSelectedRecord } from '@/hooks/logicHooks';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import styles from './index.less';
|
||||
|
||||
const KnowledgeFile = () => {
|
||||
const data = useSelectDocumentList();
|
||||
const { fetchDocumentList } = useFetchDocumentListOnMount();
|
||||
const parserList = useSelectParserList();
|
||||
const { pagination, setPagination, total, searchString } =
|
||||
useGetPagination(fetchDocumentList);
|
||||
const { pagination } = useGetPagination(fetchDocumentList);
|
||||
const onChangeStatus = useSetDocumentStatus();
|
||||
const { linkToUploadPage, toChunk } = useNavigateToOtherPage();
|
||||
|
||||
const { handleInputChange } = useHandleSearchChange(setPagination);
|
||||
const { toChunk } = useNavigateToOtherPage();
|
||||
const { currentRecord, setRecord } = useSetSelectedRecord();
|
||||
const {
|
||||
renameLoading,
|
||||
@ -81,38 +61,7 @@ const KnowledgeFile = () => {
|
||||
keyPrefix: 'knowledgeDetails',
|
||||
});
|
||||
|
||||
const actionItems: MenuProps['items'] = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
key: '1',
|
||||
onClick: linkToUploadPage,
|
||||
label: (
|
||||
<div>
|
||||
<Button type="link">
|
||||
<Space>
|
||||
<FileTextOutlined />
|
||||
{t('localFiles')}
|
||||
</Space>
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{
|
||||
key: '2',
|
||||
onClick: showCreateModal,
|
||||
label: (
|
||||
<div>
|
||||
<Button type="link">
|
||||
<FileOutlined />
|
||||
{t('emptyFiles')}
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
// disabled: true,
|
||||
},
|
||||
];
|
||||
}, [linkToUploadPage, showCreateModal, t]);
|
||||
const rowSelection = useGetRowSelection();
|
||||
|
||||
const columns: ColumnsType<IKnowledgeFile> = [
|
||||
{
|
||||
@ -161,7 +110,7 @@ const KnowledgeFile = () => {
|
||||
render: (_, { status, id }) => (
|
||||
<>
|
||||
<Switch
|
||||
defaultChecked={status === '1'}
|
||||
checked={status === '1'}
|
||||
onChange={(e) => {
|
||||
onChangeStatus(e, id);
|
||||
}}
|
||||
@ -201,36 +150,17 @@ const KnowledgeFile = () => {
|
||||
<h3>{t('dataset')}</h3>
|
||||
<p>{t('datasetDescription')}</p>
|
||||
<Divider></Divider>
|
||||
<div className={styles.filter}>
|
||||
<Space>
|
||||
<h3>{t('total', { keyPrefix: 'common' })}</h3>
|
||||
<Tag color="purple">
|
||||
{total} {t('files')}
|
||||
</Tag>
|
||||
</Space>
|
||||
<Space>
|
||||
<Input
|
||||
placeholder={t('searchFiles')}
|
||||
value={searchString}
|
||||
style={{ width: 220 }}
|
||||
allowClear
|
||||
onChange={handleInputChange}
|
||||
prefix={<SearchOutlined />}
|
||||
/>
|
||||
|
||||
<Dropdown menu={{ items: actionItems }} trigger={['click']}>
|
||||
<Button type="primary" icon={<PlusOutlined />}>
|
||||
{t('addFile')}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</Space>
|
||||
</div>
|
||||
<DocumentToolbar
|
||||
selectedRowKeys={rowSelection.selectedRowKeys as string[]}
|
||||
showCreateModal={showCreateModal}
|
||||
></DocumentToolbar>
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={finalColumns}
|
||||
dataSource={data}
|
||||
// loading={loading}
|
||||
pagination={pagination}
|
||||
rowSelection={rowSelection}
|
||||
scroll={{ scrollToFirstRowOnChange: true, x: 1300, y: 'fill' }}
|
||||
/>
|
||||
<CreateFileModal
|
||||
|
@ -30,12 +30,12 @@ const ParsingActionCell = ({
|
||||
const documentId = record.id;
|
||||
const isRunning = isParserRunning(record.run);
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
const removeDocument = useRemoveDocument(documentId);
|
||||
const removeDocument = useRemoveDocument();
|
||||
const showDeleteConfirm = useShowDeleteConfirm();
|
||||
|
||||
const onRmDocument = () => {
|
||||
if (!isRunning) {
|
||||
showDeleteConfirm({ onOk: removeDocument });
|
||||
showDeleteConfirm({ onOk: () => removeDocument(documentId) });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -18,8 +18,7 @@
|
||||
|
||||
.operationIcon {
|
||||
text-align: center;
|
||||
margin-right: 20%;
|
||||
width: 20px;
|
||||
display: flex;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
import { ReactComponent as CancelIcon } from '@/assets/svg/cancel.svg';
|
||||
import { ReactComponent as RefreshIcon } from '@/assets/svg/refresh.svg';
|
||||
import { ReactComponent as RunIcon } from '@/assets/svg/run.svg';
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { useRunDocument } from '@/hooks/documentHooks';
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||
import { Badge, DescriptionsProps, Flex, Popover, Space, Tag } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import reactStringReplace from 'react-string-replace';
|
||||
import { useDispatch } from 'umi';
|
||||
import { RunningStatus, RunningStatusMap } from '../constant';
|
||||
import { isParserRunning } from '../utils';
|
||||
import styles from './index.less';
|
||||
|
||||
const iconMap = {
|
||||
[RunningStatus.UNSTART]: RunIcon,
|
||||
[RunningStatus.RUNNING]: CloseCircleOutlined,
|
||||
[RunningStatus.RUNNING]: CancelIcon,
|
||||
[RunningStatus.CANCEL]: RefreshIcon,
|
||||
[RunningStatus.DONE]: RefreshIcon,
|
||||
[RunningStatus.FAIL]: RefreshIcon,
|
||||
@ -78,10 +78,10 @@ const PopoverContent = ({ record }: IProps) => {
|
||||
};
|
||||
|
||||
export const ParsingStatusCell = ({ record }: IProps) => {
|
||||
const dispatch = useDispatch();
|
||||
const text = record.run;
|
||||
const runningStatus = RunningStatusMap[text];
|
||||
const { t } = useTranslation();
|
||||
const runDocumentByIds = useRunDocument();
|
||||
|
||||
const isRunning = isParserRunning(text);
|
||||
|
||||
@ -90,18 +90,15 @@ export const ParsingStatusCell = ({ record }: IProps) => {
|
||||
const label = t(`knowledgeDetails.runningStatus${text}`);
|
||||
|
||||
const handleOperationIconClick = () => {
|
||||
dispatch({
|
||||
type: 'kFModel/document_run',
|
||||
payload: {
|
||||
doc_ids: [record.id],
|
||||
run: isRunning ? 2 : 1,
|
||||
knowledgeBaseId: record.kb_id,
|
||||
},
|
||||
runDocumentByIds({
|
||||
doc_ids: [record.id],
|
||||
run: isRunning ? 2 : 1,
|
||||
knowledgeBaseId: record.kb_id,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex justify={'space-between'}>
|
||||
<Flex justify={'space-between'} align="center">
|
||||
<Popover content={<PopoverContent record={record}></PopoverContent>}>
|
||||
<Tag color={runningStatus.color}>
|
||||
{isRunning ? (
|
||||
|
Loading…
x
Reference in New Issue
Block a user