balibabu commited on
Commit
ba91369
·
1 Parent(s): 0a4eab6

feat: Move files in file manager #1826 (#1837)

Browse files

### 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)

web/src/assets/svg/move.svg ADDED
web/src/hooks/file-manager-hooks.ts CHANGED
@@ -28,6 +28,23 @@ export interface IListResult {
28
  loading: boolean;
29
  }
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  export const useFetchFileList = (): ResponseType<any> & IListResult => {
32
  const { searchString, handleInputChange } = useHandleSearchChange();
33
  const { pagination, setPagination } = useGetPaginationWithRouter();
@@ -225,3 +242,31 @@ export const useConnectToKnowledge = () => {
225
 
226
  return { data, loading, connectFileToKnowledge: mutateAsync };
227
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  loading: boolean;
29
  }
30
 
31
+ export const useFetchPureFileList = () => {
32
+ const { mutateAsync, isPending: loading } = useMutation({
33
+ mutationKey: ['fetchPureFileList'],
34
+ gcTime: 0,
35
+
36
+ mutationFn: async (parentId: string) => {
37
+ const { data } = await fileManagerService.listFile({
38
+ parent_id: parentId,
39
+ });
40
+
41
+ return data;
42
+ },
43
+ });
44
+
45
+ return { loading, fetchList: mutateAsync };
46
+ };
47
+
48
  export const useFetchFileList = (): ResponseType<any> & IListResult => {
49
  const { searchString, handleInputChange } = useHandleSearchChange();
50
  const { pagination, setPagination } = useGetPaginationWithRouter();
 
242
 
243
  return { data, loading, connectFileToKnowledge: mutateAsync };
244
  };
245
+
246
+ export interface IMoveFileBody {
247
+ src_file_ids: string[];
248
+ dest_file_id: string; // target folder id
249
+ }
250
+
251
+ export const useMoveFile = () => {
252
+ const queryClient = useQueryClient();
253
+ const { t } = useTranslation();
254
+
255
+ const {
256
+ data,
257
+ isPending: loading,
258
+ mutateAsync,
259
+ } = useMutation({
260
+ mutationKey: ['moveFile'],
261
+ mutationFn: async (params: IMoveFileBody) => {
262
+ const { data } = await fileManagerService.moveFile(params);
263
+ if (data.retcode === 0) {
264
+ message.success(t('message.operated'));
265
+ queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
266
+ }
267
+ return data.retcode;
268
+ },
269
+ });
270
+
271
+ return { data, loading, moveFile: mutateAsync };
272
+ };
web/src/locales/en.ts CHANGED
@@ -26,6 +26,7 @@ export default {
26
  download: 'Download',
27
  close: 'Close',
28
  preview: 'Preview',
 
29
  },
30
  login: {
31
  login: 'Sign in',
@@ -564,6 +565,7 @@ The above is the content you need to summarize.`,
564
  fileError: 'File error',
565
  uploadLimit:
566
  'The file size cannot exceed 10M, and the total number of files cannot exceed 128',
 
567
  },
568
  flow: {
569
  cite: 'Cite',
 
26
  download: 'Download',
27
  close: 'Close',
28
  preview: 'Preview',
29
+ move: 'Move',
30
  },
31
  login: {
32
  login: 'Sign in',
 
565
  fileError: 'File error',
566
  uploadLimit:
567
  'The file size cannot exceed 10M, and the total number of files cannot exceed 128',
568
+ destinationFolder: 'Destination folder',
569
  },
570
  flow: {
571
  cite: 'Cite',
web/src/locales/zh-traditional.ts CHANGED
@@ -26,6 +26,7 @@ export default {
26
  download: '下載',
27
  close: '關閉',
28
  preview: '預覽',
 
29
  },
30
  login: {
31
  login: '登入',
@@ -524,6 +525,7 @@ export default {
524
  preview: '預覽',
525
  fileError: '文件錯誤',
526
  uploadLimit: '文件大小不能超過10M,文件總數不超過128個',
 
527
  },
528
  flow: {
529
  cite: '引用',
 
26
  download: '下載',
27
  close: '關閉',
28
  preview: '預覽',
29
+ move: '移動',
30
  },
31
  login: {
32
  login: '登入',
 
525
  preview: '預覽',
526
  fileError: '文件錯誤',
527
  uploadLimit: '文件大小不能超過10M,文件總數不超過128個',
528
+ destinationFolder: '目標資料夾',
529
  },
530
  flow: {
531
  cite: '引用',
web/src/locales/zh.ts CHANGED
@@ -26,6 +26,7 @@ export default {
26
  download: '下载',
27
  close: '关闭',
28
  preview: '预览',
 
29
  },
30
  login: {
31
  login: '登录',
@@ -542,6 +543,7 @@ export default {
542
  preview: '预览',
543
  fileError: '文件错误',
544
  uploadLimit: '文件大小不能超过10M,文件总数不超过128个',
 
545
  },
546
  flow: {
547
  flow: '工作流',
 
26
  download: '下载',
27
  close: '关闭',
28
  preview: '预览',
29
+ move: '移动',
30
  },
31
  login: {
32
  login: '登录',
 
543
  preview: '预览',
544
  fileError: '文件错误',
545
  uploadLimit: '文件大小不能超过10M,文件总数不超过128个',
546
+ destinationFolder: '目标文件夹',
547
  },
548
  flow: {
549
  flow: '工作流',
web/src/pages/file-manager/action-cell/index.tsx CHANGED
@@ -1,6 +1,12 @@
 
 
1
  import { useTranslate } from '@/hooks/common-hooks';
2
  import { IFile } from '@/interfaces/database/file-manager';
3
  import { api_host } from '@/utils/api';
 
 
 
 
4
  import { downloadFile } from '@/utils/file-util';
5
  import {
6
  DeleteOutlined,
@@ -11,18 +17,13 @@ import {
11
  } from '@ant-design/icons';
12
  import { Button, Space, Tooltip } from 'antd';
13
  import { useHandleDeleteFile } from '../hooks';
14
-
15
- import NewDocumentLink from '@/components/new-document-link';
16
- import {
17
- getExtension,
18
- isSupportedPreviewDocumentType,
19
- } from '@/utils/document-util';
20
  import styles from './index.less';
21
 
22
  interface IProps {
23
  record: IFile;
24
  setCurrentRecord: (record: any) => void;
25
  showRenameModal: (record: IFile) => void;
 
26
  showConnectToKnowledgeModal: (record: IFile) => void;
27
  setSelectedRowKeys(keys: string[]): void;
28
  }
@@ -33,6 +34,7 @@ const ActionCell = ({
33
  showRenameModal,
34
  showConnectToKnowledgeModal,
35
  setSelectedRowKeys,
 
36
  }: IProps) => {
37
  const documentId = record.id;
38
  const beingUsed = false;
@@ -64,6 +66,10 @@ const ActionCell = ({
64
  showConnectToKnowledgeModal(record);
65
  };
66
 
 
 
 
 
67
  return (
68
  <Space size={0}>
69
  {isKnowledgeBase || (
@@ -90,6 +96,18 @@ const ActionCell = ({
90
  </Button>
91
  </Tooltip>
92
  )}
 
 
 
 
 
 
 
 
 
 
 
 
93
  {isKnowledgeBase || (
94
  <Tooltip title={t('delete', { keyPrefix: 'common' })}>
95
  <Button
 
1
+ import NewDocumentLink from '@/components/new-document-link';
2
+ import SvgIcon from '@/components/svg-icon';
3
  import { useTranslate } from '@/hooks/common-hooks';
4
  import { IFile } from '@/interfaces/database/file-manager';
5
  import { api_host } from '@/utils/api';
6
+ import {
7
+ getExtension,
8
+ isSupportedPreviewDocumentType,
9
+ } from '@/utils/document-util';
10
  import { downloadFile } from '@/utils/file-util';
11
  import {
12
  DeleteOutlined,
 
17
  } from '@ant-design/icons';
18
  import { Button, Space, Tooltip } from 'antd';
19
  import { useHandleDeleteFile } from '../hooks';
 
 
 
 
 
 
20
  import styles from './index.less';
21
 
22
  interface IProps {
23
  record: IFile;
24
  setCurrentRecord: (record: any) => void;
25
  showRenameModal: (record: IFile) => void;
26
+ showMoveFileModal: (ids: string[]) => void;
27
  showConnectToKnowledgeModal: (record: IFile) => void;
28
  setSelectedRowKeys(keys: string[]): void;
29
  }
 
34
  showRenameModal,
35
  showConnectToKnowledgeModal,
36
  setSelectedRowKeys,
37
+ showMoveFileModal,
38
  }: IProps) => {
39
  const documentId = record.id;
40
  const beingUsed = false;
 
66
  showConnectToKnowledgeModal(record);
67
  };
68
 
69
+ const onShowMoveFileModal = () => {
70
+ showMoveFileModal([documentId]);
71
+ };
72
+
73
  return (
74
  <Space size={0}>
75
  {isKnowledgeBase || (
 
96
  </Button>
97
  </Tooltip>
98
  )}
99
+ {isKnowledgeBase || (
100
+ <Tooltip title={t('move', { keyPrefix: 'common' })}>
101
+ <Button
102
+ type="text"
103
+ disabled={beingUsed}
104
+ onClick={onShowMoveFileModal}
105
+ className={styles.iconButton}
106
+ >
107
+ <SvgIcon name={`move`} width={16}></SvgIcon>
108
+ </Button>
109
+ </Tooltip>
110
+ )}
111
  {isKnowledgeBase || (
112
  <Tooltip title={t('delete', { keyPrefix: 'common' })}>
113
  <Button
web/src/pages/file-manager/file-toolbar.tsx CHANGED
@@ -17,13 +17,14 @@ import {
17
  MenuProps,
18
  Space,
19
  } from 'antd';
20
- import { useMemo } from 'react';
21
  import {
22
  useHandleBreadcrumbClick,
23
  useHandleDeleteFile,
24
  useSelectBreadcrumbItems,
25
  } from './hooks';
26
 
 
27
  import {
28
  IListResult,
29
  useFetchParentFolderList,
@@ -36,6 +37,7 @@ interface IProps
36
  showFolderCreateModal: () => void;
37
  showFileUploadModal: () => void;
38
  setSelectedRowKeys: (keys: string[]) => void;
 
39
  }
40
 
41
  const FileToolbar = ({
@@ -45,6 +47,7 @@ const FileToolbar = ({
45
  setSelectedRowKeys,
46
  searchString,
47
  handleInputChange,
 
48
  }: IProps) => {
49
  const { t } = useTranslate('knowledgeDetails');
50
  const breadcrumbItems = useSelectBreadcrumbItems();
@@ -111,6 +114,10 @@ const FileToolbar = ({
111
  setSelectedRowKeys,
112
  );
113
 
 
 
 
 
114
  const disabled = selectedRowKeys.length === 0;
115
 
116
  const items: MenuProps['items'] = useMemo(() => {
@@ -127,8 +134,20 @@ const FileToolbar = ({
127
  </Flex>
128
  ),
129
  },
 
 
 
 
 
 
 
 
 
 
 
 
130
  ];
131
- }, [handleRemoveFile, t]);
132
 
133
  return (
134
  <div className={styles.filter}>
 
17
  MenuProps,
18
  Space,
19
  } from 'antd';
20
+ import { useCallback, useMemo } from 'react';
21
  import {
22
  useHandleBreadcrumbClick,
23
  useHandleDeleteFile,
24
  useSelectBreadcrumbItems,
25
  } from './hooks';
26
 
27
+ import SvgIcon from '@/components/svg-icon';
28
  import {
29
  IListResult,
30
  useFetchParentFolderList,
 
37
  showFolderCreateModal: () => void;
38
  showFileUploadModal: () => void;
39
  setSelectedRowKeys: (keys: string[]) => void;
40
+ showMoveFileModal: (ids: string[]) => void;
41
  }
42
 
43
  const FileToolbar = ({
 
47
  setSelectedRowKeys,
48
  searchString,
49
  handleInputChange,
50
+ showMoveFileModal,
51
  }: IProps) => {
52
  const { t } = useTranslate('knowledgeDetails');
53
  const breadcrumbItems = useSelectBreadcrumbItems();
 
114
  setSelectedRowKeys,
115
  );
116
 
117
+ const handleShowMoveFileModal = useCallback(() => {
118
+ showMoveFileModal(selectedRowKeys);
119
+ }, [selectedRowKeys, showMoveFileModal]);
120
+
121
  const disabled = selectedRowKeys.length === 0;
122
 
123
  const items: MenuProps['items'] = useMemo(() => {
 
134
  </Flex>
135
  ),
136
  },
137
+ {
138
+ key: '5',
139
+ onClick: handleShowMoveFileModal,
140
+ label: (
141
+ <Flex gap={10}>
142
+ <span className={styles.deleteIconWrapper}>
143
+ <SvgIcon name={`move`} width={18}></SvgIcon>
144
+ </span>
145
+ <b>{t('move', { keyPrefix: 'common' })}</b>
146
+ </Flex>
147
+ ),
148
+ },
149
  ];
150
+ }, [handleShowMoveFileModal, t, handleRemoveFile]);
151
 
152
  return (
153
  <div className={styles.filter}>
web/src/pages/file-manager/folder-create-modal/index.tsx CHANGED
@@ -21,24 +21,12 @@ const FolderCreateModal = ({ visible, hideModal, loading, onOk }: IProps) => {
21
  return onOk(ret.name);
22
  };
23
 
24
- const handleCancel = () => {
25
- hideModal();
26
- };
27
-
28
- const onFinish = (values: any) => {
29
- console.log('Success:', values);
30
- };
31
-
32
- const onFinishFailed = (errorInfo: any) => {
33
- console.log('Failed:', errorInfo);
34
- };
35
-
36
  return (
37
  <Modal
38
  title={t('newFolder', { keyPrefix: 'fileManager' })}
39
  open={visible}
40
  onOk={handleOk}
41
- onCancel={handleCancel}
42
  okButtonProps={{ loading }}
43
  confirmLoading={loading}
44
  >
@@ -47,8 +35,6 @@ const FolderCreateModal = ({ visible, hideModal, loading, onOk }: IProps) => {
47
  labelCol={{ span: 4 }}
48
  wrapperCol={{ span: 20 }}
49
  style={{ maxWidth: 600 }}
50
- onFinish={onFinish}
51
- onFinishFailed={onFinishFailed}
52
  autoComplete="off"
53
  form={form}
54
  >
 
21
  return onOk(ret.name);
22
  };
23
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  return (
25
  <Modal
26
  title={t('newFolder', { keyPrefix: 'fileManager' })}
27
  open={visible}
28
  onOk={handleOk}
29
+ onCancel={hideModal}
30
  okButtonProps={{ loading }}
31
  confirmLoading={loading}
32
  >
 
35
  labelCol={{ span: 4 }}
36
  wrapperCol={{ span: 20 }}
37
  style={{ maxWidth: 600 }}
 
 
38
  autoComplete="off"
39
  form={form}
40
  >
web/src/pages/file-manager/hooks.ts CHANGED
@@ -4,6 +4,7 @@ import {
4
  useCreateFolder,
5
  useDeleteFile,
6
  useFetchParentFolderList,
 
7
  useRenameFile,
8
  useUploadFile,
9
  } from '@/hooks/file-manager-hooks';
@@ -246,3 +247,48 @@ export const useHandleBreadcrumbClick = () => {
246
 
247
  return { handleBreadcrumbClick };
248
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  useCreateFolder,
5
  useDeleteFile,
6
  useFetchParentFolderList,
7
+ useMoveFile,
8
  useRenameFile,
9
  useUploadFile,
10
  } from '@/hooks/file-manager-hooks';
 
247
 
248
  return { handleBreadcrumbClick };
249
  };
250
+
251
+ export const useHandleMoveFile = (
252
+ setSelectedRowKeys: (keys: string[]) => void,
253
+ ) => {
254
+ const {
255
+ visible: moveFileVisible,
256
+ hideModal: hideMoveFileModal,
257
+ showModal: showMoveFileModal,
258
+ } = useSetModalState();
259
+ const { moveFile, loading } = useMoveFile();
260
+ const [sourceFileIds, setSourceFileIds] = useState<string[]>([]);
261
+
262
+ const onMoveFileOk = useCallback(
263
+ async (targetFolderId: string) => {
264
+ const ret = await moveFile({
265
+ src_file_ids: sourceFileIds,
266
+ dest_file_id: targetFolderId,
267
+ });
268
+
269
+ if (ret === 0) {
270
+ setSelectedRowKeys([]);
271
+ hideMoveFileModal();
272
+ }
273
+ return ret;
274
+ },
275
+ [moveFile, hideMoveFileModal, sourceFileIds, setSelectedRowKeys],
276
+ );
277
+
278
+ const handleShowMoveFileModal = useCallback(
279
+ (ids: string[]) => {
280
+ setSourceFileIds(ids);
281
+ showMoveFileModal();
282
+ },
283
+ [showMoveFileModal],
284
+ );
285
+
286
+ return {
287
+ initialValue: '',
288
+ moveFileLoading: loading,
289
+ onMoveFileOk,
290
+ moveFileVisible,
291
+ hideMoveFileModal,
292
+ showMoveFileModal: handleShowMoveFileModal,
293
+ };
294
+ };
web/src/pages/file-manager/index.tsx CHANGED
@@ -9,6 +9,7 @@ import {
9
  useGetRowSelection,
10
  useHandleConnectToKnowledge,
11
  useHandleCreateFolder,
 
12
  useHandleUploadFile,
13
  useNavigateToOtherFolder,
14
  useRenameCurrentFile,
@@ -23,6 +24,7 @@ import { getExtension } from '@/utils/document-util';
23
  import ConnectToKnowledgeModal from './connect-to-knowledge-modal';
24
  import FolderCreateModal from './folder-create-modal';
25
  import styles from './index.less';
 
26
 
27
  const { Text } = Typography;
28
 
@@ -61,7 +63,13 @@ const FileManager = () => {
61
  initialValue,
62
  connectToKnowledgeLoading,
63
  } = useHandleConnectToKnowledge();
64
- // const { pagination } = useGetFilesPagination();
 
 
 
 
 
 
65
  const { pagination, data, searchString, handleInputChange, loading } =
66
  useFetchFileList();
67
  const columns: ColumnsType<IFile> = [
@@ -139,6 +147,7 @@ const FileManager = () => {
139
  console.info(record);
140
  }}
141
  showRenameModal={showFileRenameModal}
 
142
  showConnectToKnowledgeModal={showConnectToKnowledgeModal}
143
  setSelectedRowKeys={setSelectedRowKeys}
144
  ></ActionCell>
@@ -155,6 +164,7 @@ const FileManager = () => {
155
  showFolderCreateModal={showFolderCreateModal}
156
  showFileUploadModal={showFileUploadModal}
157
  setSelectedRowKeys={setSelectedRowKeys}
 
158
  ></FileToolbar>
159
  <Table
160
  dataSource={data?.files}
@@ -191,6 +201,14 @@ const FileManager = () => {
191
  onOk={onConnectToKnowledgeOk}
192
  loading={connectToKnowledgeLoading}
193
  ></ConnectToKnowledgeModal>
 
 
 
 
 
 
 
 
194
  </section>
195
  );
196
  };
 
9
  useGetRowSelection,
10
  useHandleConnectToKnowledge,
11
  useHandleCreateFolder,
12
+ useHandleMoveFile,
13
  useHandleUploadFile,
14
  useNavigateToOtherFolder,
15
  useRenameCurrentFile,
 
24
  import ConnectToKnowledgeModal from './connect-to-knowledge-modal';
25
  import FolderCreateModal from './folder-create-modal';
26
  import styles from './index.less';
27
+ import FileMovingModal from './move-file-modal';
28
 
29
  const { Text } = Typography;
30
 
 
63
  initialValue,
64
  connectToKnowledgeLoading,
65
  } = useHandleConnectToKnowledge();
66
+ const {
67
+ showMoveFileModal,
68
+ moveFileVisible,
69
+ onMoveFileOk,
70
+ hideMoveFileModal,
71
+ moveFileLoading,
72
+ } = useHandleMoveFile(setSelectedRowKeys);
73
  const { pagination, data, searchString, handleInputChange, loading } =
74
  useFetchFileList();
75
  const columns: ColumnsType<IFile> = [
 
147
  console.info(record);
148
  }}
149
  showRenameModal={showFileRenameModal}
150
+ showMoveFileModal={showMoveFileModal}
151
  showConnectToKnowledgeModal={showConnectToKnowledgeModal}
152
  setSelectedRowKeys={setSelectedRowKeys}
153
  ></ActionCell>
 
164
  showFolderCreateModal={showFolderCreateModal}
165
  showFileUploadModal={showFileUploadModal}
166
  setSelectedRowKeys={setSelectedRowKeys}
167
+ showMoveFileModal={showMoveFileModal}
168
  ></FileToolbar>
169
  <Table
170
  dataSource={data?.files}
 
201
  onOk={onConnectToKnowledgeOk}
202
  loading={connectToKnowledgeLoading}
203
  ></ConnectToKnowledgeModal>
204
+ {moveFileVisible && (
205
+ <FileMovingModal
206
+ visible={moveFileVisible}
207
+ hideModal={hideMoveFileModal}
208
+ onOk={onMoveFileOk}
209
+ loading={moveFileLoading}
210
+ ></FileMovingModal>
211
+ )}
212
  </section>
213
  );
214
  };
web/src/pages/file-manager/move-file-modal/async-tree-select.tsx ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useFetchPureFileList } from '@/hooks/file-manager-hooks';
2
+ import { IFile } from '@/interfaces/database/file-manager';
3
+ import type { GetProp, TreeSelectProps } from 'antd';
4
+ import { TreeSelect } from 'antd';
5
+ import { useCallback, useEffect, useState } from 'react';
6
+
7
+ type DefaultOptionType = GetProp<TreeSelectProps, 'treeData'>[number];
8
+
9
+ interface IProps {
10
+ value?: string;
11
+ onChange?: (value: string) => void;
12
+ }
13
+
14
+ const AsyncTreeSelect = ({ value, onChange }: IProps) => {
15
+ const { fetchList } = useFetchPureFileList();
16
+ const [treeData, setTreeData] = useState<Omit<DefaultOptionType, 'label'>[]>(
17
+ [],
18
+ );
19
+
20
+ const onLoadData: TreeSelectProps['loadData'] = useCallback(
21
+ async ({ id }) => {
22
+ const ret = await fetchList(id);
23
+ if (ret.retcode === 0) {
24
+ setTreeData((tree) => {
25
+ return tree.concat(
26
+ ret.data.files
27
+ .filter((x: IFile) => x.type === 'folder')
28
+ .map((x: IFile) => ({
29
+ id: x.id,
30
+ pId: x.parent_id,
31
+ value: x.id,
32
+ title: x.name,
33
+ isLeaf: false,
34
+ })),
35
+ );
36
+ });
37
+ }
38
+ },
39
+ [fetchList],
40
+ );
41
+
42
+ const handleChange = (newValue: string) => {
43
+ onChange?.(newValue);
44
+ };
45
+
46
+ useEffect(() => {
47
+ onLoadData?.({ id: '', props: '' });
48
+ }, [onLoadData]);
49
+
50
+ return (
51
+ <TreeSelect
52
+ treeDataSimpleMode
53
+ style={{ width: '100%' }}
54
+ value={value}
55
+ dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
56
+ placeholder="Please select"
57
+ onChange={handleChange}
58
+ loadData={onLoadData}
59
+ treeData={treeData}
60
+ />
61
+ );
62
+ };
63
+
64
+ export default AsyncTreeSelect;
web/src/pages/file-manager/move-file-modal/index.tsx ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { IModalManagerChildrenProps } from '@/components/modal-manager';
2
+ import { useTranslate } from '@/hooks/common-hooks';
3
+ import { Form, Modal } from 'antd';
4
+ import AsyncTreeSelect from './async-tree-select';
5
+
6
+ interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
7
+ loading: boolean;
8
+ onOk: (id: string) => void;
9
+ }
10
+
11
+ const FileMovingModal = ({ visible, hideModal, loading, onOk }: IProps) => {
12
+ const [form] = Form.useForm();
13
+ const { t } = useTranslate('fileManager');
14
+
15
+ type FieldType = {
16
+ name?: string;
17
+ };
18
+
19
+ const handleOk = async () => {
20
+ const ret = await form.validateFields();
21
+
22
+ return onOk(ret.name);
23
+ };
24
+
25
+ return (
26
+ <Modal
27
+ title={t('move', { keyPrefix: 'common' })}
28
+ open={visible}
29
+ onOk={handleOk}
30
+ onCancel={hideModal}
31
+ okButtonProps={{ loading }}
32
+ confirmLoading={loading}
33
+ width={600}
34
+ >
35
+ <Form
36
+ name="basic"
37
+ labelCol={{ span: 6 }}
38
+ wrapperCol={{ span: 18 }}
39
+ autoComplete="off"
40
+ form={form}
41
+ >
42
+ <Form.Item<FieldType>
43
+ label={t('destinationFolder')}
44
+ name="name"
45
+ rules={[{ required: true, message: t('pleaseSelect') }]}
46
+ >
47
+ <AsyncTreeSelect></AsyncTreeSelect>
48
+ </Form.Item>
49
+ </Form>
50
+ </Modal>
51
+ );
52
+ };
53
+
54
+ export default FileMovingModal;
web/src/services/file-manager-service.ts CHANGED
@@ -13,6 +13,7 @@ const {
13
  connectFileToKnowledge,
14
  get_document_file,
15
  getFile,
 
16
  } = api;
17
 
18
  const methods = {
@@ -49,6 +50,10 @@ const methods = {
49
  method: 'get',
50
  responseType: 'blob',
51
  },
 
 
 
 
52
  } as const;
53
 
54
  const fileManagerService = registerServer<keyof typeof methods>(
 
13
  connectFileToKnowledge,
14
  get_document_file,
15
  getFile,
16
+ moveFile,
17
  } = api;
18
 
19
  const methods = {
 
50
  method: 'get',
51
  responseType: 'blob',
52
  },
53
+ moveFile: {
54
+ url: moveFile,
55
+ method: 'post',
56
+ },
57
  } as const;
58
 
59
  const fileManagerService = registerServer<keyof typeof methods>(
web/src/utils/api.ts CHANGED
@@ -79,6 +79,7 @@ export default {
79
  createFolder: `${api_host}/file/create`,
80
  connectFileToKnowledge: `${api_host}/file2document/convert`,
81
  getFile: `${api_host}/file/get`,
 
82
 
83
  // system
84
  getSystemVersion: `${api_host}/system/version`,
 
79
  createFolder: `${api_host}/file/create`,
80
  connectFileToKnowledge: `${api_host}/file2document/convert`,
81
  getFile: `${api_host}/file/get`,
82
+ moveFile: `${api_host}/file/mv`,
83
 
84
  // system
85
  getSystemVersion: `${api_host}/system/version`,