({
type: 'kFModel/document_run',
- payload: { doc_ids: ids, run: 1 },
+ payload,
});
} catch (errorInfo) {
console.log('Failed:', errorInfo);
diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts
index 29c91160d..33fb8d9cc 100644
--- a/web/src/locales/en.ts
+++ b/web/src/locales/en.ts
@@ -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:
diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts
index af162fe9f..70a3b42c7 100644
--- a/web/src/locales/zh.ts
+++ b/web/src/locales/zh.ts
@@ -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: '在这里更新您的知识库详细信息,尤其是解析方法。',
diff --git a/web/src/pages/add-knowledge/components/knowledge-dataset/knowledge-upload-file/index.tsx b/web/src/pages/add-knowledge/components/knowledge-dataset/knowledge-upload-file/index.tsx
index 263457a75..b7025e1cf 100644
--- a/web/src/pages/add-knowledge/components/knowledge-dataset/knowledge-upload-file/index.tsx
+++ b/web/src/pages/add-knowledge/components/knowledge-dataset/knowledge-upload-file/index.tsx
@@ -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 = () => {
diff --git a/web/src/pages/add-knowledge/components/knowledge-file/document-toolbar.tsx b/web/src/pages/add-knowledge/components/knowledge-file/document-toolbar.tsx
new file mode 100644
index 000000000..f6fb5bef2
--- /dev/null
+++ b/web/src/pages/add-knowledge/components/knowledge-file/document-toolbar.tsx
@@ -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: (
+
+
+
+
+ {t('localFiles')}
+
+
+
+ ),
+ },
+ { type: 'divider' },
+ {
+ key: '2',
+ onClick: showCreateModal,
+ label: (
+
+
+
+ {t('emptyFiles')}
+
+
+ ),
+ // 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: (
+
+
+ {t('enabled')}
+
+ ),
+ },
+ {
+ key: '1',
+ onClick: handleDisableClick,
+ label: (
+
+
+ {t('disabled')}
+
+ ),
+ },
+ { type: 'divider' },
+ {
+ key: '2',
+ onClick: handleRunClick,
+ label: (
+
+
+ {t('run')}
+
+ ),
+ },
+ {
+ key: '3',
+ onClick: handleCancelClick,
+ label: (
+
+
+ {t('cancel')}
+
+ ),
+ },
+ { type: 'divider' },
+ {
+ key: '4',
+ onClick: handleDelete,
+ label: (
+
+
+
+
+ {t('delete', { keyPrefix: 'common' })}
+
+ ),
+ },
+ ];
+ }, [handleDelete, handleRunClick, handleCancelClick, t]);
+
+ return (
+
+
+
+
+ {t('bulk')}
+
+
+
+
+
+ }
+ />
+
+
+ }>
+ {t('addFile')}
+
+
+
+
+ );
+};
+
+export default DocumentToolbar;
diff --git a/web/src/pages/add-knowledge/components/knowledge-file/hooks.ts b/web/src/pages/add-knowledge/components/knowledge-file/hooks.ts
index 1bf98ca29..4091bfd99 100644
--- a/web/src/pages/add-knowledge/components/knowledge-file/hooks.ts
+++ b/web/src/pages/add-knowledge/components/knowledge-file/hooks.ts
@@ -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([]);
+
+ const rowSelection = {
+ selectedRowKeys,
+ onChange: (newSelectedRowKeys: React.Key[]) => {
+ setSelectedRowKeys(newSelectedRowKeys);
+ },
+ };
+
+ return rowSelection;
+};
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 d78737b36..fa7139c05 100644
--- a/web/src/pages/add-knowledge/components/knowledge-file/index.less
+++ b/web/src/pages/add-knowledge/components/knowledge-file/index.less
@@ -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 {
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 096b22de4..765d67bc8 100644
--- a/web/src/pages/add-knowledge/components/knowledge-file/index.tsx
+++ b/web/src/pages/add-knowledge/components/knowledge-file/index.tsx
@@ -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: (
-
-
-
-
- {t('localFiles')}
-
-
-
- ),
- },
- { type: 'divider' },
- {
- key: '2',
- onClick: showCreateModal,
- label: (
-
-
-
- {t('emptyFiles')}
-
-
- ),
- // disabled: true,
- },
- ];
- }, [linkToUploadPage, showCreateModal, t]);
+ const rowSelection = useGetRowSelection();
const columns: ColumnsType = [
{
@@ -161,7 +110,7 @@ const KnowledgeFile = () => {
render: (_, { status, id }) => (
<>
{
onChangeStatus(e, id);
}}
@@ -201,36 +150,17 @@ const KnowledgeFile = () => {
{t('dataset')}
{t('datasetDescription')}
-
-
- {t('total', { keyPrefix: 'common' })}
-
- {total} {t('files')}
-
-
-
- }
- />
-
-
- }>
- {t('addFile')}
-
-
-
-
+
{
if (!isRunning) {
- showDeleteConfirm({ onOk: removeDocument });
+ showDeleteConfirm({ onOk: () => removeDocument(documentId) });
}
};
diff --git a/web/src/pages/add-knowledge/components/knowledge-file/parsing-status-cell/index.less b/web/src/pages/add-knowledge/components/knowledge-file/parsing-status-cell/index.less
index 25ccfaaa2..c55127f26 100644
--- a/web/src/pages/add-knowledge/components/knowledge-file/parsing-status-cell/index.less
+++ b/web/src/pages/add-knowledge/components/knowledge-file/parsing-status-cell/index.less
@@ -18,8 +18,7 @@
.operationIcon {
text-align: center;
- margin-right: 20%;
- width: 20px;
+ display: flex;
&:hover {
cursor: pointer;
}
diff --git a/web/src/pages/add-knowledge/components/knowledge-file/parsing-status-cell/index.tsx b/web/src/pages/add-knowledge/components/knowledge-file/parsing-status-cell/index.tsx
index d5ca83e88..7e2d102a9 100644
--- a/web/src/pages/add-knowledge/components/knowledge-file/parsing-status-cell/index.tsx
+++ b/web/src/pages/add-knowledge/components/knowledge-file/parsing-status-cell/index.tsx
@@ -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 (
-
+
}>
{isRunning ? (