mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-05-30 18:15:52 +08:00
### What problem does this PR solve? feat: create folder feat: ensure that all files in the current folder can be correctly requested after renaming the folder #345 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
369400c483
commit
2d228dbf7f
@ -22,10 +22,10 @@ export const useRemoveFile = () => {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const removeFile = useCallback(
|
const removeFile = useCallback(
|
||||||
(fileIds: string[]) => {
|
(fileIds: string[], parentId: string) => {
|
||||||
return dispatch<any>({
|
return dispatch<any>({
|
||||||
type: 'fileManager/removeFile',
|
type: 'fileManager/removeFile',
|
||||||
payload: { fileIds },
|
payload: { fileIds, parentId },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[dispatch],
|
[dispatch],
|
||||||
@ -38,10 +38,10 @@ export const useRenameFile = () => {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const renameFile = useCallback(
|
const renameFile = useCallback(
|
||||||
(fileId: string, name: string) => {
|
(fileId: string, name: string, parentId: string) => {
|
||||||
return dispatch<any>({
|
return dispatch<any>({
|
||||||
type: 'fileManager/renameFile',
|
type: 'fileManager/renameFile',
|
||||||
payload: { fileId, name },
|
payload: { fileId, name, parentId },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[dispatch],
|
[dispatch],
|
||||||
@ -66,6 +66,22 @@ export const useFetchParentFolderList = () => {
|
|||||||
return fetchParentFolderList;
|
return fetchParentFolderList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useCreateFolder = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const createFolder = useCallback(
|
||||||
|
(parentId: string, name: string) => {
|
||||||
|
return dispatch<any>({
|
||||||
|
type: 'fileManager/createFolder',
|
||||||
|
payload: { parentId, name, type: 'folder' },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[dispatch],
|
||||||
|
);
|
||||||
|
|
||||||
|
return createFolder;
|
||||||
|
};
|
||||||
|
|
||||||
export const useSelectFileList = () => {
|
export const useSelectFileList = () => {
|
||||||
const fileList = useSelector((state) => state.fileManager.fileList);
|
const fileList = useSelector((state) => state.fileManager.fileList);
|
||||||
|
|
||||||
|
@ -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 { api_host } from '@/utils/api';
|
||||||
import { downloadFile } from '@/utils/fileUtil';
|
import { downloadFile } from '@/utils/fileUtil';
|
||||||
import {
|
import {
|
||||||
@ -8,9 +9,8 @@ import {
|
|||||||
ToolOutlined,
|
ToolOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { Button, Space, Tooltip } from 'antd';
|
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';
|
import styles from './index.less';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
@ -23,18 +23,7 @@ const ActionCell = ({ record, setCurrentRecord, showRenameModal }: IProps) => {
|
|||||||
const documentId = record.id;
|
const documentId = record.id;
|
||||||
const beingUsed = false;
|
const beingUsed = false;
|
||||||
const { t } = useTranslate('knowledgeDetails');
|
const { t } = useTranslate('knowledgeDetails');
|
||||||
const removeDocument = useRemoveFile();
|
const { handleRemoveFile } = useHandleDeleteFile([documentId]);
|
||||||
const showDeleteConfirm = useShowDeleteConfirm();
|
|
||||||
|
|
||||||
const onRmDocument = () => {
|
|
||||||
if (!beingUsed) {
|
|
||||||
showDeleteConfirm({
|
|
||||||
onOk: () => {
|
|
||||||
return removeDocument([documentId]);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDownloadDocument = () => {
|
const onDownloadDocument = () => {
|
||||||
downloadFile({
|
downloadFile({
|
||||||
@ -71,7 +60,7 @@ const ActionCell = ({ record, setCurrentRecord, showRenameModal }: IProps) => {
|
|||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
disabled={beingUsed}
|
disabled={beingUsed}
|
||||||
onClick={onRmDocument}
|
onClick={handleRemoveFile}
|
||||||
className={styles.iconButton}
|
className={styles.iconButton}
|
||||||
>
|
>
|
||||||
<DeleteOutlined size={20} />
|
<DeleteOutlined size={20} />
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { ReactComponent as DeleteIcon } from '@/assets/svg/delete.svg';
|
import { ReactComponent as DeleteIcon } from '@/assets/svg/delete.svg';
|
||||||
import { useShowDeleteConfirm, useTranslate } from '@/hooks/commonHooks';
|
import { useTranslate } from '@/hooks/commonHooks';
|
||||||
import {
|
import {
|
||||||
DownOutlined,
|
DownOutlined,
|
||||||
FileOutlined,
|
|
||||||
FileTextOutlined,
|
FileTextOutlined,
|
||||||
|
FolderOpenOutlined,
|
||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
SearchOutlined,
|
SearchOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
@ -17,20 +17,21 @@ import {
|
|||||||
MenuProps,
|
MenuProps,
|
||||||
Space,
|
Space,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
useFetchDocumentListOnMount,
|
useFetchDocumentListOnMount,
|
||||||
useGetPagination,
|
useGetPagination,
|
||||||
|
useHandleDeleteFile,
|
||||||
useHandleSearchChange,
|
useHandleSearchChange,
|
||||||
useSelectBreadcrumbItems,
|
useSelectBreadcrumbItems,
|
||||||
} from './hooks';
|
} from './hooks';
|
||||||
|
|
||||||
import { useRemoveFile } from '@/hooks/fileManagerHooks';
|
|
||||||
import { Link } from 'umi';
|
import { Link } from 'umi';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
selectedRowKeys: string[];
|
selectedRowKeys: string[];
|
||||||
|
showFolderCreateModal: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemRender: BreadcrumbProps['itemRender'] = (
|
const itemRender: BreadcrumbProps['itemRender'] = (
|
||||||
@ -47,13 +48,11 @@ const itemRender: BreadcrumbProps['itemRender'] = (
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const FileToolbar = ({ selectedRowKeys }: IProps) => {
|
const FileToolbar = ({ selectedRowKeys, showFolderCreateModal }: IProps) => {
|
||||||
const { t } = useTranslate('knowledgeDetails');
|
const { t } = useTranslate('knowledgeDetails');
|
||||||
const { fetchDocumentList } = useFetchDocumentListOnMount();
|
const { fetchDocumentList } = useFetchDocumentListOnMount();
|
||||||
const { setPagination, searchString } = useGetPagination(fetchDocumentList);
|
const { setPagination, searchString } = useGetPagination(fetchDocumentList);
|
||||||
const { handleInputChange } = useHandleSearchChange(setPagination);
|
const { handleInputChange } = useHandleSearchChange(setPagination);
|
||||||
const removeDocument = useRemoveFile();
|
|
||||||
const showDeleteConfirm = useShowDeleteConfirm();
|
|
||||||
const breadcrumbItems = useSelectBreadcrumbItems();
|
const breadcrumbItems = useSelectBreadcrumbItems();
|
||||||
|
|
||||||
const actionItems: MenuProps['items'] = useMemo(() => {
|
const actionItems: MenuProps['items'] = useMemo(() => {
|
||||||
@ -74,26 +73,21 @@ const FileToolbar = ({ selectedRowKeys }: IProps) => {
|
|||||||
{ type: 'divider' },
|
{ type: 'divider' },
|
||||||
{
|
{
|
||||||
key: '2',
|
key: '2',
|
||||||
|
onClick: showFolderCreateModal,
|
||||||
label: (
|
label: (
|
||||||
<div>
|
<div>
|
||||||
<Button type="link">
|
<Button type="link">
|
||||||
<FileOutlined />
|
<FolderOpenOutlined />
|
||||||
{t('emptyFiles')}
|
New Folder
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
// disabled: true,
|
// disabled: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [t]);
|
}, [t, showFolderCreateModal]);
|
||||||
|
|
||||||
const handleDelete = useCallback(() => {
|
const { handleRemoveFile } = useHandleDeleteFile(selectedRowKeys);
|
||||||
showDeleteConfirm({
|
|
||||||
onOk: () => {
|
|
||||||
return removeDocument(selectedRowKeys);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}, [removeDocument, showDeleteConfirm, selectedRowKeys]);
|
|
||||||
|
|
||||||
const disabled = selectedRowKeys.length === 0;
|
const disabled = selectedRowKeys.length === 0;
|
||||||
|
|
||||||
@ -101,7 +95,7 @@ const FileToolbar = ({ selectedRowKeys }: IProps) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
key: '4',
|
key: '4',
|
||||||
onClick: handleDelete,
|
onClick: handleRemoveFile,
|
||||||
label: (
|
label: (
|
||||||
<Flex gap={10}>
|
<Flex gap={10}>
|
||||||
<span className={styles.deleteIconWrapper}>
|
<span className={styles.deleteIconWrapper}>
|
||||||
@ -112,7 +106,7 @@ const FileToolbar = ({ selectedRowKeys }: IProps) => {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [handleDelete, t]);
|
}, [handleRemoveFile, t]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.filter}>
|
<div className={styles.filter}>
|
||||||
|
64
web/src/pages/file-manager/file-upload-modal/index.tsx
Normal file
64
web/src/pages/file-manager/file-upload-modal/index.tsx
Normal file
@ -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 (
|
||||||
|
<>
|
||||||
|
<Modal
|
||||||
|
title="File upload"
|
||||||
|
open={isModalOpen}
|
||||||
|
onOk={handleOk}
|
||||||
|
onCancel={handleCancel}
|
||||||
|
>
|
||||||
|
<Segmented options={['Local uploads', 'S3 uploads']} block />
|
||||||
|
<Dragger {...props}>
|
||||||
|
<p className="ant-upload-drag-icon">
|
||||||
|
<InboxOutlined />
|
||||||
|
</p>
|
||||||
|
<p className="ant-upload-text">
|
||||||
|
Click or drag file to this area to upload
|
||||||
|
</p>
|
||||||
|
<p className="ant-upload-hint">
|
||||||
|
Support for a single or bulk upload. Strictly prohibited from
|
||||||
|
uploading company data or other banned files.
|
||||||
|
</p>
|
||||||
|
</Dragger>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FileUploadModal;
|
67
web/src/pages/file-manager/folder-create-modal/index.tsx
Normal file
67
web/src/pages/file-manager/folder-create-modal/index.tsx
Normal file
@ -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<IModalManagerChildrenProps, 'showModal'> {
|
||||||
|
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 (
|
||||||
|
<Modal
|
||||||
|
title={'New Folder'}
|
||||||
|
open={visible}
|
||||||
|
onOk={handleOk}
|
||||||
|
onCancel={handleCancel}
|
||||||
|
okButtonProps={{ loading }}
|
||||||
|
confirmLoading={loading}
|
||||||
|
>
|
||||||
|
<Form
|
||||||
|
name="basic"
|
||||||
|
labelCol={{ span: 4 }}
|
||||||
|
wrapperCol={{ span: 20 }}
|
||||||
|
style={{ maxWidth: 600 }}
|
||||||
|
onFinish={onFinish}
|
||||||
|
onFinishFailed={onFinishFailed}
|
||||||
|
autoComplete="off"
|
||||||
|
form={form}
|
||||||
|
>
|
||||||
|
<Form.Item<FieldType>
|
||||||
|
label={t('name')}
|
||||||
|
name="name"
|
||||||
|
rules={[{ required: true, message: t('namePlaceholder') }]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FolderCreateModal;
|
@ -1,7 +1,13 @@
|
|||||||
import { useSetModalState, useTranslate } from '@/hooks/commonHooks';
|
|
||||||
import {
|
import {
|
||||||
|
useSetModalState,
|
||||||
|
useShowDeleteConfirm,
|
||||||
|
useTranslate,
|
||||||
|
} from '@/hooks/commonHooks';
|
||||||
|
import {
|
||||||
|
useCreateFolder,
|
||||||
useFetchFileList,
|
useFetchFileList,
|
||||||
useFetchParentFolderList,
|
useFetchParentFolderList,
|
||||||
|
useRemoveFile,
|
||||||
useRenameFile,
|
useRenameFile,
|
||||||
useSelectFileList,
|
useSelectFileList,
|
||||||
useSelectParentFolderList,
|
useSelectParentFolderList,
|
||||||
@ -144,7 +150,7 @@ export const useRenameCurrentFile = () => {
|
|||||||
|
|
||||||
const onFileRenameOk = useCallback(
|
const onFileRenameOk = useCallback(
|
||||||
async (name: string) => {
|
async (name: string) => {
|
||||||
const ret = await renameFile(file.id, name);
|
const ret = await renameFile(file.id, name, file.parent_id);
|
||||||
|
|
||||||
if (ret === 0) {
|
if (ret === 0) {
|
||||||
hideFileRenameModal();
|
hideFileRenameModal();
|
||||||
@ -191,3 +197,56 @@ export const useSelectBreadcrumbItems = () => {
|
|||||||
path: `/file?folderId=${x.id}`,
|
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']);
|
||||||
|
};
|
||||||
|
@ -7,16 +7,20 @@ import ActionCell from './action-cell';
|
|||||||
import FileToolbar from './file-toolbar';
|
import FileToolbar from './file-toolbar';
|
||||||
import {
|
import {
|
||||||
useGetRowSelection,
|
useGetRowSelection,
|
||||||
|
useHandleCreateFolder,
|
||||||
useNavigateToOtherFolder,
|
useNavigateToOtherFolder,
|
||||||
useRenameCurrentFile,
|
useRenameCurrentFile,
|
||||||
|
useSelectFileListLoading,
|
||||||
} from './hooks';
|
} from './hooks';
|
||||||
|
|
||||||
import RenameModal from '@/components/rename-modal';
|
import RenameModal from '@/components/rename-modal';
|
||||||
|
import FolderCreateModal from './folder-create-modal';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
const FileManager = () => {
|
const FileManager = () => {
|
||||||
const fileList = useSelectFileList();
|
const fileList = useSelectFileList();
|
||||||
const rowSelection = useGetRowSelection();
|
const rowSelection = useGetRowSelection();
|
||||||
|
const loading = useSelectFileListLoading();
|
||||||
const navigateToOtherFolder = useNavigateToOtherFolder();
|
const navigateToOtherFolder = useNavigateToOtherFolder();
|
||||||
const {
|
const {
|
||||||
fileRenameVisible,
|
fileRenameVisible,
|
||||||
@ -26,6 +30,13 @@ const FileManager = () => {
|
|||||||
initialFileName,
|
initialFileName,
|
||||||
onFileRenameOk,
|
onFileRenameOk,
|
||||||
} = useRenameCurrentFile();
|
} = useRenameCurrentFile();
|
||||||
|
const {
|
||||||
|
folderCreateModalVisible,
|
||||||
|
showFolderCreateModal,
|
||||||
|
hideFolderCreateModal,
|
||||||
|
folderCreateLoading,
|
||||||
|
onFolderCreateOk,
|
||||||
|
} = useHandleCreateFolder();
|
||||||
|
|
||||||
const columns: ColumnsType<IFile> = [
|
const columns: ColumnsType<IFile> = [
|
||||||
{
|
{
|
||||||
@ -78,12 +89,14 @@ const FileManager = () => {
|
|||||||
<section className={styles.fileManagerWrapper}>
|
<section className={styles.fileManagerWrapper}>
|
||||||
<FileToolbar
|
<FileToolbar
|
||||||
selectedRowKeys={rowSelection.selectedRowKeys as string[]}
|
selectedRowKeys={rowSelection.selectedRowKeys as string[]}
|
||||||
|
showFolderCreateModal={showFolderCreateModal}
|
||||||
></FileToolbar>
|
></FileToolbar>
|
||||||
<Table
|
<Table
|
||||||
dataSource={fileList}
|
dataSource={fileList}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey={'id'}
|
rowKey={'id'}
|
||||||
rowSelection={rowSelection}
|
rowSelection={rowSelection}
|
||||||
|
loading={loading}
|
||||||
/>
|
/>
|
||||||
<RenameModal
|
<RenameModal
|
||||||
visible={fileRenameVisible}
|
visible={fileRenameVisible}
|
||||||
@ -92,6 +105,12 @@ const FileManager = () => {
|
|||||||
initialName={initialFileName}
|
initialName={initialFileName}
|
||||||
loading={fileRenameLoading}
|
loading={fileRenameLoading}
|
||||||
></RenameModal>
|
></RenameModal>
|
||||||
|
<FolderCreateModal
|
||||||
|
loading={folderCreateLoading}
|
||||||
|
visible={folderCreateModalVisible}
|
||||||
|
hideModal={hideFolderCreateModal}
|
||||||
|
onOk={onFolderCreateOk}
|
||||||
|
></FolderCreateModal>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { IFile, IFolder } from '@/interfaces/database/file-manager';
|
import { IFile, IFolder } from '@/interfaces/database/file-manager';
|
||||||
import fileManagerService from '@/services/fileManagerService';
|
import fileManagerService from '@/services/fileManagerService';
|
||||||
|
import omit from 'lodash/omit';
|
||||||
import { DvaModel } from 'umi';
|
import { DvaModel } from 'umi';
|
||||||
|
|
||||||
export interface FileManagerModelState {
|
export interface FileManagerModelState {
|
||||||
@ -20,12 +21,14 @@ const model: DvaModel<FileManagerModelState> = {
|
|||||||
},
|
},
|
||||||
effects: {
|
effects: {
|
||||||
*removeFile({ payload = {} }, { call, put }) {
|
*removeFile({ payload = {} }, { call, put }) {
|
||||||
const { data } = yield call(fileManagerService.removeFile, payload);
|
const { data } = yield call(fileManagerService.removeFile, {
|
||||||
|
fileIds: payload.fileIds,
|
||||||
|
});
|
||||||
const { retcode } = data;
|
const { retcode } = data;
|
||||||
if (retcode === 0) {
|
if (retcode === 0) {
|
||||||
yield put({
|
yield put({
|
||||||
type: 'listFile',
|
type: 'listFile',
|
||||||
payload: data.data?.files ?? [],
|
payload: { parentId: payload.parentId },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -41,9 +44,25 @@ const model: DvaModel<FileManagerModelState> = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
*renameFile({ payload = {} }, { call, put }) {
|
*renameFile({ payload = {} }, { call, put }) {
|
||||||
const { data } = yield call(fileManagerService.renameFile, payload);
|
const { data } = yield call(
|
||||||
|
fileManagerService.renameFile,
|
||||||
|
omit(payload, ['parentId']),
|
||||||
|
);
|
||||||
if (data.retcode === 0) {
|
if (data.retcode === 0) {
|
||||||
yield put({ type: 'listFile' });
|
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',
|
||||||
|
payload: { parentId: payload.parentId },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return data.retcode;
|
return data.retcode;
|
||||||
},
|
},
|
||||||
|
@ -2,8 +2,14 @@ import api from '@/utils/api';
|
|||||||
import registerServer from '@/utils/registerServer';
|
import registerServer from '@/utils/registerServer';
|
||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
|
|
||||||
const { listFile, removeFile, uploadFile, renameFile, getAllParentFolder } =
|
const {
|
||||||
api;
|
listFile,
|
||||||
|
removeFile,
|
||||||
|
uploadFile,
|
||||||
|
renameFile,
|
||||||
|
getAllParentFolder,
|
||||||
|
createFolder,
|
||||||
|
} = api;
|
||||||
|
|
||||||
const methods = {
|
const methods = {
|
||||||
listFile: {
|
listFile: {
|
||||||
@ -26,6 +32,10 @@ const methods = {
|
|||||||
url: getAllParentFolder,
|
url: getAllParentFolder,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
},
|
},
|
||||||
|
createFolder: {
|
||||||
|
url: createFolder,
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
const fileManagerService = registerServer<keyof typeof methods>(
|
const fileManagerService = registerServer<keyof typeof methods>(
|
||||||
|
@ -73,4 +73,5 @@ export default {
|
|||||||
removeFile: `${api_host}/file/rm`,
|
removeFile: `${api_host}/file/rm`,
|
||||||
renameFile: `${api_host}/file/rename`,
|
renameFile: `${api_host}/file/rename`,
|
||||||
getAllParentFolder: `${api_host}/file/all_parent_folder`,
|
getAllParentFolder: `${api_host}/file/all_parent_folder`,
|
||||||
|
createFolder: `${api_host}/file/create`,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user