mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-02-03 17:15:08 +08:00
### What problem does this PR solve? feat: Move files in file manager #1826 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -0,0 +1,64 @@
|
||||
import { useFetchPureFileList } from '@/hooks/file-manager-hooks';
|
||||
import { IFile } from '@/interfaces/database/file-manager';
|
||||
import type { GetProp, TreeSelectProps } from 'antd';
|
||||
import { TreeSelect } from 'antd';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
type DefaultOptionType = GetProp<TreeSelectProps, 'treeData'>[number];
|
||||
|
||||
interface IProps {
|
||||
value?: string;
|
||||
onChange?: (value: string) => void;
|
||||
}
|
||||
|
||||
const AsyncTreeSelect = ({ value, onChange }: IProps) => {
|
||||
const { fetchList } = useFetchPureFileList();
|
||||
const [treeData, setTreeData] = useState<Omit<DefaultOptionType, 'label'>[]>(
|
||||
[],
|
||||
);
|
||||
|
||||
const onLoadData: TreeSelectProps['loadData'] = useCallback(
|
||||
async ({ id }) => {
|
||||
const ret = await fetchList(id);
|
||||
if (ret.retcode === 0) {
|
||||
setTreeData((tree) => {
|
||||
return tree.concat(
|
||||
ret.data.files
|
||||
.filter((x: IFile) => x.type === 'folder')
|
||||
.map((x: IFile) => ({
|
||||
id: x.id,
|
||||
pId: x.parent_id,
|
||||
value: x.id,
|
||||
title: x.name,
|
||||
isLeaf: false,
|
||||
})),
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
[fetchList],
|
||||
);
|
||||
|
||||
const handleChange = (newValue: string) => {
|
||||
onChange?.(newValue);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
onLoadData?.({ id: '', props: '' });
|
||||
}, [onLoadData]);
|
||||
|
||||
return (
|
||||
<TreeSelect
|
||||
treeDataSimpleMode
|
||||
style={{ width: '100%' }}
|
||||
value={value}
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
placeholder="Please select"
|
||||
onChange={handleChange}
|
||||
loadData={onLoadData}
|
||||
treeData={treeData}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default AsyncTreeSelect;
|
||||
54
web/src/pages/file-manager/move-file-modal/index.tsx
Normal file
54
web/src/pages/file-manager/move-file-modal/index.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { Form, Modal } from 'antd';
|
||||
import AsyncTreeSelect from './async-tree-select';
|
||||
|
||||
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
||||
loading: boolean;
|
||||
onOk: (id: string) => void;
|
||||
}
|
||||
|
||||
const FileMovingModal = ({ visible, hideModal, loading, onOk }: IProps) => {
|
||||
const [form] = Form.useForm();
|
||||
const { t } = useTranslate('fileManager');
|
||||
|
||||
type FieldType = {
|
||||
name?: string;
|
||||
};
|
||||
|
||||
const handleOk = async () => {
|
||||
const ret = await form.validateFields();
|
||||
|
||||
return onOk(ret.name);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={t('move', { keyPrefix: 'common' })}
|
||||
open={visible}
|
||||
onOk={handleOk}
|
||||
onCancel={hideModal}
|
||||
okButtonProps={{ loading }}
|
||||
confirmLoading={loading}
|
||||
width={600}
|
||||
>
|
||||
<Form
|
||||
name="basic"
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
autoComplete="off"
|
||||
form={form}
|
||||
>
|
||||
<Form.Item<FieldType>
|
||||
label={t('destinationFolder')}
|
||||
name="name"
|
||||
rules={[{ required: true, message: t('pleaseSelect') }]}
|
||||
>
|
||||
<AsyncTreeSelect></AsyncTreeSelect>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default FileMovingModal;
|
||||
Reference in New Issue
Block a user