You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

hooks.ts 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. import { useSetModalState } from '@/hooks/common-hooks';
  2. import {
  3. useCreateNextDocument,
  4. useNextWebCrawl,
  5. useRunNextDocument,
  6. useSaveNextDocumentName,
  7. useSetDocumentMeta,
  8. useSetNextDocumentParser,
  9. useUploadNextDocument,
  10. } from '@/hooks/document-hooks';
  11. import { useGetKnowledgeSearchParams } from '@/hooks/route-hook';
  12. import { IDocumentInfo } from '@/interfaces/database/document';
  13. import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
  14. import { UploadFile } from 'antd';
  15. import { TableRowSelection } from 'antd/es/table/interface';
  16. import { useCallback, useState } from 'react';
  17. import { useNavigate } from 'umi';
  18. import { KnowledgeRouteKey } from './constant';
  19. export const useNavigateToOtherPage = () => {
  20. const navigate = useNavigate();
  21. const { knowledgeId } = useGetKnowledgeSearchParams();
  22. const linkToUploadPage = useCallback(() => {
  23. navigate(`/knowledge/dataset/upload?id=${knowledgeId}`);
  24. }, [navigate, knowledgeId]);
  25. const toChunk = useCallback(
  26. (id: string) => {
  27. navigate(
  28. `/knowledge/${KnowledgeRouteKey.Dataset}/chunk?id=${knowledgeId}&doc_id=${id}`,
  29. );
  30. },
  31. [navigate, knowledgeId],
  32. );
  33. return { linkToUploadPage, toChunk };
  34. };
  35. export const useRenameDocument = (documentId: string) => {
  36. const { saveName, loading } = useSaveNextDocumentName();
  37. const {
  38. visible: renameVisible,
  39. hideModal: hideRenameModal,
  40. showModal: showRenameModal,
  41. } = useSetModalState();
  42. const onRenameOk = useCallback(
  43. async (name: string) => {
  44. const ret = await saveName({ documentId, name });
  45. if (ret === 0) {
  46. hideRenameModal();
  47. }
  48. },
  49. [hideRenameModal, saveName, documentId],
  50. );
  51. return {
  52. renameLoading: loading,
  53. onRenameOk,
  54. renameVisible,
  55. hideRenameModal,
  56. showRenameModal,
  57. };
  58. };
  59. export const useCreateEmptyDocument = () => {
  60. const { createDocument, loading } = useCreateNextDocument();
  61. const {
  62. visible: createVisible,
  63. hideModal: hideCreateModal,
  64. showModal: showCreateModal,
  65. } = useSetModalState();
  66. const onCreateOk = useCallback(
  67. async (name: string) => {
  68. const ret = await createDocument(name);
  69. if (ret === 0) {
  70. hideCreateModal();
  71. }
  72. },
  73. [hideCreateModal, createDocument],
  74. );
  75. return {
  76. createLoading: loading,
  77. onCreateOk,
  78. createVisible,
  79. hideCreateModal,
  80. showCreateModal,
  81. };
  82. };
  83. export const useChangeDocumentParser = (documentId: string) => {
  84. const { setDocumentParser, loading } = useSetNextDocumentParser();
  85. const {
  86. visible: changeParserVisible,
  87. hideModal: hideChangeParserModal,
  88. showModal: showChangeParserModal,
  89. } = useSetModalState();
  90. const onChangeParserOk = useCallback(
  91. async (parserId: string, parserConfig: IChangeParserConfigRequestBody) => {
  92. const ret = await setDocumentParser({
  93. parserId,
  94. documentId,
  95. parserConfig,
  96. });
  97. if (ret === 0) {
  98. hideChangeParserModal();
  99. }
  100. },
  101. [hideChangeParserModal, setDocumentParser, documentId],
  102. );
  103. return {
  104. changeParserLoading: loading,
  105. onChangeParserOk,
  106. changeParserVisible,
  107. hideChangeParserModal,
  108. showChangeParserModal,
  109. };
  110. };
  111. export const useGetRowSelection = () => {
  112. const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  113. const rowSelection: TableRowSelection<IDocumentInfo> = {
  114. selectedRowKeys,
  115. onChange: (newSelectedRowKeys: React.Key[]) => {
  116. setSelectedRowKeys(newSelectedRowKeys);
  117. },
  118. };
  119. return rowSelection;
  120. };
  121. export const useHandleUploadDocument = () => {
  122. const {
  123. visible: documentUploadVisible,
  124. hideModal: hideDocumentUploadModal,
  125. showModal: showDocumentUploadModal,
  126. } = useSetModalState();
  127. const [fileList, setFileList] = useState<UploadFile[]>([]);
  128. const [uploadProgress, setUploadProgress] = useState<number>(0);
  129. const { uploadDocument, loading } = useUploadNextDocument();
  130. const { runDocumentByIds } = useRunNextDocument();
  131. const onDocumentUploadOk = useCallback(
  132. async ({
  133. parseOnCreation,
  134. directoryFileList,
  135. }: {
  136. directoryFileList: UploadFile[];
  137. parseOnCreation: boolean;
  138. }): Promise<number | undefined> => {
  139. const processFileGroup = async (filesPart: UploadFile[]) => {
  140. // set status to uploading on files
  141. setFileList(
  142. fileList.map((file) => {
  143. if (!filesPart.includes(file)) {
  144. return file;
  145. }
  146. let newFile = file;
  147. newFile.status = 'uploading';
  148. newFile.percent = 1;
  149. return newFile;
  150. }),
  151. );
  152. const ret = await uploadDocument(filesPart);
  153. const files = ret?.data || [];
  154. const successfulFilenames = files.map((file: any) => file.name);
  155. // set status to done or error on files (based on response)
  156. setFileList(
  157. fileList.map((file) => {
  158. if (!filesPart.includes(file)) {
  159. return file;
  160. }
  161. let newFile = file;
  162. newFile.status = successfulFilenames.includes(file.name)
  163. ? 'done'
  164. : 'error';
  165. newFile.percent = 100;
  166. newFile.response = ret.message;
  167. return newFile;
  168. }),
  169. );
  170. return {
  171. code: ret?.code,
  172. fileIds: files.map((file: any) => file.id),
  173. totalSuccess: successfulFilenames.length,
  174. };
  175. };
  176. const totalFiles = fileList.length;
  177. if (directoryFileList.length > 0) {
  178. const ret = await uploadDocument(directoryFileList);
  179. if (ret?.code === 0) {
  180. hideDocumentUploadModal();
  181. }
  182. if (totalFiles === 0) {
  183. return 0;
  184. }
  185. }
  186. if (totalFiles === 0) {
  187. console.log('No files to upload');
  188. hideDocumentUploadModal();
  189. return 0;
  190. }
  191. let totalSuccess = 0;
  192. let codes = [];
  193. let toRunFileIds: any[] = [];
  194. for (let i = 0; i < totalFiles; i += 10) {
  195. setUploadProgress(Math.floor((i / totalFiles) * 100));
  196. const files = fileList.slice(i, i + 10);
  197. const {
  198. code,
  199. totalSuccess: count,
  200. fileIds,
  201. } = await processFileGroup(files);
  202. codes.push(code);
  203. totalSuccess += count;
  204. toRunFileIds = toRunFileIds.concat(fileIds);
  205. }
  206. const allSuccess = codes.every((code) => code === 0);
  207. const any500 = codes.some((code) => code === 500);
  208. let code = 500;
  209. if (allSuccess || (any500 && totalSuccess === totalFiles)) {
  210. code = 0;
  211. hideDocumentUploadModal();
  212. }
  213. if (parseOnCreation) {
  214. await runDocumentByIds({
  215. documentIds: toRunFileIds,
  216. run: 1,
  217. shouldDelete: false,
  218. });
  219. }
  220. setUploadProgress(100);
  221. return code;
  222. },
  223. [fileList, uploadDocument, hideDocumentUploadModal, runDocumentByIds],
  224. );
  225. return {
  226. documentUploadLoading: loading,
  227. onDocumentUploadOk,
  228. documentUploadVisible,
  229. hideDocumentUploadModal,
  230. showDocumentUploadModal,
  231. uploadFileList: fileList,
  232. setUploadFileList: setFileList,
  233. uploadProgress,
  234. setUploadProgress,
  235. };
  236. };
  237. export const useHandleWebCrawl = () => {
  238. const {
  239. visible: webCrawlUploadVisible,
  240. hideModal: hideWebCrawlUploadModal,
  241. showModal: showWebCrawlUploadModal,
  242. } = useSetModalState();
  243. const { webCrawl, loading } = useNextWebCrawl();
  244. const onWebCrawlUploadOk = useCallback(
  245. async (name: string, url: string) => {
  246. const ret = await webCrawl({ name, url });
  247. if (ret === 0) {
  248. hideWebCrawlUploadModal();
  249. return 0;
  250. }
  251. return -1;
  252. },
  253. [webCrawl, hideWebCrawlUploadModal],
  254. );
  255. return {
  256. webCrawlUploadLoading: loading,
  257. onWebCrawlUploadOk,
  258. webCrawlUploadVisible,
  259. hideWebCrawlUploadModal,
  260. showWebCrawlUploadModal,
  261. };
  262. };
  263. export const useHandleRunDocumentByIds = (id: string) => {
  264. const { runDocumentByIds, loading } = useRunNextDocument();
  265. const [currentId, setCurrentId] = useState<string>('');
  266. const isLoading = loading && currentId !== '' && currentId === id;
  267. const handleRunDocumentByIds = async (
  268. documentId: string,
  269. isRunning: boolean,
  270. shouldDelete: boolean = false,
  271. ) => {
  272. if (isLoading) {
  273. return;
  274. }
  275. setCurrentId(documentId);
  276. try {
  277. await runDocumentByIds({
  278. documentIds: [documentId],
  279. run: isRunning ? 2 : 1,
  280. shouldDelete,
  281. });
  282. setCurrentId('');
  283. } catch (error) {
  284. setCurrentId('');
  285. }
  286. };
  287. return {
  288. handleRunDocumentByIds,
  289. loading: isLoading,
  290. };
  291. };
  292. export const useShowMetaModal = (documentId: string) => {
  293. const { setDocumentMeta, loading } = useSetDocumentMeta();
  294. const {
  295. visible: setMetaVisible,
  296. hideModal: hideSetMetaModal,
  297. showModal: showSetMetaModal,
  298. } = useSetModalState();
  299. const onSetMetaModalOk = useCallback(
  300. async (meta: string) => {
  301. const ret = await setDocumentMeta({
  302. documentId,
  303. meta,
  304. });
  305. if (ret === 0) {
  306. hideSetMetaModal();
  307. }
  308. },
  309. [setDocumentMeta, documentId, hideSetMetaModal],
  310. );
  311. return {
  312. setMetaLoading: loading,
  313. onSetMetaModalOk,
  314. setMetaVisible,
  315. hideSetMetaModal,
  316. showSetMetaModal,
  317. };
  318. };