balibabu commited on
Commit
db736e5
·
1 Parent(s): 149dd1b

fix: Change document status with @tanstack/react-query #13306 (#2788)

Browse files

### What problem does this PR solve?

fix: Change document status with @tanstack/react-query #13306

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
- [ ] New Feature (non-breaking change which adds functionality)
- [ ] Documentation Update
- [ ] Refactoring
- [ ] Performance Improvement
- [ ] Other (please describe):

web/.umirc.ts CHANGED
@@ -18,8 +18,7 @@ export default defineConfig({
18
  history: {
19
  type: 'browser',
20
  },
21
- plugins: ['@react-dev-inspector/umi4-plugin', '@umijs/plugins/dist/dva'],
22
- dva: {},
23
  jsMinifier: 'terser',
24
  lessLoader: {
25
  modifyVars: {
 
18
  history: {
19
  type: 'browser',
20
  },
21
+ plugins: ['@react-dev-inspector/umi4-plugin'],
 
22
  jsMinifier: 'terser',
23
  lessLoader: {
24
  modifyVars: {
web/src/components/chunk-method-modal/index.tsx CHANGED
@@ -1,7 +1,5 @@
1
  import MaxTokenNumber from '@/components/max-token-number';
2
  import { IModalManagerChildrenProps } from '@/components/modal-manager';
3
- import { IKnowledgeFileParserConfig } from '@/interfaces/database/knowledge';
4
- import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
5
  import {
6
  MinusCircleOutlined,
7
  PlusOutlined,
@@ -22,6 +20,8 @@ import React, { useEffect, useMemo } from 'react';
22
  import { useFetchParserListOnMount } from './hooks';
23
 
24
  import { useTranslate } from '@/hooks/common-hooks';
 
 
25
  import Delimiter from '../delimiter';
26
  import EntityTypesItem from '../entity-types-item';
27
  import ExcelToHtml from '../excel-to-html';
@@ -39,7 +39,7 @@ interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
39
  ) => void;
40
  showModal?(): void;
41
  parserId: string;
42
- parserConfig: IKnowledgeFileParserConfig;
43
  documentExtension: string;
44
  documentId: string;
45
  }
@@ -115,7 +115,7 @@ const ChunkMethodModal: React.FC<IProps> = ({
115
  useEffect(() => {
116
  if (visible) {
117
  const pages =
118
- parserConfig.pages?.map((x) => ({ from: x[0], to: x[1] })) ?? [];
119
  form.setFieldsValue({
120
  pages: pages.length > 0 ? pages : [{ from: 1, to: 1024 }],
121
  parser_config: omit(parserConfig, 'pages'),
 
1
  import MaxTokenNumber from '@/components/max-token-number';
2
  import { IModalManagerChildrenProps } from '@/components/modal-manager';
 
 
3
  import {
4
  MinusCircleOutlined,
5
  PlusOutlined,
 
20
  import { useFetchParserListOnMount } from './hooks';
21
 
22
  import { useTranslate } from '@/hooks/common-hooks';
23
+ import { IParserConfig } from '@/interfaces/database/document';
24
+ import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
25
  import Delimiter from '../delimiter';
26
  import EntityTypesItem from '../entity-types-item';
27
  import ExcelToHtml from '../excel-to-html';
 
39
  ) => void;
40
  showModal?(): void;
41
  parserId: string;
42
+ parserConfig: IParserConfig;
43
  documentExtension: string;
44
  documentId: string;
45
  }
 
115
  useEffect(() => {
116
  if (visible) {
117
  const pages =
118
+ parserConfig?.pages?.map((x) => ({ from: x[0], to: x[1] })) ?? [];
119
  form.setFieldsValue({
120
  pages: pages.length > 0 ? pages : [{ from: 1, to: 1024 }],
121
  parser_config: omit(parserConfig, 'pages'),
web/src/components/file-icon/index.tsx CHANGED
@@ -1,7 +1,8 @@
1
  import { getExtension } from '@/utils/document-util';
2
  import SvgIcon from '../svg-icon';
3
 
4
- import { useSelectFileThumbnails } from '@/hooks/knowledge-hooks';
 
5
  import styles from './index.less';
6
 
7
  interface IProps {
@@ -11,10 +12,15 @@ interface IProps {
11
 
12
  const FileIcon = ({ name, id }: IProps) => {
13
  const fileExtension = getExtension(name);
14
- // TODO: replace this line with react query
15
- const fileThumbnails = useSelectFileThumbnails();
 
16
  const fileThumbnail = fileThumbnails[id];
17
 
 
 
 
 
18
  return fileThumbnail ? (
19
  <img src={fileThumbnail} className={styles.thumbnailImg}></img>
20
  ) : (
 
1
  import { getExtension } from '@/utils/document-util';
2
  import SvgIcon from '../svg-icon';
3
 
4
+ import { useFetchDocumentThumbnailsByIds } from '@/hooks/document-hooks';
5
+ import { useEffect } from 'react';
6
  import styles from './index.less';
7
 
8
  interface IProps {
 
12
 
13
  const FileIcon = ({ name, id }: IProps) => {
14
  const fileExtension = getExtension(name);
15
+
16
+ const { data: fileThumbnails, setDocumentIds } =
17
+ useFetchDocumentThumbnailsByIds();
18
  const fileThumbnail = fileThumbnails[id];
19
 
20
+ useEffect(() => {
21
+ setDocumentIds([id]);
22
+ }, [id, setDocumentIds]);
23
+
24
  return fileThumbnail ? (
25
  <img src={fileThumbnail} className={styles.thumbnailImg}></img>
26
  ) : (
web/src/components/message-item/index.tsx CHANGED
@@ -1,7 +1,6 @@
1
  import { ReactComponent as AssistantIcon } from '@/assets/svg/assistant.svg';
2
  import { MessageType } from '@/constants/chat';
3
  import { useSetModalState } from '@/hooks/common-hooks';
4
- import { useSelectFileThumbnails } from '@/hooks/knowledge-hooks';
5
  import { IReference } from '@/interfaces/database/chat';
6
  import { IChunk } from '@/interfaces/database/knowledge';
7
  import classNames from 'classnames';
@@ -50,7 +49,6 @@ const MessageItem = ({
50
  }: IProps) => {
51
  const isAssistant = item.role === MessageType.Assistant;
52
  const isUser = item.role === MessageType.User;
53
- const fileThumbnails = useSelectFileThumbnails();
54
  const { data: documentList, setDocumentIds } = useFetchDocumentInfosByIds();
55
  const { data: documentThumbnails, setDocumentIds: setIds } =
56
  useFetchDocumentThumbnailsByIds();
@@ -77,12 +75,12 @@ const MessageItem = ({
77
  const ids = item?.doc_ids ?? [];
78
  if (ids.length) {
79
  setDocumentIds(ids);
80
- const documentIds = ids.filter((x) => !(x in fileThumbnails));
81
  if (documentIds.length) {
82
  setIds(documentIds);
83
  }
84
  }
85
- }, [item.doc_ids, setDocumentIds, setIds, fileThumbnails]);
86
 
87
  return (
88
  <div
@@ -184,7 +182,7 @@ const MessageItem = ({
184
  renderItem={(item) => {
185
  // TODO:
186
  const fileThumbnail =
187
- documentThumbnails[item.id] || fileThumbnails[item.id];
188
  const fileExtension = getExtension(item.name);
189
  return (
190
  <List.Item>
 
1
  import { ReactComponent as AssistantIcon } from '@/assets/svg/assistant.svg';
2
  import { MessageType } from '@/constants/chat';
3
  import { useSetModalState } from '@/hooks/common-hooks';
 
4
  import { IReference } from '@/interfaces/database/chat';
5
  import { IChunk } from '@/interfaces/database/knowledge';
6
  import classNames from 'classnames';
 
49
  }: IProps) => {
50
  const isAssistant = item.role === MessageType.Assistant;
51
  const isUser = item.role === MessageType.User;
 
52
  const { data: documentList, setDocumentIds } = useFetchDocumentInfosByIds();
53
  const { data: documentThumbnails, setDocumentIds: setIds } =
54
  useFetchDocumentThumbnailsByIds();
 
75
  const ids = item?.doc_ids ?? [];
76
  if (ids.length) {
77
  setDocumentIds(ids);
78
+ const documentIds = ids.filter((x) => !(x in documentThumbnails));
79
  if (documentIds.length) {
80
  setIds(documentIds);
81
  }
82
  }
83
+ }, [item.doc_ids, setDocumentIds, setIds, documentThumbnails]);
84
 
85
  return (
86
  <div
 
182
  renderItem={(item) => {
183
  // TODO:
184
  const fileThumbnail =
185
+ documentThumbnails[item.id] || documentThumbnails[item.id];
186
  const fileExtension = getExtension(item.name);
187
  return (
188
  <List.Item>
web/src/hooks/document-hooks.ts CHANGED
@@ -1,17 +1,24 @@
1
  import { IDocumentInfo } from '@/interfaces/database/document';
2
- import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge';
3
  import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
 
4
  import chatService from '@/services/chat-service';
5
  import kbService from '@/services/knowledge-service';
6
  import { api_host } from '@/utils/api';
7
  import { buildChunkHighlights } from '@/utils/document-util';
8
- import { useMutation, useQuery } from '@tanstack/react-query';
9
- import { UploadFile } from 'antd';
 
10
  import { useCallback, useMemo, useState } from 'react';
11
  import { IHighlight } from 'react-pdf-highlighter';
12
- import { useDispatch, useSelector } from 'umi';
13
- import { useGetKnowledgeSearchParams } from './route-hook';
14
- import { useOneNamespaceEffectsLoading } from './store-hooks';
 
 
 
 
 
15
 
16
  export const useGetDocumentUrl = (documentId?: string) => {
17
  const getDocumentUrl = useCallback(
@@ -43,219 +50,284 @@ export const useGetChunkHighlights = (selectedChunk: IChunk) => {
43
  return { highlights, setWidthAndHeight };
44
  };
45
 
46
- export const useFetchDocumentList = () => {
47
  const { knowledgeId } = useGetKnowledgeSearchParams();
48
-
49
- const dispatch = useDispatch();
50
-
51
- const fetchKfList = useCallback(() => {
52
- return dispatch<any>({
53
- type: 'kFModel/getKfList',
54
- payload: {
 
 
 
 
 
55
  kb_id: knowledgeId,
56
- },
57
- });
58
- }, [dispatch, knowledgeId]);
59
-
60
- return fetchKfList;
61
- };
 
62
 
63
- export const useSetDocumentStatus = () => {
64
- const dispatch = useDispatch();
65
- const { knowledgeId } = useGetKnowledgeSearchParams();
 
 
 
66
 
67
- const setDocumentStatus = useCallback(
68
- (status: boolean, documentId: string) => {
69
- dispatch({
70
- type: 'kFModel/updateDocumentStatus',
71
- payload: {
72
- doc_id: documentId,
73
- status: Number(status),
74
- kb_id: knowledgeId,
75
- },
76
- });
77
  },
78
- [dispatch, knowledgeId],
79
  );
80
 
81
- return setDocumentStatus;
82
- };
83
-
84
- export const useSelectDocumentList = () => {
85
- const list: IKnowledgeFile[] = useSelector(
86
- (state: any) => state.kFModel.data,
87
- );
88
- return list;
89
  };
90
 
91
- export const useSaveDocumentName = () => {
92
- const dispatch = useDispatch();
93
- const { knowledgeId } = useGetKnowledgeSearchParams();
94
 
95
- const saveName = useCallback(
96
- (documentId: string, name: string) => {
97
- return dispatch<any>({
98
- type: 'kFModel/document_rename',
99
- payload: {
100
- doc_id: documentId,
101
- name: name,
102
- kb_id: knowledgeId,
103
- },
 
 
 
 
 
 
 
104
  });
 
 
 
 
 
105
  },
106
- [dispatch, knowledgeId],
107
- );
108
 
109
- return saveName;
110
  };
111
 
112
- export const useCreateDocument = () => {
113
- const dispatch = useDispatch();
114
- const { knowledgeId } = useGetKnowledgeSearchParams();
115
 
116
- const createDocument = useCallback(
117
- (name: string) => {
118
- try {
119
- return dispatch<any>({
120
- type: 'kFModel/document_create',
121
- payload: {
122
- name,
123
- kb_id: knowledgeId,
124
- },
125
- });
126
- } catch (errorInfo) {
127
- console.log('Failed:', errorInfo);
 
 
 
 
 
 
 
 
128
  }
 
129
  },
130
- [dispatch, knowledgeId],
131
- );
132
 
133
- return createDocument;
134
  };
135
 
136
- export const useSetDocumentParser = () => {
137
- const dispatch = useDispatch();
138
  const { knowledgeId } = useGetKnowledgeSearchParams();
 
 
139
 
140
- const setDocumentParser = useCallback(
141
- (
142
- parserId: string,
143
- documentId: string,
144
- parserConfig: IChangeParserConfigRequestBody,
145
- ) => {
146
- try {
147
- return dispatch<any>({
148
- type: 'kFModel/document_change_parser',
149
- payload: {
150
- parser_id: parserId,
151
- doc_id: documentId,
152
- kb_id: knowledgeId,
153
- parser_config: parserConfig,
154
- },
155
- });
156
- } catch (errorInfo) {
157
- console.log('Failed:', errorInfo);
 
158
  }
 
159
  },
160
- [dispatch, knowledgeId],
161
- );
162
 
163
- return setDocumentParser;
164
  };
165
 
166
- export const useRemoveDocument = () => {
167
- const dispatch = useDispatch();
168
- const { knowledgeId } = useGetKnowledgeSearchParams();
169
 
170
- const removeDocument = useCallback(
171
- (documentIds: string[]) => {
172
- try {
173
- return dispatch<any>({
174
- type: 'kFModel/document_rm',
175
- payload: {
176
- doc_id: documentIds,
177
- kb_id: knowledgeId,
178
- },
179
- });
180
- } catch (errorInfo) {
181
- console.log('Failed:', errorInfo);
 
 
 
 
 
 
 
 
 
 
 
 
182
  }
 
183
  },
184
- [dispatch, knowledgeId],
185
- );
186
 
187
- return removeDocument;
188
  };
189
 
190
- export const useUploadDocument = () => {
191
- const dispatch = useDispatch();
192
  const { knowledgeId } = useGetKnowledgeSearchParams();
193
 
194
- const uploadDocument = useCallback(
195
- (fileList: UploadFile[]) => {
 
 
 
 
 
 
 
 
 
 
 
196
  try {
197
- return dispatch<any>({
198
- type: 'kFModel/upload_document',
199
- payload: {
200
- fileList,
201
- kb_id: knowledgeId,
202
- },
203
- });
204
- } catch (errorInfo) {
205
- console.log('Failed:', errorInfo);
 
 
 
 
206
  }
207
  },
208
- [dispatch, knowledgeId],
209
- );
210
 
211
- return uploadDocument;
212
  };
213
 
214
- export const useWebCrawl = () => {
215
- const dispatch = useDispatch();
216
  const { knowledgeId } = useGetKnowledgeSearchParams();
217
- return useCallback(
218
- (name: string, url: string) => {
219
- try {
220
- return dispatch<any>({
221
- type: 'kFModel/web_crawl',
222
- payload: {
223
- name,
224
- url,
225
- kb_id: knowledgeId,
226
- },
227
- });
228
- } catch (errorInfo) {
229
- console.log('Failed:', errorInfo);
 
 
 
 
230
  }
 
 
231
  },
232
- [dispatch],
233
- );
 
 
 
 
 
234
  };
235
 
236
- export const useRunDocument = () => {
237
- const dispatch = useDispatch();
238
 
239
- const runDocumentByIds = useCallback(
240
- (payload: any) => {
241
- try {
242
- return dispatch<any>({
243
- type: 'kFModel/document_run',
244
- payload,
245
- });
246
- } catch (errorInfo) {
247
- console.log('Failed:', errorInfo);
 
 
 
 
 
 
 
 
 
 
 
 
248
  }
249
- },
250
- [dispatch],
251
- );
252
 
253
- return runDocumentByIds;
254
- };
 
255
 
256
- export const useSelectRunDocumentLoading = () => {
257
- const loading = useOneNamespaceEffectsLoading('kFModel', ['document_run']);
258
- return loading;
259
  };
260
 
261
  export const useFetchDocumentInfosByIds = () => {
@@ -296,19 +368,20 @@ export const useFetchDocumentThumbnailsByIds = () => {
296
  };
297
 
298
  export const useRemoveNextDocument = () => {
299
- // const queryClient = useQueryClient();
300
  const {
301
  data,
302
  isPending: loading,
303
  mutateAsync,
304
  } = useMutation({
305
  mutationKey: ['removeDocument'],
306
- mutationFn: async (documentId: string) => {
307
- const data = await kbService.document_rm({ doc_id: documentId });
308
- // if (data.retcode === 0) {
309
- // queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] });
310
- // }
311
- return data;
 
312
  },
313
  });
314
 
 
1
  import { IDocumentInfo } from '@/interfaces/database/document';
2
+ import { IChunk } from '@/interfaces/database/knowledge';
3
  import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
4
+ import i18n from '@/locales/config';
5
  import chatService from '@/services/chat-service';
6
  import kbService from '@/services/knowledge-service';
7
  import { api_host } from '@/utils/api';
8
  import { buildChunkHighlights } from '@/utils/document-util';
9
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
10
+ import { UploadFile, message } from 'antd';
11
+ import { get } from 'lodash';
12
  import { useCallback, useMemo, useState } from 'react';
13
  import { IHighlight } from 'react-pdf-highlighter';
14
+ import {
15
+ useGetPaginationWithRouter,
16
+ useHandleSearchChange,
17
+ } from './logic-hooks';
18
+ import {
19
+ useGetKnowledgeSearchParams,
20
+ useSetPaginationParams,
21
+ } from './route-hook';
22
 
23
  export const useGetDocumentUrl = (documentId?: string) => {
24
  const getDocumentUrl = useCallback(
 
50
  return { highlights, setWidthAndHeight };
51
  };
52
 
53
+ export const useFetchNextDocumentList = () => {
54
  const { knowledgeId } = useGetKnowledgeSearchParams();
55
+ const { searchString, handleInputChange } = useHandleSearchChange();
56
+ const { pagination, setPagination } = useGetPaginationWithRouter();
57
+
58
+ const { data, isFetching: loading } = useQuery<{
59
+ docs: IDocumentInfo[];
60
+ total: number;
61
+ }>({
62
+ queryKey: ['fetchDocumentList', searchString, pagination],
63
+ initialData: { docs: [], total: 0 },
64
+ refetchInterval: 15000,
65
+ queryFn: async () => {
66
+ const ret = await kbService.get_document_list({
67
  kb_id: knowledgeId,
68
+ keywords: searchString,
69
+ page_size: pagination.pageSize,
70
+ page: pagination.current,
71
+ });
72
+ if (ret.data.retcode === 0) {
73
+ return ret.data.data;
74
+ }
75
 
76
+ return {
77
+ docs: [],
78
+ total: 0,
79
+ };
80
+ },
81
+ });
82
 
83
+ const onInputChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(
84
+ (e) => {
85
+ setPagination({ page: 1 });
86
+ handleInputChange(e);
 
 
 
 
 
 
87
  },
88
+ [handleInputChange, setPagination],
89
  );
90
 
91
+ return {
92
+ loading,
93
+ searchString,
94
+ documents: data.docs,
95
+ pagination: { ...pagination, total: data?.total },
96
+ handleInputChange: onInputChange,
97
+ setPagination,
98
+ };
99
  };
100
 
101
+ export const useSetNextDocumentStatus = () => {
102
+ const queryClient = useQueryClient();
 
103
 
104
+ const {
105
+ data,
106
+ isPending: loading,
107
+ mutateAsync,
108
+ } = useMutation({
109
+ mutationKey: ['updateDocumentStatus'],
110
+ mutationFn: async ({
111
+ status,
112
+ documentId,
113
+ }: {
114
+ status: boolean;
115
+ documentId: string;
116
+ }) => {
117
+ const { data } = await kbService.document_change_status({
118
+ doc_id: documentId,
119
+ status: Number(status),
120
  });
121
+ if (data.retcode === 0) {
122
+ message.success(i18n.t('message.modified'));
123
+ queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
124
+ }
125
+ return data;
126
  },
127
+ });
 
128
 
129
+ return { setDocumentStatus: mutateAsync, data, loading };
130
  };
131
 
132
+ export const useSaveNextDocumentName = () => {
133
+ const queryClient = useQueryClient();
 
134
 
135
+ const {
136
+ data,
137
+ isPending: loading,
138
+ mutateAsync,
139
+ } = useMutation({
140
+ mutationKey: ['saveDocumentName'],
141
+ mutationFn: async ({
142
+ name,
143
+ documentId,
144
+ }: {
145
+ name: string;
146
+ documentId: string;
147
+ }) => {
148
+ const { data } = await kbService.document_rename({
149
+ doc_id: documentId,
150
+ name: name,
151
+ });
152
+ if (data.retcode === 0) {
153
+ message.success(i18n.t('message.renamed'));
154
+ queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
155
  }
156
+ return data.retcode;
157
  },
158
+ });
 
159
 
160
+ return { loading, saveName: mutateAsync, data };
161
  };
162
 
163
+ export const useCreateNextDocument = () => {
 
164
  const { knowledgeId } = useGetKnowledgeSearchParams();
165
+ const { setPaginationParams, page } = useSetPaginationParams();
166
+ const queryClient = useQueryClient();
167
 
168
+ const {
169
+ data,
170
+ isPending: loading,
171
+ mutateAsync,
172
+ } = useMutation({
173
+ mutationKey: ['createDocument'],
174
+ mutationFn: async (name: string) => {
175
+ const { data } = await kbService.document_create({
176
+ name,
177
+ kb_id: knowledgeId,
178
+ });
179
+ if (data.retcode === 0) {
180
+ if (page === 1) {
181
+ queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
182
+ } else {
183
+ setPaginationParams(); // fetch document list
184
+ }
185
+
186
+ message.success(i18n.t('message.created'));
187
  }
188
+ return data.retcode;
189
  },
190
+ });
 
191
 
192
+ return { createDocument: mutateAsync, loading, data };
193
  };
194
 
195
+ export const useSetNextDocumentParser = () => {
196
+ const queryClient = useQueryClient();
 
197
 
198
+ const {
199
+ data,
200
+ isPending: loading,
201
+ mutateAsync,
202
+ } = useMutation({
203
+ mutationKey: ['setDocumentParser'],
204
+ mutationFn: async ({
205
+ parserId,
206
+ documentId,
207
+ parserConfig,
208
+ }: {
209
+ parserId: string;
210
+ documentId: string;
211
+ parserConfig: IChangeParserConfigRequestBody;
212
+ }) => {
213
+ const { data } = await kbService.document_change_parser({
214
+ parser_id: parserId,
215
+ doc_id: documentId,
216
+ parser_config: parserConfig,
217
+ });
218
+ if (data.retcode === 0) {
219
+ queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
220
+
221
+ message.success(i18n.t('message.modified'));
222
  }
223
+ return data.retcode;
224
  },
225
+ });
 
226
 
227
+ return { setDocumentParser: mutateAsync, data, loading };
228
  };
229
 
230
+ export const useUploadNextDocument = () => {
231
+ const queryClient = useQueryClient();
232
  const { knowledgeId } = useGetKnowledgeSearchParams();
233
 
234
+ const {
235
+ data,
236
+ isPending: loading,
237
+ mutateAsync,
238
+ } = useMutation({
239
+ mutationKey: ['uploadDocument'],
240
+ mutationFn: async (fileList: UploadFile[]) => {
241
+ const formData = new FormData();
242
+ formData.append('kb_id', knowledgeId);
243
+ fileList.forEach((file: any) => {
244
+ formData.append('file', file);
245
+ });
246
+
247
  try {
248
+ const ret = await kbService.document_upload(formData);
249
+ const retcode = get(ret, 'data.retcode');
250
+ if (retcode === 0) {
251
+ message.success(i18n.t('message.uploaded'));
252
+ }
253
+
254
+ if (retcode === 0 || retcode === 500) {
255
+ queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
256
+ }
257
+ return ret?.data;
258
+ } catch (error) {
259
+ console.warn(error);
260
+ return {};
261
  }
262
  },
263
+ });
 
264
 
265
+ return { uploadDocument: mutateAsync, loading, data };
266
  };
267
 
268
+ export const useNextWebCrawl = () => {
 
269
  const { knowledgeId } = useGetKnowledgeSearchParams();
270
+
271
+ const {
272
+ data,
273
+ isPending: loading,
274
+ mutateAsync,
275
+ } = useMutation({
276
+ mutationKey: ['webCrawl'],
277
+ mutationFn: async ({ name, url }: { name: string; url: string }) => {
278
+ const formData = new FormData();
279
+ formData.append('name', name);
280
+ formData.append('url', url);
281
+ formData.append('kb_id', knowledgeId);
282
+
283
+ const ret = await kbService.web_crawl(formData);
284
+ const retcode = get(ret, 'data.retcode');
285
+ if (retcode === 0) {
286
+ message.success(i18n.t('message.uploaded'));
287
  }
288
+
289
+ return retcode;
290
  },
291
+ });
292
+
293
+ return {
294
+ data,
295
+ loading,
296
+ webCrawl: mutateAsync,
297
+ };
298
  };
299
 
300
+ export const useRunNextDocument = () => {
301
+ const queryClient = useQueryClient();
302
 
303
+ const {
304
+ data,
305
+ isPending: loading,
306
+ mutateAsync,
307
+ } = useMutation({
308
+ mutationKey: ['runDocumentByIds'],
309
+ mutationFn: async ({
310
+ documentIds,
311
+ run,
312
+ }: {
313
+ documentIds: string[];
314
+ run: number;
315
+ }) => {
316
+ const ret = await kbService.document_run({
317
+ doc_ids: documentIds,
318
+ run,
319
+ });
320
+ const retcode = get(ret, 'data.retcode');
321
+ if (retcode === 0) {
322
+ queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
323
+ message.success(i18n.t('message.operated'));
324
  }
 
 
 
325
 
326
+ return retcode;
327
+ },
328
+ });
329
 
330
+ return { runDocumentByIds: mutateAsync, loading, data };
 
 
331
  };
332
 
333
  export const useFetchDocumentInfosByIds = () => {
 
368
  };
369
 
370
  export const useRemoveNextDocument = () => {
371
+ const queryClient = useQueryClient();
372
  const {
373
  data,
374
  isPending: loading,
375
  mutateAsync,
376
  } = useMutation({
377
  mutationKey: ['removeDocument'],
378
+ mutationFn: async (documentIds: string | string[]) => {
379
+ const { data } = await kbService.document_rm({ doc_id: documentIds });
380
+ if (data.retcode === 0) {
381
+ message.success(i18n.t('message.deleted'));
382
+ queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
383
+ }
384
+ return data.retcode;
385
  },
386
  });
387
 
web/src/hooks/file-manager-hooks.ts CHANGED
@@ -61,8 +61,7 @@ export const useFetchFileList = (): ResponseType<any> & IListResult => {
61
  ],
62
  initialData: {},
63
  gcTime: 0,
64
- queryFn: async (params: any) => {
65
- console.info(params);
66
  const { data } = await fileManagerService.listFile({
67
  parent_id: id,
68
  keywords: searchString,
 
61
  ],
62
  initialData: {},
63
  gcTime: 0,
64
+ queryFn: async () => {
 
65
  const { data } = await fileManagerService.listFile({
66
  parent_id: id,
67
  keywords: searchString,
web/src/hooks/knowledge-hooks.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { useShowDeleteConfirm } from '@/hooks/common-hooks';
2
  import { ResponsePostType } from '@/interfaces/database/base';
3
  import { IKnowledge, ITestingResult } from '@/interfaces/database/knowledge';
4
  import i18n from '@/locales/config';
@@ -11,8 +10,7 @@ import {
11
  useQueryClient,
12
  } from '@tanstack/react-query';
13
  import { message } from 'antd';
14
- import { useCallback, useEffect } from 'react';
15
- import { useDispatch, useSearchParams, useSelector } from 'umi';
16
  import { useSetPaginationParams } from './route-hook';
17
 
18
  export const useKnowledgeBaseId = (): string => {
@@ -22,32 +20,6 @@ export const useKnowledgeBaseId = (): string => {
22
  return knowledgeBaseId || '';
23
  };
24
 
25
- export const useDeleteDocumentById = (): {
26
- removeDocument: (documentId: string) => Promise<number>;
27
- } => {
28
- const dispatch = useDispatch();
29
- const knowledgeBaseId = useKnowledgeBaseId();
30
- const showDeleteConfirm = useShowDeleteConfirm();
31
-
32
- const removeDocument = (documentId: string) => () => {
33
- return dispatch({
34
- type: 'kFModel/document_rm',
35
- payload: {
36
- doc_id: documentId,
37
- kb_id: knowledgeBaseId,
38
- },
39
- });
40
- };
41
-
42
- const onRmDocument = (documentId: string): Promise<number> => {
43
- return showDeleteConfirm({ onOk: removeDocument(documentId) });
44
- };
45
-
46
- return {
47
- removeDocument: onRmDocument,
48
- };
49
- };
50
-
51
  export const useFetchKnowledgeBaseConfiguration = () => {
52
  const knowledgeBaseId = useKnowledgeBaseId();
53
 
@@ -132,37 +104,6 @@ export const useDeleteKnowledge = () => {
132
  return { data, loading, deleteKnowledge: mutateAsync };
133
  };
134
 
135
- export const useSelectFileThumbnails = () => {
136
- const fileThumbnails: Record<string, string> = useSelector(
137
- (state: any) => state.kFModel.fileThumbnails,
138
- );
139
-
140
- return fileThumbnails;
141
- };
142
-
143
- export const useFetchFileThumbnails = (docIds?: Array<string>) => {
144
- const dispatch = useDispatch();
145
- const fileThumbnails = useSelectFileThumbnails();
146
-
147
- const fetchFileThumbnails = useCallback(
148
- (docIds: Array<string>) => {
149
- dispatch({
150
- type: 'kFModel/fetch_document_thumbnails',
151
- payload: { doc_ids: docIds.join(',') },
152
- });
153
- },
154
- [dispatch],
155
- );
156
-
157
- useEffect(() => {
158
- if (docIds) {
159
- fetchFileThumbnails(docIds);
160
- }
161
- }, [docIds, fetchFileThumbnails]);
162
-
163
- return { fileThumbnails, fetchFileThumbnails };
164
- };
165
-
166
  //#region knowledge configuration
167
 
168
  export const useUpdateKnowledge = () => {
 
 
1
  import { ResponsePostType } from '@/interfaces/database/base';
2
  import { IKnowledge, ITestingResult } from '@/interfaces/database/knowledge';
3
  import i18n from '@/locales/config';
 
10
  useQueryClient,
11
  } from '@tanstack/react-query';
12
  import { message } from 'antd';
13
+ import { useSearchParams } from 'umi';
 
14
  import { useSetPaginationParams } from './route-hook';
15
 
16
  export const useKnowledgeBaseId = (): string => {
 
20
  return knowledgeBaseId || '';
21
  };
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  export const useFetchKnowledgeBaseConfiguration = () => {
24
  const knowledgeBaseId = useKnowledgeBaseId();
25
 
 
104
  return { data, loading, deleteKnowledge: mutateAsync };
105
  };
106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  //#region knowledge configuration
108
 
109
  export const useUpdateKnowledge = () => {
web/src/hooks/logic-hooks.ts CHANGED
@@ -1,11 +1,9 @@
1
  import { Authorization } from '@/constants/authorization';
2
  import { MessageType } from '@/constants/chat';
3
  import { LanguageTranslationMap } from '@/constants/common';
4
- import { Pagination } from '@/interfaces/common';
5
  import { ResponseType } from '@/interfaces/database/base';
6
  import { IAnswer, Message } from '@/interfaces/database/chat';
7
  import { IKnowledgeFile } from '@/interfaces/database/knowledge';
8
- import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
9
  import { IClientConversation, IMessage } from '@/pages/chat/interface';
10
  import api from '@/utils/api';
11
  import { getAuthorization } from '@/utils/authorization-util';
@@ -23,45 +21,11 @@ import {
23
  useState,
24
  } from 'react';
25
  import { useTranslation } from 'react-i18next';
26
- import { useDispatch } from 'umi';
27
  import { v4 as uuid } from 'uuid';
28
- import { useSetModalState, useTranslate } from './common-hooks';
29
- import { useSetDocumentParser } from './document-hooks';
30
  import { useSetPaginationParams } from './route-hook';
31
- import { useOneNamespaceEffectsLoading } from './store-hooks';
32
  import { useFetchTenantInfo, useSaveSetting } from './user-setting-hooks';
33
 
34
- export const useChangeDocumentParser = (documentId: string) => {
35
- const setDocumentParser = useSetDocumentParser();
36
-
37
- const {
38
- visible: changeParserVisible,
39
- hideModal: hideChangeParserModal,
40
- showModal: showChangeParserModal,
41
- } = useSetModalState();
42
- const loading = useOneNamespaceEffectsLoading('kFModel', [
43
- 'document_change_parser',
44
- ]);
45
-
46
- const onChangeParserOk = useCallback(
47
- async (parserId: string, parserConfig: IChangeParserConfigRequestBody) => {
48
- const ret = await setDocumentParser(parserId, documentId, parserConfig);
49
- if (ret === 0) {
50
- hideChangeParserModal();
51
- }
52
- },
53
- [hideChangeParserModal, setDocumentParser, documentId],
54
- );
55
-
56
- return {
57
- changeParserLoading: loading,
58
- onChangeParserOk,
59
- changeParserVisible,
60
- hideChangeParserModal,
61
- showChangeParserModal,
62
- };
63
- };
64
-
65
  export const useSetSelectedRecord = <T = IKnowledgeFile>() => {
66
  const [currentRecord, setCurrentRecord] = useState<T>({} as T);
67
 
@@ -170,28 +134,6 @@ export const useGetPagination = () => {
170
  };
171
  };
172
 
173
- export const useSetPagination = (namespace: string) => {
174
- const dispatch = useDispatch();
175
-
176
- const setPagination = useCallback(
177
- (pageNumber = 1, pageSize?: number) => {
178
- const pagination: Pagination = {
179
- current: pageNumber,
180
- } as Pagination;
181
- if (pageSize) {
182
- pagination.pageSize = pageSize;
183
- }
184
- dispatch({
185
- type: `${namespace}/setPagination`,
186
- payload: pagination,
187
- });
188
- },
189
- [dispatch, namespace],
190
- );
191
-
192
- return setPagination;
193
- };
194
-
195
  export interface AppConf {
196
  appName: string;
197
  }
 
1
  import { Authorization } from '@/constants/authorization';
2
  import { MessageType } from '@/constants/chat';
3
  import { LanguageTranslationMap } from '@/constants/common';
 
4
  import { ResponseType } from '@/interfaces/database/base';
5
  import { IAnswer, Message } from '@/interfaces/database/chat';
6
  import { IKnowledgeFile } from '@/interfaces/database/knowledge';
 
7
  import { IClientConversation, IMessage } from '@/pages/chat/interface';
8
  import api from '@/utils/api';
9
  import { getAuthorization } from '@/utils/authorization-util';
 
21
  useState,
22
  } from 'react';
23
  import { useTranslation } from 'react-i18next';
 
24
  import { v4 as uuid } from 'uuid';
25
+ import { useTranslate } from './common-hooks';
 
26
  import { useSetPaginationParams } from './route-hook';
 
27
  import { useFetchTenantInfo, useSaveSetting } from './user-setting-hooks';
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  export const useSetSelectedRecord = <T = IKnowledgeFile>() => {
30
  const [currentRecord, setCurrentRecord] = useState<T>({} as T);
31
 
 
134
  };
135
  };
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  export interface AppConf {
138
  appName: string;
139
  }
web/src/hooks/store-hooks.ts DELETED
@@ -1,11 +0,0 @@
1
- import { getOneNamespaceEffectsLoading } from '@/utils/store-util';
2
- import { useSelector } from 'umi';
3
-
4
- // Get the loading status of given effects under a certain namespace
5
- export const useOneNamespaceEffectsLoading = (
6
- namespace: string,
7
- effectNames: Array<string>,
8
- ) => {
9
- const effects = useSelector((state: any) => state.loading.effects);
10
- return getOneNamespaceEffectsLoading(namespace, effects, effectNames);
11
- };
 
 
 
 
 
 
 
 
 
 
 
 
web/src/interfaces/database/document.ts CHANGED
@@ -1,3 +1,5 @@
 
 
1
  export interface IDocumentInfo {
2
  chunk_num: number;
3
  create_date: string;
@@ -7,13 +9,13 @@ export interface IDocumentInfo {
7
  kb_id: string;
8
  location: string;
9
  name: string;
10
- parser_config: Parserconfig;
11
  parser_id: string;
12
  process_begin_at: null;
13
  process_duation: number;
14
  progress: number;
15
  progress_msg: string;
16
- run: string;
17
  size: number;
18
  source_type: string;
19
  status: string;
@@ -24,9 +26,11 @@ export interface IDocumentInfo {
24
  update_time: number;
25
  }
26
 
27
- interface Parserconfig {
28
- chunk_token_num: number;
 
29
  layout_recognize: boolean;
 
30
  raptor: Raptor;
31
  }
32
 
 
1
+ import { RunningStatus } from '@/constants/knowledge';
2
+
3
  export interface IDocumentInfo {
4
  chunk_num: number;
5
  create_date: string;
 
9
  kb_id: string;
10
  location: string;
11
  name: string;
12
+ parser_config: IParserConfig;
13
  parser_id: string;
14
  process_begin_at: null;
15
  process_duation: number;
16
  progress: number;
17
  progress_msg: string;
18
+ run: RunningStatus;
19
  size: number;
20
  source_type: string;
21
  status: string;
 
26
  update_time: number;
27
  }
28
 
29
+ export interface IParserConfig {
30
+ delimiter: string;
31
+ html4excel: boolean;
32
  layout_recognize: boolean;
33
+ pages: any[];
34
  raptor: Raptor;
35
  }
36
 
web/src/pages/add-knowledge/components/knowledge-file/document-toolbar.tsx CHANGED
@@ -5,11 +5,10 @@ import { ReactComponent as EnableIcon } from '@/assets/svg/enable.svg';
5
  import { ReactComponent as RunIcon } from '@/assets/svg/run.svg';
6
  import { useShowDeleteConfirm, useTranslate } from '@/hooks/common-hooks';
7
  import {
8
- useRemoveDocument,
9
- useRunDocument,
10
- useSetDocumentStatus,
11
  } from '@/hooks/document-hooks';
12
- import { useGetKnowledgeSearchParams } from '@/hooks/route-hook';
13
  import {
14
  DownOutlined,
15
  FileOutlined,
@@ -19,11 +18,7 @@ import {
19
  } from '@ant-design/icons';
20
  import { Button, Dropdown, Flex, Input, MenuProps, Space } from 'antd';
21
  import { useCallback, useMemo } from 'react';
22
- import {
23
- useFetchDocumentListOnMount,
24
- useGetPagination,
25
- useHandleSearchChange,
26
- } from './hooks';
27
  import styles from './index.less';
28
 
29
  interface IProps {
@@ -31,23 +26,22 @@ interface IProps {
31
  showCreateModal(): void;
32
  showWebCrawlModal(): void;
33
  showDocumentUploadModal(): void;
 
 
34
  }
35
 
36
  const DocumentToolbar = ({
 
37
  selectedRowKeys,
38
  showCreateModal,
39
- showWebCrawlModal,
40
  showDocumentUploadModal,
 
41
  }: IProps) => {
42
  const { t } = useTranslate('knowledgeDetails');
43
- const { fetchDocumentList } = useFetchDocumentListOnMount();
44
- const { setPagination, searchString } = useGetPagination(fetchDocumentList);
45
- const { handleInputChange } = useHandleSearchChange(setPagination);
46
- const removeDocument = useRemoveDocument();
47
  const showDeleteConfirm = useShowDeleteConfirm();
48
- const runDocumentByIds = useRunDocument();
49
- const { knowledgeId } = useGetKnowledgeSearchParams();
50
- const changeStatus = useSetDocumentStatus();
51
 
52
  const actionItems: MenuProps['items'] = useMemo(() => {
53
  return [
@@ -66,19 +60,6 @@ const DocumentToolbar = ({
66
  ),
67
  },
68
  { type: 'divider' },
69
- // {
70
- // key: '2',
71
- // onClick: showWebCrawlModal,
72
- // label: (
73
- // <div>
74
- // <Button type="link">
75
- // <FileTextOutlined />
76
- // {t('webCrawl')}
77
- // </Button>
78
- // </div>
79
- // ),
80
- // },
81
- { type: 'divider' },
82
  {
83
  key: '3',
84
  onClick: showCreateModal,
@@ -105,12 +86,11 @@ const DocumentToolbar = ({
105
  const runDocument = useCallback(
106
  (run: number) => {
107
  runDocumentByIds({
108
- doc_ids: selectedRowKeys,
109
  run,
110
- knowledgeBaseId: knowledgeId,
111
  });
112
  },
113
- [runDocumentByIds, selectedRowKeys, knowledgeId],
114
  );
115
 
116
  const handleRunClick = useCallback(() => {
@@ -124,10 +104,10 @@ const DocumentToolbar = ({
124
  const onChangeStatus = useCallback(
125
  (enabled: boolean) => {
126
  selectedRowKeys.forEach((id) => {
127
- changeStatus(enabled, id);
128
  });
129
  },
130
- [selectedRowKeys, changeStatus],
131
  );
132
 
133
  const handleEnableClick = useCallback(() => {
 
5
  import { ReactComponent as RunIcon } from '@/assets/svg/run.svg';
6
  import { useShowDeleteConfirm, useTranslate } from '@/hooks/common-hooks';
7
  import {
8
+ useRemoveNextDocument,
9
+ useRunNextDocument,
10
+ useSetNextDocumentStatus,
11
  } from '@/hooks/document-hooks';
 
12
  import {
13
  DownOutlined,
14
  FileOutlined,
 
18
  } from '@ant-design/icons';
19
  import { Button, Dropdown, Flex, Input, MenuProps, Space } from 'antd';
20
  import { useCallback, useMemo } from 'react';
21
+
 
 
 
 
22
  import styles from './index.less';
23
 
24
  interface IProps {
 
26
  showCreateModal(): void;
27
  showWebCrawlModal(): void;
28
  showDocumentUploadModal(): void;
29
+ searchString: string;
30
+ handleInputChange: React.ChangeEventHandler<HTMLInputElement>;
31
  }
32
 
33
  const DocumentToolbar = ({
34
+ searchString,
35
  selectedRowKeys,
36
  showCreateModal,
 
37
  showDocumentUploadModal,
38
+ handleInputChange,
39
  }: IProps) => {
40
  const { t } = useTranslate('knowledgeDetails');
41
+ const { removeDocument } = useRemoveNextDocument();
 
 
 
42
  const showDeleteConfirm = useShowDeleteConfirm();
43
+ const { runDocumentByIds } = useRunNextDocument();
44
+ const { setDocumentStatus } = useSetNextDocumentStatus();
 
45
 
46
  const actionItems: MenuProps['items'] = useMemo(() => {
47
  return [
 
60
  ),
61
  },
62
  { type: 'divider' },
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  {
64
  key: '3',
65
  onClick: showCreateModal,
 
86
  const runDocument = useCallback(
87
  (run: number) => {
88
  runDocumentByIds({
89
+ documentIds: selectedRowKeys,
90
  run,
 
91
  });
92
  },
93
+ [runDocumentByIds, selectedRowKeys],
94
  );
95
 
96
  const handleRunClick = useCallback(() => {
 
104
  const onChangeStatus = useCallback(
105
  (enabled: boolean) => {
106
  selectedRowKeys.forEach((id) => {
107
+ setDocumentStatus({ status: enabled, documentId: id });
108
  });
109
  },
110
+ [selectedRowKeys, setDocumentStatus],
111
  );
112
 
113
  const handleEnableClick = useCallback(() => {
web/src/pages/add-knowledge/components/knowledge-file/hooks.ts CHANGED
@@ -1,104 +1,20 @@
1
- import { useSetModalState, useTranslate } from '@/hooks/common-hooks';
2
  import {
3
- useCreateDocument,
4
- useFetchDocumentList,
5
- useRunDocument,
6
- useSaveDocumentName,
7
- useSelectRunDocumentLoading,
8
- useSetDocumentParser,
9
- useUploadDocument,
10
- useWebCrawl,
11
  } from '@/hooks/document-hooks';
12
  import { useGetKnowledgeSearchParams } from '@/hooks/route-hook';
13
- import { useOneNamespaceEffectsLoading } from '@/hooks/store-hooks';
14
- import { Pagination } from '@/interfaces/common';
15
  import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
16
  import { getUnSupportedFilesCount } from '@/utils/document-util';
17
- import { PaginationProps, UploadFile } from 'antd';
18
- import { useCallback, useEffect, useMemo, useState } from 'react';
19
- import { useDispatch, useNavigate, useSelector } from 'umi';
20
  import { KnowledgeRouteKey } from './constant';
21
 
22
- export const useFetchDocumentListOnMount = () => {
23
- const { knowledgeId } = useGetKnowledgeSearchParams();
24
- const fetchDocumentList = useFetchDocumentList();
25
- const dispatch = useDispatch();
26
-
27
- useEffect(() => {
28
- if (knowledgeId) {
29
- fetchDocumentList();
30
- dispatch({
31
- type: 'kFModel/pollGetDocumentList-start',
32
- payload: knowledgeId,
33
- });
34
- }
35
- return () => {
36
- dispatch({
37
- type: 'kFModel/pollGetDocumentList-stop',
38
- });
39
- };
40
- }, [knowledgeId, dispatch, fetchDocumentList]);
41
-
42
- return { fetchDocumentList };
43
- };
44
-
45
- export const useGetPagination = (fetchDocumentList: () => void) => {
46
- const dispatch = useDispatch();
47
- const kFModel = useSelector((state: any) => state.kFModel);
48
- const { t } = useTranslate('common');
49
-
50
- const setPagination = useCallback(
51
- (pageNumber = 1, pageSize?: number) => {
52
- const pagination: Pagination = {
53
- current: pageNumber,
54
- } as Pagination;
55
- if (pageSize) {
56
- pagination.pageSize = pageSize;
57
- }
58
- dispatch({
59
- type: 'kFModel/setPagination',
60
- payload: pagination,
61
- });
62
- },
63
- [dispatch],
64
- );
65
-
66
- const onPageChange: PaginationProps['onChange'] = useCallback(
67
- (pageNumber: number, pageSize: number) => {
68
- setPagination(pageNumber, pageSize);
69
- fetchDocumentList();
70
- },
71
- [fetchDocumentList, setPagination],
72
- );
73
-
74
- const pagination: PaginationProps = useMemo(() => {
75
- return {
76
- showQuickJumper: true,
77
- total: kFModel.total,
78
- showSizeChanger: true,
79
- current: kFModel.pagination.current,
80
- pageSize: kFModel.pagination.pageSize,
81
- pageSizeOptions: [1, 2, 10, 20, 50, 100],
82
- onChange: onPageChange,
83
- showTotal: (total) => `${t('total')} ${total}`,
84
- };
85
- }, [kFModel, onPageChange, t]);
86
-
87
- return {
88
- pagination,
89
- setPagination,
90
- total: kFModel.total,
91
- searchString: kFModel.searchString,
92
- };
93
- };
94
-
95
- export const useSelectDocumentListLoading = () => {
96
- return useOneNamespaceEffectsLoading('kFModel', [
97
- 'getKfList',
98
- 'updateDocumentStatus',
99
- ]);
100
- };
101
-
102
  export const useNavigateToOtherPage = () => {
103
  const navigate = useNavigate();
104
  const { knowledgeId } = useGetKnowledgeSearchParams();
@@ -119,43 +35,18 @@ export const useNavigateToOtherPage = () => {
119
  return { linkToUploadPage, toChunk };
120
  };
121
 
122
- export const useHandleSearchChange = (setPagination: () => void) => {
123
- const dispatch = useDispatch();
124
- const { knowledgeId } = useGetKnowledgeSearchParams();
125
-
126
- const throttledGetDocumentList = useCallback(() => {
127
- dispatch({
128
- type: 'kFModel/throttledGetDocumentList',
129
- payload: knowledgeId,
130
- });
131
- }, [dispatch, knowledgeId]);
132
-
133
- const handleInputChange = useCallback(
134
- (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
135
- const value = e.target.value;
136
- dispatch({ type: 'kFModel/setSearchString', payload: value });
137
- setPagination();
138
- throttledGetDocumentList();
139
- },
140
- [setPagination, throttledGetDocumentList, dispatch],
141
- );
142
-
143
- return { handleInputChange };
144
- };
145
-
146
  export const useRenameDocument = (documentId: string) => {
147
- const saveName = useSaveDocumentName();
148
 
149
  const {
150
  visible: renameVisible,
151
  hideModal: hideRenameModal,
152
  showModal: showRenameModal,
153
  } = useSetModalState();
154
- const loading = useOneNamespaceEffectsLoading('kFModel', ['document_rename']);
155
 
156
  const onRenameOk = useCallback(
157
  async (name: string) => {
158
- const ret = await saveName(documentId, name);
159
  if (ret === 0) {
160
  hideRenameModal();
161
  }
@@ -173,14 +64,13 @@ export const useRenameDocument = (documentId: string) => {
173
  };
174
 
175
  export const useCreateEmptyDocument = () => {
176
- const createDocument = useCreateDocument();
177
 
178
  const {
179
  visible: createVisible,
180
  hideModal: hideCreateModal,
181
  showModal: showCreateModal,
182
  } = useSetModalState();
183
- const loading = useOneNamespaceEffectsLoading('kFModel', ['document_create']);
184
 
185
  const onCreateOk = useCallback(
186
  async (name: string) => {
@@ -202,20 +92,21 @@ export const useCreateEmptyDocument = () => {
202
  };
203
 
204
  export const useChangeDocumentParser = (documentId: string) => {
205
- const setDocumentParser = useSetDocumentParser();
206
 
207
  const {
208
  visible: changeParserVisible,
209
  hideModal: hideChangeParserModal,
210
  showModal: showChangeParserModal,
211
  } = useSetModalState();
212
- const loading = useOneNamespaceEffectsLoading('kFModel', [
213
- 'document_change_parser',
214
- ]);
215
 
216
  const onChangeParserOk = useCallback(
217
  async (parserId: string, parserConfig: IChangeParserConfigRequestBody) => {
218
- const ret = await setDocumentParser(parserId, documentId, parserConfig);
 
 
 
 
219
  if (ret === 0) {
220
  hideChangeParserModal();
221
  }
@@ -251,18 +142,21 @@ export const useHandleUploadDocument = () => {
251
  hideModal: hideDocumentUploadModal,
252
  showModal: showDocumentUploadModal,
253
  } = useSetModalState();
254
- const uploadDocument = useUploadDocument();
255
 
256
  const onDocumentUploadOk = useCallback(
257
  async (fileList: UploadFile[]): Promise<number | undefined> => {
258
  if (fileList.length > 0) {
259
  const ret: any = await uploadDocument(fileList);
260
- const count = getUnSupportedFilesCount(ret.retmsg);
 
 
 
261
  /// 500 error code indicates that some file types are not supported
262
- let retcode = ret.retcode;
263
  if (
264
- ret.retcode === 0 ||
265
- (ret.retcode === 500 && count !== fileList.length) // Some files were not uploaded successfully, but some were uploaded successfully.
266
  ) {
267
  retcode = 0;
268
  hideDocumentUploadModal();
@@ -273,8 +167,6 @@ export const useHandleUploadDocument = () => {
273
  [uploadDocument, hideDocumentUploadModal],
274
  );
275
 
276
- const loading = useOneNamespaceEffectsLoading('kFModel', ['upload_document']);
277
-
278
  return {
279
  documentUploadLoading: loading,
280
  onDocumentUploadOk,
@@ -290,11 +182,11 @@ export const useHandleWebCrawl = () => {
290
  hideModal: hideWebCrawlUploadModal,
291
  showModal: showWebCrawlUploadModal,
292
  } = useSetModalState();
293
- const webCrawl = useWebCrawl();
294
 
295
  const onWebCrawlUploadOk = useCallback(
296
  async (name: string, url: string) => {
297
- const ret = await webCrawl(name, url);
298
  if (ret === 0) {
299
  hideWebCrawlUploadModal();
300
  return 0;
@@ -304,8 +196,6 @@ export const useHandleWebCrawl = () => {
304
  [webCrawl, hideWebCrawlUploadModal],
305
  );
306
 
307
- const loading = useOneNamespaceEffectsLoading('kFModel', ['web_crawl']);
308
-
309
  return {
310
  webCrawlUploadLoading: loading,
311
  onWebCrawlUploadOk,
@@ -316,14 +206,12 @@ export const useHandleWebCrawl = () => {
316
  };
317
 
318
  export const useHandleRunDocumentByIds = (id: string) => {
319
- const loading = useSelectRunDocumentLoading();
320
- const runDocumentByIds = useRunDocument();
321
  const [currentId, setCurrentId] = useState<string>('');
322
  const isLoading = loading && currentId !== '' && currentId === id;
323
 
324
  const handleRunDocumentByIds = async (
325
  documentId: string,
326
- knowledgeBaseId: string,
327
  isRunning: boolean,
328
  ) => {
329
  if (isLoading) {
@@ -332,9 +220,8 @@ export const useHandleRunDocumentByIds = (id: string) => {
332
  setCurrentId(documentId);
333
  try {
334
  await runDocumentByIds({
335
- doc_ids: [documentId],
336
  run: isRunning ? 2 : 1,
337
- knowledgeBaseId,
338
  });
339
  setCurrentId('');
340
  } catch (error) {
 
1
+ import { useSetModalState } from '@/hooks/common-hooks';
2
  import {
3
+ useCreateNextDocument,
4
+ useNextWebCrawl,
5
+ useRunNextDocument,
6
+ useSaveNextDocumentName,
7
+ useSetNextDocumentParser,
8
+ useUploadNextDocument,
 
 
9
  } from '@/hooks/document-hooks';
10
  import { useGetKnowledgeSearchParams } from '@/hooks/route-hook';
 
 
11
  import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
12
  import { getUnSupportedFilesCount } from '@/utils/document-util';
13
+ import { UploadFile } from 'antd';
14
+ import { useCallback, useState } from 'react';
15
+ import { useNavigate } from 'umi';
16
  import { KnowledgeRouteKey } from './constant';
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  export const useNavigateToOtherPage = () => {
19
  const navigate = useNavigate();
20
  const { knowledgeId } = useGetKnowledgeSearchParams();
 
35
  return { linkToUploadPage, toChunk };
36
  };
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  export const useRenameDocument = (documentId: string) => {
39
+ const { saveName, loading } = useSaveNextDocumentName();
40
 
41
  const {
42
  visible: renameVisible,
43
  hideModal: hideRenameModal,
44
  showModal: showRenameModal,
45
  } = useSetModalState();
 
46
 
47
  const onRenameOk = useCallback(
48
  async (name: string) => {
49
+ const ret = await saveName({ documentId, name });
50
  if (ret === 0) {
51
  hideRenameModal();
52
  }
 
64
  };
65
 
66
  export const useCreateEmptyDocument = () => {
67
+ const { createDocument, loading } = useCreateNextDocument();
68
 
69
  const {
70
  visible: createVisible,
71
  hideModal: hideCreateModal,
72
  showModal: showCreateModal,
73
  } = useSetModalState();
 
74
 
75
  const onCreateOk = useCallback(
76
  async (name: string) => {
 
92
  };
93
 
94
  export const useChangeDocumentParser = (documentId: string) => {
95
+ const { setDocumentParser, loading } = useSetNextDocumentParser();
96
 
97
  const {
98
  visible: changeParserVisible,
99
  hideModal: hideChangeParserModal,
100
  showModal: showChangeParserModal,
101
  } = useSetModalState();
 
 
 
102
 
103
  const onChangeParserOk = useCallback(
104
  async (parserId: string, parserConfig: IChangeParserConfigRequestBody) => {
105
+ const ret = await setDocumentParser({
106
+ parserId,
107
+ documentId,
108
+ parserConfig,
109
+ });
110
  if (ret === 0) {
111
  hideChangeParserModal();
112
  }
 
142
  hideModal: hideDocumentUploadModal,
143
  showModal: showDocumentUploadModal,
144
  } = useSetModalState();
145
+ const { uploadDocument, loading } = useUploadNextDocument();
146
 
147
  const onDocumentUploadOk = useCallback(
148
  async (fileList: UploadFile[]): Promise<number | undefined> => {
149
  if (fileList.length > 0) {
150
  const ret: any = await uploadDocument(fileList);
151
+ if (typeof ret?.retmsg !== 'string') {
152
+ return;
153
+ }
154
+ const count = getUnSupportedFilesCount(ret?.retmsg);
155
  /// 500 error code indicates that some file types are not supported
156
+ let retcode = ret?.retcode;
157
  if (
158
+ ret?.retcode === 0 ||
159
+ (ret?.retcode === 500 && count !== fileList.length) // Some files were not uploaded successfully, but some were uploaded successfully.
160
  ) {
161
  retcode = 0;
162
  hideDocumentUploadModal();
 
167
  [uploadDocument, hideDocumentUploadModal],
168
  );
169
 
 
 
170
  return {
171
  documentUploadLoading: loading,
172
  onDocumentUploadOk,
 
182
  hideModal: hideWebCrawlUploadModal,
183
  showModal: showWebCrawlUploadModal,
184
  } = useSetModalState();
185
+ const { webCrawl, loading } = useNextWebCrawl();
186
 
187
  const onWebCrawlUploadOk = useCallback(
188
  async (name: string, url: string) => {
189
+ const ret = await webCrawl({ name, url });
190
  if (ret === 0) {
191
  hideWebCrawlUploadModal();
192
  return 0;
 
196
  [webCrawl, hideWebCrawlUploadModal],
197
  );
198
 
 
 
199
  return {
200
  webCrawlUploadLoading: loading,
201
  onWebCrawlUploadOk,
 
206
  };
207
 
208
  export const useHandleRunDocumentByIds = (id: string) => {
209
+ const { runDocumentByIds, loading } = useRunNextDocument();
 
210
  const [currentId, setCurrentId] = useState<string>('');
211
  const isLoading = loading && currentId !== '' && currentId === id;
212
 
213
  const handleRunDocumentByIds = async (
214
  documentId: string,
 
215
  isRunning: boolean,
216
  ) => {
217
  if (isLoading) {
 
220
  setCurrentId(documentId);
221
  try {
222
  await runDocumentByIds({
223
+ documentIds: [documentId],
224
  run: isRunning ? 2 : 1,
 
225
  });
226
  setCurrentId('');
227
  } catch (error) {
web/src/pages/add-knowledge/components/knowledge-file/index.tsx CHANGED
@@ -1,12 +1,11 @@
1
  import ChunkMethodModal from '@/components/chunk-method-modal';
2
  import SvgIcon from '@/components/svg-icon';
3
  import {
4
- useSelectDocumentList,
5
- useSetDocumentStatus,
6
  } from '@/hooks/document-hooks';
7
  import { useSetSelectedRecord } from '@/hooks/logic-hooks';
8
  import { useSelectParserList } from '@/hooks/user-setting-hooks';
9
- import { IKnowledgeFile } from '@/interfaces/database/knowledge';
10
  import { getExtension } from '@/utils/document-util';
11
  import { Divider, Flex, Switch, Table, Typography } from 'antd';
12
  import type { ColumnsType } from 'antd/es/table';
@@ -16,8 +15,6 @@ import DocumentToolbar from './document-toolbar';
16
  import {
17
  useChangeDocumentParser,
18
  useCreateEmptyDocument,
19
- useFetchDocumentListOnMount,
20
- useGetPagination,
21
  useGetRowSelection,
22
  useHandleUploadDocument,
23
  useHandleWebCrawl,
@@ -30,19 +27,19 @@ import RenameModal from './rename-modal';
30
  import WebCrawlModal from './web-crawl-modal';
31
 
32
  import FileUploadModal from '@/components/file-upload-modal';
 
33
  import { formatDate } from '@/utils/date';
34
  import styles from './index.less';
35
 
36
  const { Text } = Typography;
37
 
38
  const KnowledgeFile = () => {
39
- const data = useSelectDocumentList();
40
- const { fetchDocumentList } = useFetchDocumentListOnMount();
41
  const parserList = useSelectParserList();
42
- const { pagination } = useGetPagination(fetchDocumentList);
43
- const onChangeStatus = useSetDocumentStatus();
44
  const { toChunk } = useNavigateToOtherPage();
45
- const { currentRecord, setRecord } = useSetSelectedRecord();
46
  const {
47
  renameLoading,
48
  onRenameOk,
@@ -84,7 +81,7 @@ const KnowledgeFile = () => {
84
 
85
  const rowSelection = useGetRowSelection();
86
 
87
- const columns: ColumnsType<IKnowledgeFile> = [
88
  {
89
  title: t('name'),
90
  dataIndex: 'name',
@@ -138,7 +135,7 @@ const KnowledgeFile = () => {
138
  <Switch
139
  checked={status === '1'}
140
  onChange={(e) => {
141
- onChangeStatus(e, id);
142
  }}
143
  />
144
  </>
@@ -181,12 +178,13 @@ const KnowledgeFile = () => {
181
  showCreateModal={showCreateModal}
182
  showWebCrawlModal={showWebCrawlUploadModal}
183
  showDocumentUploadModal={showDocumentUploadModal}
 
 
184
  ></DocumentToolbar>
185
  <Table
186
  rowKey="id"
187
  columns={finalColumns}
188
- dataSource={data}
189
- // loading={loading}
190
  pagination={pagination}
191
  rowSelection={rowSelection}
192
  className={styles.documentTable}
 
1
  import ChunkMethodModal from '@/components/chunk-method-modal';
2
  import SvgIcon from '@/components/svg-icon';
3
  import {
4
+ useFetchNextDocumentList,
5
+ useSetNextDocumentStatus,
6
  } from '@/hooks/document-hooks';
7
  import { useSetSelectedRecord } from '@/hooks/logic-hooks';
8
  import { useSelectParserList } from '@/hooks/user-setting-hooks';
 
9
  import { getExtension } from '@/utils/document-util';
10
  import { Divider, Flex, Switch, Table, Typography } from 'antd';
11
  import type { ColumnsType } from 'antd/es/table';
 
15
  import {
16
  useChangeDocumentParser,
17
  useCreateEmptyDocument,
 
 
18
  useGetRowSelection,
19
  useHandleUploadDocument,
20
  useHandleWebCrawl,
 
27
  import WebCrawlModal from './web-crawl-modal';
28
 
29
  import FileUploadModal from '@/components/file-upload-modal';
30
+ import { IDocumentInfo } from '@/interfaces/database/document';
31
  import { formatDate } from '@/utils/date';
32
  import styles from './index.less';
33
 
34
  const { Text } = Typography;
35
 
36
  const KnowledgeFile = () => {
37
+ const { searchString, documents, pagination, handleInputChange } =
38
+ useFetchNextDocumentList();
39
  const parserList = useSelectParserList();
40
+ const { setDocumentStatus } = useSetNextDocumentStatus();
 
41
  const { toChunk } = useNavigateToOtherPage();
42
+ const { currentRecord, setRecord } = useSetSelectedRecord<IDocumentInfo>();
43
  const {
44
  renameLoading,
45
  onRenameOk,
 
81
 
82
  const rowSelection = useGetRowSelection();
83
 
84
+ const columns: ColumnsType<IDocumentInfo> = [
85
  {
86
  title: t('name'),
87
  dataIndex: 'name',
 
135
  <Switch
136
  checked={status === '1'}
137
  onChange={(e) => {
138
+ setDocumentStatus({ status: e, documentId: id });
139
  }}
140
  />
141
  </>
 
178
  showCreateModal={showCreateModal}
179
  showWebCrawlModal={showWebCrawlUploadModal}
180
  showDocumentUploadModal={showDocumentUploadModal}
181
+ searchString={searchString}
182
+ handleInputChange={handleInputChange}
183
  ></DocumentToolbar>
184
  <Table
185
  rowKey="id"
186
  columns={finalColumns}
187
+ dataSource={documents}
 
188
  pagination={pagination}
189
  rowSelection={rowSelection}
190
  className={styles.documentTable}
web/src/pages/add-knowledge/components/knowledge-file/model.ts DELETED
@@ -1,276 +0,0 @@
1
- import { BaseState } from '@/interfaces/common';
2
- import { IKnowledgeFile } from '@/interfaces/database/knowledge';
3
- import i18n from '@/locales/config';
4
- import kbService, { getDocumentFile } from '@/services/knowledge-service';
5
- import { message } from 'antd';
6
- import omit from 'lodash/omit';
7
- import pick from 'lodash/pick';
8
- import { DvaModel } from 'umi';
9
-
10
- export interface KFModelState extends BaseState {
11
- tenantIfo: any;
12
- data: IKnowledgeFile[];
13
- total: number;
14
- currentRecord: Nullable<IKnowledgeFile>;
15
- fileThumbnails: Record<string, string>;
16
- }
17
-
18
- const model: DvaModel<KFModelState> = {
19
- namespace: 'kFModel',
20
- state: {
21
- tenantIfo: {},
22
- data: [],
23
- total: 0,
24
- currentRecord: null,
25
- searchString: '',
26
- pagination: {
27
- current: 1,
28
- pageSize: 10,
29
- },
30
- fileThumbnails: {} as Record<string, string>,
31
- },
32
- reducers: {
33
- updateState(state, { payload }) {
34
- return {
35
- ...state,
36
- ...payload,
37
- };
38
- },
39
-
40
- setCurrentRecord(state, { payload }) {
41
- return { ...state, currentRecord: payload };
42
- },
43
- setSearchString(state, { payload }) {
44
- return { ...state, searchString: payload };
45
- },
46
- setPagination(state, { payload }) {
47
- return { ...state, pagination: { ...state.pagination, ...payload } };
48
- },
49
- setFileThumbnails(state, { payload }) {
50
- return { ...state, fileThumbnails: payload };
51
- },
52
- },
53
- effects: {
54
- *createKf({ payload = {} }, { call }) {
55
- const { data } = yield call(kbService.createKb, payload);
56
- const { retcode } = data;
57
- if (retcode === 0) {
58
- message.success(i18n.t('message.created'));
59
- }
60
- },
61
- *updateKf({ payload = {} }, { call }) {
62
- const { data } = yield call(kbService.updateKb, payload);
63
- const { retcode } = data;
64
- if (retcode === 0) {
65
- message.success(i18n.t('message.modified'));
66
- }
67
- },
68
- *getKfDetail({ payload = {} }, { call }) {
69
- const { data } = yield call(kbService.get_kb_detail, payload);
70
- },
71
- *getKfList({ payload = {} }, { call, put, select }) {
72
- const state: KFModelState = yield select((state: any) => state.kFModel);
73
- const requestBody = {
74
- ...payload,
75
- page: state.pagination.current,
76
- page_size: state.pagination.pageSize,
77
- };
78
- if (state.searchString) {
79
- requestBody['keywords'] = state.searchString;
80
- }
81
- const { data } = yield call(kbService.get_document_list, requestBody);
82
- const { retcode, data: res } = data;
83
-
84
- if (retcode === 0) {
85
- yield put({
86
- type: 'updateState',
87
- payload: {
88
- data: res.docs,
89
- total: res.total,
90
- },
91
- });
92
- }
93
- },
94
- throttledGetDocumentList: [
95
- function* ({ payload }, { call, put }) {
96
- yield put({ type: 'getKfList', payload: { kb_id: payload } });
97
- },
98
- { type: 'throttle', ms: 1000 }, // TODO: Provide type support for this effect
99
- ],
100
- pollGetDocumentList: [
101
- function* ({ payload }, { call, put }) {
102
- yield put({ type: 'getKfList', payload: { kb_id: payload } });
103
- },
104
- { type: 'poll', delay: 15000 }, // TODO: Provide type support for this effect
105
- ],
106
- *updateDocumentStatus({ payload = {} }, { call, put }) {
107
- const { data } = yield call(
108
- kbService.document_change_status,
109
- pick(payload, ['doc_id', 'status']),
110
- );
111
- const { retcode } = data;
112
- if (retcode === 0) {
113
- message.success(i18n.t('message.modified'));
114
- yield put({
115
- type: 'getKfList',
116
- payload: { kb_id: payload.kb_id },
117
- });
118
- }
119
- },
120
- *document_rm({ payload = {} }, { call, put }) {
121
- const { data } = yield call(kbService.document_rm, {
122
- doc_id: payload.doc_id,
123
- });
124
- const { retcode } = data;
125
- if (retcode === 0) {
126
- message.success(i18n.t('message.deleted'));
127
- yield put({
128
- type: 'getKfList',
129
- payload: { kb_id: payload.kb_id },
130
- });
131
- }
132
- return retcode;
133
- },
134
- *document_rename({ payload = {} }, { call, put }) {
135
- const { data } = yield call(
136
- kbService.document_rename,
137
- omit(payload, ['kb_id']),
138
- );
139
- const { retcode } = data;
140
- if (retcode === 0) {
141
- message.success(i18n.t('message.renamed'));
142
-
143
- yield put({
144
- type: 'getKfList',
145
- payload: { kb_id: payload.kb_id },
146
- });
147
- }
148
-
149
- return retcode;
150
- },
151
- *document_create({ payload = {} }, { call, put }) {
152
- const { data } = yield call(kbService.document_create, payload);
153
- const { retcode } = data;
154
- if (retcode === 0) {
155
- yield put({
156
- type: 'getKfList',
157
- payload: { kb_id: payload.kb_id },
158
- });
159
-
160
- message.success(i18n.t('message.created'));
161
- }
162
- return retcode;
163
- },
164
- *document_run({ payload = {} }, { call, put }) {
165
- const { data } = yield call(
166
- kbService.document_run,
167
- omit(payload, ['knowledgeBaseId']),
168
- );
169
- const { retcode } = data;
170
- if (retcode === 0) {
171
- if (payload.knowledgeBaseId) {
172
- yield put({
173
- type: 'getKfList',
174
- payload: { kb_id: payload.knowledgeBaseId },
175
- });
176
- }
177
- message.success(i18n.t('message.operated'));
178
- }
179
- return retcode;
180
- },
181
- *document_change_parser({ payload = {} }, { call, put }) {
182
- const { data } = yield call(
183
- kbService.document_change_parser,
184
- omit(payload, ['kb_id']),
185
- );
186
- const { retcode } = data;
187
- if (retcode === 0) {
188
- yield put({
189
- type: 'getKfList',
190
- payload: { kb_id: payload.kb_id },
191
- });
192
-
193
- message.success(i18n.t('message.modified'));
194
- }
195
- return retcode;
196
- },
197
- *fetch_document_thumbnails({ payload = {} }, { call, put }) {
198
- const { data } = yield call(kbService.document_thumbnails, payload);
199
- if (data.retcode === 0) {
200
- yield put({ type: 'setFileThumbnails', payload: data.data });
201
- }
202
- },
203
- *fetch_document_file({ payload = {} }, { call }) {
204
- const documentId = payload;
205
- try {
206
- const ret = yield call(getDocumentFile, documentId);
207
- return ret;
208
- } catch (error) {
209
- console.warn(error);
210
- }
211
- },
212
- *upload_document({ payload = {} }, { call, put }) {
213
- const fileList = payload.fileList;
214
- const formData = new FormData();
215
- formData.append('kb_id', payload.kb_id);
216
- fileList.forEach((file: any) => {
217
- formData.append('file', file);
218
- });
219
-
220
- const ret = yield call(kbService.document_upload, formData);
221
-
222
- const succeed = ret?.data?.retcode === 0;
223
-
224
- if (succeed) {
225
- message.success(i18n.t('message.uploaded'));
226
- }
227
- if (succeed || ret?.data?.retcode === 500) {
228
- yield put({
229
- type: 'getKfList',
230
- payload: { kb_id: payload.kb_id },
231
- });
232
- }
233
- return ret?.data;
234
- },
235
- *web_crawl({ payload = {} }, { call, put }) {
236
- const formData = new FormData();
237
- formData.append('name', payload.name);
238
- formData.append('url', payload.url);
239
- formData.append('kb_id', payload.kb_id);
240
-
241
- const { data } = yield call(kbService.web_crawl, formData);
242
-
243
- const succeed = data.retcode === 0;
244
-
245
- if (succeed) {
246
- message.success(i18n.t('message.uploaded'));
247
- }
248
- if (succeed || data.retcode === 500) {
249
- yield put({
250
- type: 'getKfList',
251
- payload: { kb_id: payload.kb_id },
252
- });
253
- }
254
- return data.retcode;
255
- },
256
- },
257
- subscriptions: {
258
- setup({ dispatch, history }) {
259
- history.listen(({ location }) => {
260
- const state: { from: string } = (location.state ?? {
261
- from: '',
262
- }) as { from: string };
263
- if (
264
- state.from === '/knowledge' || // TODO: Just directly determine whether the current page is on the knowledge list page.
265
- location.pathname === '/knowledge/dataset/upload'
266
- ) {
267
- dispatch({
268
- type: 'setPagination',
269
- payload: { current: 1, pageSize: 10 },
270
- });
271
- }
272
- });
273
- },
274
- },
275
- };
276
- export default model;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
web/src/pages/add-knowledge/components/knowledge-file/parsing-action-cell/index.tsx CHANGED
@@ -1,6 +1,6 @@
1
  import { useShowDeleteConfirm, useTranslate } from '@/hooks/common-hooks';
2
- import { useRemoveDocument } from '@/hooks/document-hooks';
3
- import { IKnowledgeFile } from '@/interfaces/database/knowledge';
4
  import { api_host } from '@/utils/api';
5
  import { downloadFile } from '@/utils/file-util';
6
  import {
@@ -15,8 +15,8 @@ import { isParserRunning } from '../utils';
15
  import styles from './index.less';
16
 
17
  interface IProps {
18
- record: IKnowledgeFile;
19
- setCurrentRecord: (record: IKnowledgeFile) => void;
20
  showRenameModal: () => void;
21
  showChangeParserModal: () => void;
22
  }
@@ -30,7 +30,7 @@ const ParsingActionCell = ({
30
  const documentId = record.id;
31
  const isRunning = isParserRunning(record.run);
32
  const { t } = useTranslate('knowledgeDetails');
33
- const removeDocument = useRemoveDocument();
34
  const showDeleteConfirm = useShowDeleteConfirm();
35
 
36
  const onRmDocument = () => {
 
1
  import { useShowDeleteConfirm, useTranslate } from '@/hooks/common-hooks';
2
+ import { useRemoveNextDocument } from '@/hooks/document-hooks';
3
+ import { IDocumentInfo } from '@/interfaces/database/document';
4
  import { api_host } from '@/utils/api';
5
  import { downloadFile } from '@/utils/file-util';
6
  import {
 
15
  import styles from './index.less';
16
 
17
  interface IProps {
18
+ record: IDocumentInfo;
19
+ setCurrentRecord: (record: IDocumentInfo) => void;
20
  showRenameModal: () => void;
21
  showChangeParserModal: () => void;
22
  }
 
30
  const documentId = record.id;
31
  const isRunning = isParserRunning(record.run);
32
  const { t } = useTranslate('knowledgeDetails');
33
+ const { removeDocument } = useRemoveNextDocument();
34
  const showDeleteConfirm = useShowDeleteConfirm();
35
 
36
  const onRmDocument = () => {
web/src/pages/add-knowledge/components/knowledge-file/parsing-status-cell/index.tsx CHANGED
@@ -2,7 +2,7 @@ import { ReactComponent as CancelIcon } from '@/assets/svg/cancel.svg';
2
  import { ReactComponent as RefreshIcon } from '@/assets/svg/refresh.svg';
3
  import { ReactComponent as RunIcon } from '@/assets/svg/run.svg';
4
  import { useTranslate } from '@/hooks/common-hooks';
5
- import { IKnowledgeFile } from '@/interfaces/database/knowledge';
6
  import { Badge, DescriptionsProps, Flex, Popover, Space, Tag } from 'antd';
7
  import classNames from 'classnames';
8
  import { useTranslation } from 'react-i18next';
@@ -21,7 +21,7 @@ const iconMap = {
21
  };
22
 
23
  interface IProps {
24
- record: IKnowledgeFile;
25
  }
26
 
27
  const PopoverContent = ({ record }: IProps) => {
@@ -93,7 +93,7 @@ export const ParsingStatusCell = ({ record }: IProps) => {
93
  const label = t(`knowledgeDetails.runningStatus${text}`);
94
 
95
  const handleOperationIconClick = () => {
96
- handleRunDocumentByIds(record.id, record.kb_id, isRunning);
97
  };
98
 
99
  return (
 
2
  import { ReactComponent as RefreshIcon } from '@/assets/svg/refresh.svg';
3
  import { ReactComponent as RunIcon } from '@/assets/svg/run.svg';
4
  import { useTranslate } from '@/hooks/common-hooks';
5
+ import { IDocumentInfo } from '@/interfaces/database/document';
6
  import { Badge, DescriptionsProps, Flex, Popover, Space, Tag } from 'antd';
7
  import classNames from 'classnames';
8
  import { useTranslation } from 'react-i18next';
 
21
  };
22
 
23
  interface IProps {
24
+ record: IDocumentInfo;
25
  }
26
 
27
  const PopoverContent = ({ record }: IProps) => {
 
93
  const label = t(`knowledgeDetails.runningStatus${text}`);
94
 
95
  const handleOperationIconClick = () => {
96
+ handleRunDocumentByIds(record.id, isRunning);
97
  };
98
 
99
  return (
web/src/pages/add-knowledge/index.tsx CHANGED
@@ -6,19 +6,17 @@ import {
6
  } from '@/hooks/route-hook';
7
  import { Breadcrumb } from 'antd';
8
  import { ItemType } from 'antd/es/breadcrumb/Breadcrumb';
9
- import { useEffect, useMemo } from 'react';
10
  import { useTranslation } from 'react-i18next';
11
- import { Link, Outlet, useDispatch, useLocation } from 'umi';
12
  import Siderbar from './components/knowledge-sidebar';
13
  import { KnowledgeDatasetRouteKey, KnowledgeRouteKey } from './constant';
14
  import styles from './index.less';
15
 
16
  const KnowledgeAdding = () => {
17
- const dispatch = useDispatch();
18
  const knowledgeBaseId = useKnowledgeBaseId();
19
 
20
  const { t } = useTranslation();
21
- const location = useLocation();
22
  const activeKey: KnowledgeRouteKey =
23
  (useSecondPathName() as KnowledgeRouteKey) || KnowledgeRouteKey.Dataset;
24
 
@@ -58,23 +56,6 @@ const KnowledgeAdding = () => {
58
  return items;
59
  }, [activeKey, datasetActiveKey, gotoList, knowledgeBaseId, t]);
60
 
61
- useEffect(() => {
62
- const search: string = location.search.slice(1);
63
- const map = search.split('&').reduce<Record<string, string>>((obj, cur) => {
64
- const [key, value] = cur.split('=');
65
- obj[key] = value;
66
- return obj;
67
- }, {});
68
-
69
- dispatch({
70
- type: 'kAModel/updateState',
71
- payload: {
72
- doc_id: undefined,
73
- ...map,
74
- },
75
- });
76
- }, [location, dispatch]);
77
-
78
  return (
79
  <>
80
  <div className={styles.container}>
 
6
  } from '@/hooks/route-hook';
7
  import { Breadcrumb } from 'antd';
8
  import { ItemType } from 'antd/es/breadcrumb/Breadcrumb';
9
+ import { useMemo } from 'react';
10
  import { useTranslation } from 'react-i18next';
11
+ import { Link, Outlet } from 'umi';
12
  import Siderbar from './components/knowledge-sidebar';
13
  import { KnowledgeDatasetRouteKey, KnowledgeRouteKey } from './constant';
14
  import styles from './index.less';
15
 
16
  const KnowledgeAdding = () => {
 
17
  const knowledgeBaseId = useKnowledgeBaseId();
18
 
19
  const { t } = useTranslation();
 
20
  const activeKey: KnowledgeRouteKey =
21
  (useSecondPathName() as KnowledgeRouteKey) || KnowledgeRouteKey.Dataset;
22
 
 
56
  return items;
57
  }, [activeKey, datasetActiveKey, gotoList, knowledgeBaseId, t]);
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  return (
60
  <>
61
  <div className={styles.container}>
web/src/pages/chat/markdown-content/index.tsx CHANGED
@@ -1,19 +1,19 @@
1
  import Image from '@/components/image';
2
  import SvgIcon from '@/components/svg-icon';
3
- import { useSelectFileThumbnails } from '@/hooks/knowledge-hooks';
4
  import { IReference } from '@/interfaces/database/chat';
5
  import { IChunk } from '@/interfaces/database/knowledge';
6
  import { getExtension } from '@/utils/document-util';
7
  import { InfoCircleOutlined } from '@ant-design/icons';
8
  import { Button, Flex, Popover, Space } from 'antd';
9
  import DOMPurify from 'dompurify';
10
- import { useCallback, useMemo } from 'react';
11
  import Markdown from 'react-markdown';
12
  import reactStringReplace from 'react-string-replace';
13
  import SyntaxHighlighter from 'react-syntax-highlighter';
14
  import remarkGfm from 'remark-gfm';
15
  import { visitParents } from 'unist-util-visit-parents';
16
 
 
17
  import { useTranslation } from 'react-i18next';
18
  import styles from './index.less';
19
 
@@ -34,6 +34,8 @@ const MarkdownContent = ({
34
  clickDocumentButton?: (documentId: string, chunk: IChunk) => void;
35
  }) => {
36
  const { t } = useTranslation();
 
 
37
  const contentWithCursor = useMemo(() => {
38
  let text = content;
39
  if (text === '') {
@@ -42,7 +44,9 @@ const MarkdownContent = ({
42
  return loading ? text?.concat('~~2$$') : text;
43
  }, [content, loading, t]);
44
 
45
- const fileThumbnails = useSelectFileThumbnails();
 
 
46
 
47
  const handleDocumentButtonClick = useCallback(
48
  (documentId: string, chunk: IChunk, isPdf: boolean) => () => {
 
1
  import Image from '@/components/image';
2
  import SvgIcon from '@/components/svg-icon';
 
3
  import { IReference } from '@/interfaces/database/chat';
4
  import { IChunk } from '@/interfaces/database/knowledge';
5
  import { getExtension } from '@/utils/document-util';
6
  import { InfoCircleOutlined } from '@ant-design/icons';
7
  import { Button, Flex, Popover, Space } from 'antd';
8
  import DOMPurify from 'dompurify';
9
+ import { useCallback, useEffect, useMemo } from 'react';
10
  import Markdown from 'react-markdown';
11
  import reactStringReplace from 'react-string-replace';
12
  import SyntaxHighlighter from 'react-syntax-highlighter';
13
  import remarkGfm from 'remark-gfm';
14
  import { visitParents } from 'unist-util-visit-parents';
15
 
16
+ import { useFetchDocumentThumbnailsByIds } from '@/hooks/document-hooks';
17
  import { useTranslation } from 'react-i18next';
18
  import styles from './index.less';
19
 
 
34
  clickDocumentButton?: (documentId: string, chunk: IChunk) => void;
35
  }) => {
36
  const { t } = useTranslation();
37
+ const { setDocumentIds, data: fileThumbnails } =
38
+ useFetchDocumentThumbnailsByIds();
39
  const contentWithCursor = useMemo(() => {
40
  let text = content;
41
  if (text === '') {
 
44
  return loading ? text?.concat('~~2$$') : text;
45
  }, [content, loading, t]);
46
 
47
+ useEffect(() => {
48
+ setDocumentIds(reference?.doc_aggs.map((x) => x.doc_id) ?? []);
49
+ }, [reference, setDocumentIds]);
50
 
51
  const handleDocumentButtonClick = useCallback(
52
  (documentId: string, chunk: IChunk, isPdf: boolean) => () => {
web/src/pages/file-manager/file-toolbar.tsx CHANGED
@@ -1,5 +1,10 @@
1
  import { ReactComponent as DeleteIcon } from '@/assets/svg/delete.svg';
 
2
  import { useTranslate } from '@/hooks/common-hooks';
 
 
 
 
3
  import {
4
  DownOutlined,
5
  FileTextOutlined,
@@ -24,11 +29,6 @@ import {
24
  useSelectBreadcrumbItems,
25
  } from './hooks';
26
 
27
- import SvgIcon from '@/components/svg-icon';
28
- import {
29
- IListResult,
30
- useFetchParentFolderList,
31
- } from '@/hooks/file-manager-hooks';
32
  import styles from './index.less';
33
 
34
  interface IProps
 
1
  import { ReactComponent as DeleteIcon } from '@/assets/svg/delete.svg';
2
+ import SvgIcon from '@/components/svg-icon';
3
  import { useTranslate } from '@/hooks/common-hooks';
4
+ import {
5
+ IListResult,
6
+ useFetchParentFolderList,
7
+ } from '@/hooks/file-manager-hooks';
8
  import {
9
  DownOutlined,
10
  FileTextOutlined,
 
29
  useSelectBreadcrumbItems,
30
  } from './hooks';
31
 
 
 
 
 
 
32
  import styles from './index.less';
33
 
34
  interface IProps
web/typings.d.ts CHANGED
@@ -1,20 +1,5 @@
1
- import { KFModelState } from '@/pages/add-knowledge/components/knowledge-file/model';
2
-
3
  declare module 'lodash';
4
 
5
- function useSelector<TState = RootState, TSelected = unknown>(
6
- selector: (state: TState) => TSelected,
7
- equalityFn?: (left: TSelected, right: TSelected) => boolean,
8
- ): TSelected;
9
-
10
- export interface RootState {
11
- kFModel: KFModelState;
12
- }
13
-
14
  declare global {
15
  type Nullable<T> = T | null;
16
  }
17
-
18
- declare module 'umi' {
19
- export { useSelector };
20
- }
 
 
 
1
  declare module 'lodash';
2
 
 
 
 
 
 
 
 
 
 
3
  declare global {
4
  type Nullable<T> = T | null;
5
  }