From ff442c48b536e27c6e7c63ff2c8e258bd1c5bd14 Mon Sep 17 00:00:00 2001 From: balibabu Date: Thu, 24 Apr 2025 11:45:37 +0800 Subject: [PATCH] Feat: Display document parsing status #3221 (#7241) ### What problem does this PR solve? Feat: Display document parsing status #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/package-lock.json | 368 ++++++++++++++++++ web/package.json | 1 + web/src/components/confirm-delete-dialog.tsx | 5 +- web/src/components/ui/hover-card.tsx | 29 ++ web/src/hooks/use-document-request.ts | 144 ++++++- web/src/pages/dataset/dataset/constant.ts | 17 + .../pages/dataset/dataset/dataset-table.tsx | 4 +- web/src/pages/dataset/dataset/hooks.ts | 33 -- web/src/pages/dataset/dataset/index.tsx | 2 +- .../pages/dataset/dataset/parsing-card.tsx | 101 +++++ .../dataset/dataset/parsing-status-cell.tsx | 62 +++ .../dataset/use-dataset-table-columns.tsx | 36 +- .../pages/dataset/dataset/use-run-document.ts | 34 ++ web/src/pages/dataset/dataset/utils.ts | 6 + 14 files changed, 794 insertions(+), 48 deletions(-) create mode 100644 web/src/components/ui/hover-card.tsx create mode 100644 web/src/pages/dataset/dataset/constant.ts create mode 100644 web/src/pages/dataset/dataset/parsing-card.tsx create mode 100644 web/src/pages/dataset/dataset/parsing-status-cell.tsx create mode 100644 web/src/pages/dataset/dataset/use-run-document.ts create mode 100644 web/src/pages/dataset/dataset/utils.ts diff --git a/web/package-lock.json b/web/package-lock.json index 85e2f0582..89d0629f8 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -23,6 +23,7 @@ "@radix-ui/react-collapsible": "^1.1.3", "@radix-ui/react-dialog": "1.1.4", "@radix-ui/react-dropdown-menu": "2.1.4", + "@radix-ui/react-hover-card": "^1.1.11", "@radix-ui/react-icons": "^1.3.1", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-navigation-menu": "^1.2.1", @@ -5484,6 +5485,340 @@ } } }, + "node_modules/@radix-ui/react-hover-card": { + "version": "1.1.11", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-hover-card/-/react-hover-card-1.1.11.tgz", + "integrity": "sha512-q9h9grUpGZKR3MNhtVCLVnPGmx1YnzBgGR+O40mhSNGsUnkR+LChVH8c7FB0mkS+oudhd8KAkZGTJPJCjdAPIg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.7", + "@radix-ui/react-popper": "1.2.4", + "@radix-ui/react-portal": "1.1.6", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@floating-ui/core": { + "version": "1.6.9", + "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.9.tgz", + "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@floating-ui/dom": { + "version": "1.6.13", + "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.6.13.tgz", + "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/primitive": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/@radix-ui/primitive/-/primitive-1.1.2.tgz", + "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-arrow": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-arrow/-/react-arrow-1.1.4.tgz", + "integrity": "sha512-qz+fxrqgNxG0dYew5l7qR3c7wdgRu1XVUHGnGYX7rg5HM4p9SWaRmJwfgR3J0SgyUKayLmzQIun+N6rWRgiRKw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-popper": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-popper/-/react-popper-1.2.4.tgz", + "integrity": "sha512-3p2Rgm/a1cK0r/UVkx5F/K9v/EplfjAeIFCGOPYPO4lZ0jtg4iSQXt/YGTSLWaf4x7NG6Z4+uKFcylcTZjeqDA==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-portal": { + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-1.1.6.tgz", + "integrity": "sha512-XmsIl2z1n/TsYFLIdYam2rmFwf9OC/Sh2avkbmVMDuBZIe7hSpM0cYnWPAo7nHOVx8zTuwDZGByfcqLdnzp3Vw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-presence": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-primitive": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-primitive/-/react-primitive-2.1.0.tgz", + "integrity": "sha512-/J/FhLdK0zVcILOwt5g+dH4KnkonCtkVJsa2G6JmvbbtZfBEI1gMsO3QMjseL4F/SwfAMt1Vc/0XKYKq+xJ1sw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-slot": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", + "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-use-rect": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-use-size": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/rect": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@radix-ui/rect/-/rect-1.1.1.tgz", + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "license": "MIT" + }, "node_modules/@radix-ui/react-icons": { "version": "1.3.1", "resolved": "https://registry.npmmirror.com/@radix-ui/react-icons/-/react-icons-1.3.1.tgz", @@ -7319,6 +7654,39 @@ } } }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-escape-keydown": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", diff --git a/web/package.json b/web/package.json index 7bfc3459f..45803da70 100644 --- a/web/package.json +++ b/web/package.json @@ -34,6 +34,7 @@ "@radix-ui/react-collapsible": "^1.1.3", "@radix-ui/react-dialog": "1.1.4", "@radix-ui/react-dropdown-menu": "2.1.4", + "@radix-ui/react-hover-card": "^1.1.11", "@radix-ui/react-icons": "^1.3.1", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-navigation-menu": "^1.2.1", diff --git a/web/src/components/confirm-delete-dialog.tsx b/web/src/components/confirm-delete-dialog.tsx index 8a63fbf5d..979c7c377 100644 --- a/web/src/components/confirm-delete-dialog.tsx +++ b/web/src/components/confirm-delete-dialog.tsx @@ -23,6 +23,7 @@ export function ConfirmDeleteDialog({ children, title, onOk, + onCancel, hidden = false, }: IProps & PropsWithChildren) { const { t } = useTranslation(); @@ -48,7 +49,9 @@ export function ConfirmDeleteDialog({ */} - {t('common.cancel')} + + {t('common.cancel')} + , + React.ComponentPropsWithoutRef +>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => ( + +)); +HoverCardContent.displayName = HoverCardPrimitive.Content.displayName; + +export { HoverCard, HoverCardContent, HoverCardTrigger }; diff --git a/web/src/hooks/use-document-request.ts b/web/src/hooks/use-document-request.ts index cf7dbe9a1..c8d129ef6 100644 --- a/web/src/hooks/use-document-request.ts +++ b/web/src/hooks/use-document-request.ts @@ -1,11 +1,23 @@ +import { IDocumentInfo } from '@/interfaces/database/document'; +import i18n from '@/locales/config'; import kbService from '@/services/knowledge-service'; -import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { useDebounce } from 'ahooks'; +import { message } from 'antd'; import { get } from 'lodash'; +import { useCallback } from 'react'; import { useParams } from 'umi'; +import { + useGetPaginationWithRouter, + useHandleSearchChange, +} from './logic-hooks'; +import { useGetKnowledgeSearchParams } from './route-hook'; export const enum DocumentApiAction { UploadDocument = 'uploadDocument', FetchDocumentList = 'fetchDocumentList', + UpdateDocumentStatus = 'updateDocumentStatus', + RunDocumentByIds = 'runDocumentByIds', } export const useUploadNextDocument = () => { @@ -47,3 +59,133 @@ export const useUploadNextDocument = () => { return { uploadDocument: mutateAsync, loading, data }; }; + +export const useFetchDocumentList = () => { + const { knowledgeId } = useGetKnowledgeSearchParams(); + const { searchString, handleInputChange } = useHandleSearchChange(); + const { pagination, setPagination } = useGetPaginationWithRouter(); + const { id } = useParams(); + const debouncedSearchString = useDebounce(searchString, { wait: 500 }); + + const { data, isFetching: loading } = useQuery<{ + docs: IDocumentInfo[]; + total: number; + }>({ + queryKey: [ + DocumentApiAction.FetchDocumentList, + debouncedSearchString, + pagination, + ], + initialData: { docs: [], total: 0 }, + refetchInterval: 15000, + enabled: !!knowledgeId || !!id, + queryFn: async () => { + const ret = await kbService.get_document_list({ + kb_id: knowledgeId || id, + keywords: debouncedSearchString, + page_size: pagination.pageSize, + page: pagination.current, + }); + if (ret.data.code === 0) { + return ret.data.data; + } + + return { + docs: [], + total: 0, + }; + }, + }); + + const onInputChange: React.ChangeEventHandler = useCallback( + (e) => { + setPagination({ page: 1 }); + handleInputChange(e); + }, + [handleInputChange, setPagination], + ); + + return { + loading, + searchString, + documents: data.docs, + pagination: { ...pagination, total: data?.total }, + handleInputChange: onInputChange, + setPagination, + }; +}; + +export const useSetDocumentStatus = () => { + const queryClient = useQueryClient(); + + const { + data, + isPending: loading, + mutateAsync, + } = useMutation({ + mutationKey: [DocumentApiAction.UpdateDocumentStatus], + mutationFn: async ({ + status, + documentId, + }: { + status: boolean; + documentId: string; + }) => { + const { data } = await kbService.document_change_status({ + doc_id: documentId, + status: Number(status), + }); + if (data.code === 0) { + message.success(i18n.t('message.modified')); + queryClient.invalidateQueries({ + queryKey: [DocumentApiAction.FetchDocumentList], + }); + } + return data; + }, + }); + + return { setDocumentStatus: mutateAsync, data, loading }; +}; + +export const useRunDocument = () => { + const queryClient = useQueryClient(); + + const { + data, + isPending: loading, + mutateAsync, + } = useMutation({ + mutationKey: [DocumentApiAction.RunDocumentByIds], + mutationFn: async ({ + documentIds, + run, + shouldDelete, + }: { + documentIds: string[]; + run: number; + shouldDelete: boolean; + }) => { + queryClient.invalidateQueries({ + queryKey: [DocumentApiAction.FetchDocumentList], + }); + + const ret = await kbService.document_run({ + doc_ids: documentIds, + run, + delete: shouldDelete, + }); + const code = get(ret, 'data.code'); + if (code === 0) { + queryClient.invalidateQueries({ + queryKey: [DocumentApiAction.FetchDocumentList], + }); + message.success(i18n.t('message.operated')); + } + + return code; + }, + }); + + return { runDocumentByIds: mutateAsync, loading, data }; +}; diff --git a/web/src/pages/dataset/dataset/constant.ts b/web/src/pages/dataset/dataset/constant.ts new file mode 100644 index 000000000..52deb4577 --- /dev/null +++ b/web/src/pages/dataset/dataset/constant.ts @@ -0,0 +1,17 @@ +import { RunningStatus } from '@/constants/knowledge'; + +export const RunningStatusMap = { + [RunningStatus.UNSTART]: { + label: 'UNSTART', + color: 'cyan', + }, + [RunningStatus.RUNNING]: { + label: 'Parsing', + color: 'blue', + }, + [RunningStatus.CANCEL]: { label: 'CANCEL', color: 'orange' }, + [RunningStatus.DONE]: { label: 'SUCCESS', color: 'blue' }, + [RunningStatus.FAIL]: { label: 'FAIL', color: 'red' }, +}; + +export * from '@/constants/knowledge'; diff --git a/web/src/pages/dataset/dataset/dataset-table.tsx b/web/src/pages/dataset/dataset/dataset-table.tsx index 4cea3e098..67286a678 100644 --- a/web/src/pages/dataset/dataset/dataset-table.tsx +++ b/web/src/pages/dataset/dataset/dataset-table.tsx @@ -23,8 +23,8 @@ import { TableHeader, TableRow, } from '@/components/ui/table'; -import { useFetchNextDocumentList } from '@/hooks/document-hooks'; import { useSetSelectedRecord } from '@/hooks/logic-hooks'; +import { useFetchDocumentList } from '@/hooks/use-document-request'; import { IDocumentInfo } from '@/interfaces/database/document'; import { getExtension } from '@/utils/document-util'; import { useMemo } from 'react'; @@ -38,7 +38,7 @@ export function DatasetTable() { pagination, // handleInputChange, setPagination, - } = useFetchNextDocumentList(); + } = useFetchDocumentList(); const [sorting, setSorting] = React.useState([]); const [columnFilters, setColumnFilters] = React.useState( [], diff --git a/web/src/pages/dataset/dataset/hooks.ts b/web/src/pages/dataset/dataset/hooks.ts index 0f235aec9..e0643bee8 100644 --- a/web/src/pages/dataset/dataset/hooks.ts +++ b/web/src/pages/dataset/dataset/hooks.ts @@ -2,7 +2,6 @@ import { useSetModalState } from '@/hooks/common-hooks'; import { useCreateNextDocument, useNextWebCrawl, - useRunNextDocument, useSaveNextDocumentName, useSetNextDocumentParser, } from '@/hooks/document-hooks'; @@ -159,35 +158,3 @@ export const useHandleWebCrawl = () => { showWebCrawlUploadModal, }; }; - -export const useHandleRunDocumentByIds = (id: string) => { - const { runDocumentByIds, loading } = useRunNextDocument(); - const [currentId, setCurrentId] = useState(''); - const isLoading = loading && currentId !== '' && currentId === id; - - const handleRunDocumentByIds = async ( - documentId: string, - isRunning: boolean, - shouldDelete: boolean = false, - ) => { - if (isLoading) { - return; - } - setCurrentId(documentId); - try { - await runDocumentByIds({ - documentIds: [documentId], - run: isRunning ? 2 : 1, - shouldDelete, - }); - setCurrentId(''); - } catch (error) { - setCurrentId(''); - } - }; - - return { - handleRunDocumentByIds, - loading: isLoading, - }; -}; diff --git a/web/src/pages/dataset/dataset/index.tsx b/web/src/pages/dataset/dataset/index.tsx index aa31b97d7..f2c013cc4 100644 --- a/web/src/pages/dataset/dataset/index.tsx +++ b/web/src/pages/dataset/dataset/index.tsx @@ -19,7 +19,7 @@ export default function Dataset() { return (
- + + + + + + + ); +} diff --git a/web/src/pages/dataset/dataset/parsing-status-cell.tsx b/web/src/pages/dataset/dataset/parsing-status-cell.tsx new file mode 100644 index 000000000..a2dc23cd0 --- /dev/null +++ b/web/src/pages/dataset/dataset/parsing-status-cell.tsx @@ -0,0 +1,62 @@ +import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog'; +import { Button } from '@/components/ui/button'; +import { Progress } from '@/components/ui/progress'; +import { Separator } from '@/components/ui/separator'; +import { IDocumentInfo } from '@/interfaces/database/document'; +import { CircleX, Play, RefreshCw } from 'lucide-react'; +import { RunningStatus } from './constant'; +import { ParsingCard } from './parsing-card'; +import { useHandleRunDocumentByIds } from './use-run-document'; +import { isParserRunning } from './utils'; + +const IconMap = { + [RunningStatus.UNSTART]: , + [RunningStatus.RUNNING]: , + [RunningStatus.CANCEL]: , + [RunningStatus.DONE]: , + [RunningStatus.FAIL]: , +}; + +export function ParsingStatusCell({ record }: { record: IDocumentInfo }) { + const { run, parser_id, progress, chunk_num, id } = record; + const operationIcon = IconMap[run]; + const p = Number((progress * 100).toFixed(2)); + const { handleRunDocumentByIds } = useHandleRunDocumentByIds(id); + const isRunning = isParserRunning(run); + const isZeroChunk = chunk_num === 0; + + const handleOperationIconClick = + (shouldDelete: boolean = false) => + () => { + handleRunDocumentByIds(record.id, isRunning, shouldDelete); + }; + + return ( +
+
+ + +
+ + {isParserRunning(run) ? ( + + ) : ( + + )} +
+ ); +} diff --git a/web/src/pages/dataset/dataset/use-dataset-table-columns.tsx b/web/src/pages/dataset/dataset/use-dataset-table-columns.tsx index 30e4c1028..f90a4604e 100644 --- a/web/src/pages/dataset/dataset/use-dataset-table-columns.tsx +++ b/web/src/pages/dataset/dataset/use-dataset-table-columns.tsx @@ -16,6 +16,7 @@ import { TooltipTrigger, } from '@/components/ui/tooltip'; import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; +import { useSetDocumentStatus } from '@/hooks/use-document-request'; import { IDocumentInfo } from '@/interfaces/database/document'; import { cn } from '@/lib/utils'; import { formatDate } from '@/utils/date'; @@ -25,6 +26,7 @@ import { ArrowUpDown, MoreHorizontal, Pencil, Wrench } from 'lucide-react'; import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { useChangeDocumentParser } from './hooks'; +import { ParsingStatusCell } from './parsing-status-cell'; type UseDatasetTableColumnsType = Pick< ReturnType, @@ -57,6 +59,7 @@ export function useDatasetTableColumns({ // }, [setRecord, showSetMetaModal]); const { navigateToChunkParsedResult } = useNavigatePage(); + const { setDocumentStatus } = useSetDocumentStatus(); const columns: ColumnDef[] = [ { @@ -94,7 +97,7 @@ export function useDatasetTableColumns({ ); }, - meta: { cellClassName: 'max-w-[20vw]' }, + // meta: { cellClassName: 'max-w-[20vw]' }, cell: ({ row }) => { const name: string = row.getValue('name'); @@ -142,20 +145,34 @@ export function useDatasetTableColumns({ ), }, { - accessorKey: 'parser_id', - header: t('chunkMethod'), + accessorKey: 'status', + header: t('enabled'), + cell: ({ row }) => { + const id = row.original.id; + return ( + { + setDocumentStatus({ status: e, documentId: id }); + }} + /> + ); + }, + }, + { + accessorKey: 'chunk_num', + header: t('chunkNumber'), cell: ({ row }) => ( -
{row.getValue('parser_id')}
+
{row.getValue('chunk_num')}
), }, { accessorKey: 'run', header: t('parsingStatus'), - cell: ({ row }) => ( - - ), + // meta: { cellClassName: 'min-w-[20vw]' }, + cell: ({ row }) => { + return ; + }, }, { id: 'actions', @@ -166,7 +183,6 @@ export function useDatasetTableColumns({ return (
-