diff --git a/web/src/hooks/fileManagerHooks.ts b/web/src/hooks/fileManagerHooks.ts index a9fd72c9b7..8410aa74c6 100644 --- a/web/src/hooks/fileManagerHooks.ts +++ b/web/src/hooks/fileManagerHooks.ts @@ -22,10 +22,10 @@ export const useRemoveFile = () => { const dispatch = useDispatch(); const removeFile = useCallback( - (fileIds: string[]) => { + (fileIds: string[], parentId: string) => { return dispatch({ type: 'fileManager/removeFile', - payload: { fileIds }, + payload: { fileIds, parentId }, }); }, [dispatch], @@ -38,10 +38,10 @@ export const useRenameFile = () => { const dispatch = useDispatch(); const renameFile = useCallback( - (fileId: string, name: string) => { + (fileId: string, name: string, parentId: string) => { return dispatch({ type: 'fileManager/renameFile', - payload: { fileId, name }, + payload: { fileId, name, parentId }, }); }, [dispatch], @@ -66,6 +66,22 @@ export const useFetchParentFolderList = () => { return fetchParentFolderList; }; +export const useCreateFolder = () => { + const dispatch = useDispatch(); + + const createFolder = useCallback( + (parentId: string, name: string) => { + return dispatch({ + type: 'fileManager/createFolder', + payload: { parentId, name, type: 'folder' }, + }); + }, + [dispatch], + ); + + return createFolder; +}; + export const useSelectFileList = () => { const fileList = useSelector((state) => state.fileManager.fileList); diff --git a/web/src/pages/file-manager/action-cell/index.tsx b/web/src/pages/file-manager/action-cell/index.tsx index b6e44a28fd..518a50763d 100644 --- a/web/src/pages/file-manager/action-cell/index.tsx +++ b/web/src/pages/file-manager/action-cell/index.tsx @@ -1,4 +1,5 @@ -import { useShowDeleteConfirm, useTranslate } from '@/hooks/commonHooks'; +import { useTranslate } from '@/hooks/commonHooks'; +import { IFile } from '@/interfaces/database/file-manager'; import { api_host } from '@/utils/api'; import { downloadFile } from '@/utils/fileUtil'; import { @@ -8,9 +9,8 @@ import { ToolOutlined, } from '@ant-design/icons'; import { Button, Space, Tooltip } from 'antd'; +import { useHandleDeleteFile } from '../hooks'; -import { useRemoveFile } from '@/hooks/fileManagerHooks'; -import { IFile } from '@/interfaces/database/file-manager'; import styles from './index.less'; interface IProps { @@ -23,18 +23,7 @@ const ActionCell = ({ record, setCurrentRecord, showRenameModal }: IProps) => { const documentId = record.id; const beingUsed = false; const { t } = useTranslate('knowledgeDetails'); - const removeDocument = useRemoveFile(); - const showDeleteConfirm = useShowDeleteConfirm(); - - const onRmDocument = () => { - if (!beingUsed) { - showDeleteConfirm({ - onOk: () => { - return removeDocument([documentId]); - }, - }); - } - }; + const { handleRemoveFile } = useHandleDeleteFile([documentId]); const onDownloadDocument = () => { downloadFile({ @@ -71,7 +60,7 @@ const ActionCell = ({ record, setCurrentRecord, showRenameModal }: IProps) => { ), // disabled: true, }, ]; - }, [t]); + }, [t, showFolderCreateModal]); - const handleDelete = useCallback(() => { - showDeleteConfirm({ - onOk: () => { - return removeDocument(selectedRowKeys); - }, - }); - }, [removeDocument, showDeleteConfirm, selectedRowKeys]); + const { handleRemoveFile } = useHandleDeleteFile(selectedRowKeys); const disabled = selectedRowKeys.length === 0; @@ -101,7 +95,7 @@ const FileToolbar = ({ selectedRowKeys }: IProps) => { return [ { key: '4', - onClick: handleDelete, + onClick: handleRemoveFile, label: ( @@ -112,7 +106,7 @@ const FileToolbar = ({ selectedRowKeys }: IProps) => { ), }, ]; - }, [handleDelete, t]); + }, [handleRemoveFile, t]); return (
diff --git a/web/src/pages/file-manager/file-upload-modal/index.tsx b/web/src/pages/file-manager/file-upload-modal/index.tsx new file mode 100644 index 0000000000..f457292c5e --- /dev/null +++ b/web/src/pages/file-manager/file-upload-modal/index.tsx @@ -0,0 +1,64 @@ +import { InboxOutlined } from '@ant-design/icons'; +import { Modal, Segmented, Upload, UploadProps, message } from 'antd'; +import { useState } from 'react'; + +const { Dragger } = Upload; + +const FileUploadModal = () => { + const [isModalOpen, setIsModalOpen] = useState(false); + + const props: UploadProps = { + name: 'file', + multiple: true, + action: 'https://660d2bd96ddfa2943b33731c.mockapi.io/api/upload', + onChange(info) { + const { status } = info.file; + if (status !== 'uploading') { + console.log(info.file, info.fileList); + } + if (status === 'done') { + message.success(`${info.file.name} file uploaded successfully.`); + } else if (status === 'error') { + message.error(`${info.file.name} file upload failed.`); + } + }, + onDrop(e) { + console.log('Dropped files', e.dataTransfer.files); + }, + }; + + const handleOk = () => { + setIsModalOpen(false); + }; + + const handleCancel = () => { + setIsModalOpen(false); + }; + + return ( + <> + + + +

+ +

+

+ Click or drag file to this area to upload +

+

+ Support for a single or bulk upload. Strictly prohibited from + uploading company data or other banned files. +

+
+
+ + ); +}; + +export default FileUploadModal; diff --git a/web/src/pages/file-manager/folder-create-modal/index.tsx b/web/src/pages/file-manager/folder-create-modal/index.tsx new file mode 100644 index 0000000000..e16511f3e7 --- /dev/null +++ b/web/src/pages/file-manager/folder-create-modal/index.tsx @@ -0,0 +1,67 @@ +import { IModalManagerChildrenProps } from '@/components/modal-manager'; +import { useTranslate } from '@/hooks/commonHooks'; +import { Form, Input, Modal } from 'antd'; + +interface IProps extends Omit { + loading: boolean; + onOk: (name: string) => void; +} + +const FolderCreateModal = ({ visible, hideModal, loading, onOk }: IProps) => { + const [form] = Form.useForm(); + const { t } = useTranslate('common'); + + type FieldType = { + name?: string; + }; + + const handleOk = async () => { + const ret = await form.validateFields(); + + return onOk(ret.name); + }; + + const handleCancel = () => { + hideModal(); + }; + + const onFinish = (values: any) => { + console.log('Success:', values); + }; + + const onFinishFailed = (errorInfo: any) => { + console.log('Failed:', errorInfo); + }; + + return ( + +
+ + label={t('name')} + name="name" + rules={[{ required: true, message: t('namePlaceholder') }]} + > + + + +
+ ); +}; + +export default FolderCreateModal; diff --git a/web/src/pages/file-manager/hooks.ts b/web/src/pages/file-manager/hooks.ts index 6a43c33645..af09cf599d 100644 --- a/web/src/pages/file-manager/hooks.ts +++ b/web/src/pages/file-manager/hooks.ts @@ -1,7 +1,13 @@ -import { useSetModalState, useTranslate } from '@/hooks/commonHooks'; import { + useSetModalState, + useShowDeleteConfirm, + useTranslate, +} from '@/hooks/commonHooks'; +import { + useCreateFolder, useFetchFileList, useFetchParentFolderList, + useRemoveFile, useRenameFile, useSelectFileList, useSelectParentFolderList, @@ -144,7 +150,7 @@ export const useRenameCurrentFile = () => { const onFileRenameOk = useCallback( async (name: string) => { - const ret = await renameFile(file.id, name); + const ret = await renameFile(file.id, name, file.parent_id); if (ret === 0) { hideFileRenameModal(); @@ -191,3 +197,56 @@ export const useSelectBreadcrumbItems = () => { path: `/file?folderId=${x.id}`, })); }; + +export const useHandleCreateFolder = () => { + const { + visible: folderCreateModalVisible, + hideModal: hideFolderCreateModal, + showModal: showFolderCreateModal, + } = useSetModalState(); + const createFolder = useCreateFolder(); + const id = useGetFolderId(); + + const onFolderCreateOk = useCallback( + async (name: string) => { + const ret = await createFolder(id, name); + + if (ret === 0) { + hideFolderCreateModal(); + } + }, + [createFolder, hideFolderCreateModal, id], + ); + + const loading = useOneNamespaceEffectsLoading('fileManager', [ + 'createFolder', + ]); + + return { + folderCreateLoading: loading, + onFolderCreateOk, + folderCreateModalVisible, + hideFolderCreateModal, + showFolderCreateModal, + }; +}; + +export const useHandleDeleteFile = (fileIds: string[]) => { + const removeDocument = useRemoveFile(); + const showDeleteConfirm = useShowDeleteConfirm(); + const parentId = useGetFolderId(); + + const handleRemoveFile = () => { + showDeleteConfirm({ + onOk: () => { + return removeDocument(fileIds, parentId); + }, + }); + }; + + return { handleRemoveFile }; +}; + +export const useSelectFileListLoading = () => { + return useOneNamespaceEffectsLoading('fileManager', ['listFile']); +}; diff --git a/web/src/pages/file-manager/index.tsx b/web/src/pages/file-manager/index.tsx index 83dee7a634..829d810770 100644 --- a/web/src/pages/file-manager/index.tsx +++ b/web/src/pages/file-manager/index.tsx @@ -7,16 +7,20 @@ import ActionCell from './action-cell'; import FileToolbar from './file-toolbar'; import { useGetRowSelection, + useHandleCreateFolder, useNavigateToOtherFolder, useRenameCurrentFile, + useSelectFileListLoading, } from './hooks'; import RenameModal from '@/components/rename-modal'; +import FolderCreateModal from './folder-create-modal'; import styles from './index.less'; const FileManager = () => { const fileList = useSelectFileList(); const rowSelection = useGetRowSelection(); + const loading = useSelectFileListLoading(); const navigateToOtherFolder = useNavigateToOtherFolder(); const { fileRenameVisible, @@ -26,6 +30,13 @@ const FileManager = () => { initialFileName, onFileRenameOk, } = useRenameCurrentFile(); + const { + folderCreateModalVisible, + showFolderCreateModal, + hideFolderCreateModal, + folderCreateLoading, + onFolderCreateOk, + } = useHandleCreateFolder(); const columns: ColumnsType = [ { @@ -78,12 +89,14 @@ const FileManager = () => {
{ initialName={initialFileName} loading={fileRenameLoading} > + ); }; diff --git a/web/src/pages/file-manager/model.ts b/web/src/pages/file-manager/model.ts index e58faa9d5f..e145755754 100644 --- a/web/src/pages/file-manager/model.ts +++ b/web/src/pages/file-manager/model.ts @@ -1,5 +1,6 @@ import { IFile, IFolder } from '@/interfaces/database/file-manager'; import fileManagerService from '@/services/fileManagerService'; +import omit from 'lodash/omit'; import { DvaModel } from 'umi'; export interface FileManagerModelState { @@ -20,12 +21,14 @@ const model: DvaModel = { }, effects: { *removeFile({ payload = {} }, { call, put }) { - const { data } = yield call(fileManagerService.removeFile, payload); + const { data } = yield call(fileManagerService.removeFile, { + fileIds: payload.fileIds, + }); const { retcode } = data; if (retcode === 0) { yield put({ type: 'listFile', - payload: data.data?.files ?? [], + payload: { parentId: payload.parentId }, }); } }, @@ -41,9 +44,25 @@ const model: DvaModel = { } }, *renameFile({ payload = {} }, { call, put }) { - const { data } = yield call(fileManagerService.renameFile, payload); + const { data } = yield call( + fileManagerService.renameFile, + omit(payload, ['parentId']), + ); + if (data.retcode === 0) { + yield put({ + type: 'listFile', + payload: { parentId: payload.parentId }, + }); + } + return data.retcode; + }, + *createFolder({ payload = {} }, { call, put }) { + const { data } = yield call(fileManagerService.createFolder, payload); if (data.retcode === 0) { - yield put({ type: 'listFile' }); + yield put({ + type: 'listFile', + payload: { parentId: payload.parentId }, + }); } return data.retcode; }, diff --git a/web/src/services/fileManagerService.ts b/web/src/services/fileManagerService.ts index 9edcc2f797..01e152ee52 100644 --- a/web/src/services/fileManagerService.ts +++ b/web/src/services/fileManagerService.ts @@ -2,8 +2,14 @@ import api from '@/utils/api'; import registerServer from '@/utils/registerServer'; import request from '@/utils/request'; -const { listFile, removeFile, uploadFile, renameFile, getAllParentFolder } = - api; +const { + listFile, + removeFile, + uploadFile, + renameFile, + getAllParentFolder, + createFolder, +} = api; const methods = { listFile: { @@ -26,6 +32,10 @@ const methods = { url: getAllParentFolder, method: 'get', }, + createFolder: { + url: createFolder, + method: 'post', + }, } as const; const fileManagerService = registerServer( diff --git a/web/src/utils/api.ts b/web/src/utils/api.ts index f449f932c8..8b9847e6bb 100644 --- a/web/src/utils/api.ts +++ b/web/src/utils/api.ts @@ -73,4 +73,5 @@ export default { removeFile: `${api_host}/file/rm`, renameFile: `${api_host}/file/rename`, getAllParentFolder: `${api_host}/file/all_parent_folder`, + createFolder: `${api_host}/file/create`, };