balibabu
commited on
Commit
·
97d4387
1
Parent(s):
eb38196
feat: set chunk to available state and select all chunk (#57)
Browse files* feat: set chunk to available state
* feat: select all chunk
- web/.eslintrc.js +5 -0
- web/package-lock.json +99 -4
- web/package.json +2 -0
- web/src/app.tsx +2 -2
- web/src/interfaces/common.ts +1 -0
- web/src/interfaces/database/knowledge.ts +10 -0
- web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.less +8 -0
- web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.tsx +88 -0
- web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-toolbar/index.tsx +66 -29
- web/src/pages/add-knowledge/components/knowledge-chunk/index.less +46 -47
- web/src/pages/add-knowledge/components/knowledge-chunk/index.tsx +77 -149
- web/src/pages/add-knowledge/components/knowledge-chunk/model.ts +51 -15
- web/src/pages/add-knowledge/components/knowledge-file/model.ts +0 -1
- web/src/pages/knowledge/knowledge-card/index.tsx +10 -11
- web/src/utils/storeUtil.ts +5 -0
web/.eslintrc.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// .eslintrc.js
|
| 2 |
+
module.exports = {
|
| 3 |
+
// Umi 项目
|
| 4 |
+
extends: [require.resolve('umi/eslint'), 'plugin:react-hooks/recommended'],
|
| 5 |
+
};
|
web/package-lock.json
CHANGED
|
@@ -27,6 +27,7 @@
|
|
| 27 |
"@types/lodash": "^4.14.202",
|
| 28 |
"@types/react": "^18.0.33",
|
| 29 |
"@types/react-dom": "^18.0.11",
|
|
|
|
| 30 |
"@umijs/plugins": "^4.1.0",
|
| 31 |
"cross-env": "^7.0.3",
|
| 32 |
"prettier": "^3.2.4",
|
|
@@ -3479,16 +3480,17 @@
|
|
| 3479 |
}
|
| 3480 |
},
|
| 3481 |
"node_modules/@umijs/lint": {
|
| 3482 |
-
"version": "4.1.
|
| 3483 |
-
"resolved": "https://registry.npmmirror.com/@umijs/lint/-/lint-4.1.
|
| 3484 |
-
"integrity": "sha512-
|
|
|
|
| 3485 |
"dependencies": {
|
| 3486 |
"@babel/core": "7.23.6",
|
| 3487 |
"@babel/eslint-parser": "7.23.3",
|
| 3488 |
"@stylelint/postcss-css-in-js": "^0.38.0",
|
| 3489 |
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
| 3490 |
"@typescript-eslint/parser": "^5.62.0",
|
| 3491 |
-
"@umijs/babel-preset-umi": "4.1.
|
| 3492 |
"eslint-plugin-jest": "27.2.3",
|
| 3493 |
"eslint-plugin-react": "7.33.2",
|
| 3494 |
"eslint-plugin-react-hooks": "4.6.0",
|
|
@@ -3501,6 +3503,7 @@
|
|
| 3501 |
"version": "7.23.6",
|
| 3502 |
"resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.23.6.tgz",
|
| 3503 |
"integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==",
|
|
|
|
| 3504 |
"dependencies": {
|
| 3505 |
"@ampproject/remapping": "^2.2.0",
|
| 3506 |
"@babel/code-frame": "^7.23.5",
|
|
@@ -3522,6 +3525,54 @@
|
|
| 3522 |
"node": ">=6.9.0"
|
| 3523 |
}
|
| 3524 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3525 |
"node_modules/@umijs/mfsu": {
|
| 3526 |
"version": "4.1.0",
|
| 3527 |
"resolved": "https://registry.npmmirror.com/@umijs/mfsu/-/mfsu-4.1.0.tgz",
|
|
@@ -16319,6 +16370,31 @@
|
|
| 16319 |
"qs": "^6.9.1"
|
| 16320 |
}
|
| 16321 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16322 |
"node_modules/umi/node_modules/@babel/runtime": {
|
| 16323 |
"version": "7.23.6",
|
| 16324 |
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.6.tgz",
|
|
@@ -16330,6 +16406,25 @@
|
|
| 16330 |
"node": ">=6.9.0"
|
| 16331 |
}
|
| 16332 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16333 |
"node_modules/umi/node_modules/fast-glob": {
|
| 16334 |
"version": "3.3.2",
|
| 16335 |
"resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz",
|
|
|
|
| 27 |
"@types/lodash": "^4.14.202",
|
| 28 |
"@types/react": "^18.0.33",
|
| 29 |
"@types/react-dom": "^18.0.11",
|
| 30 |
+
"@umijs/lint": "^4.1.1",
|
| 31 |
"@umijs/plugins": "^4.1.0",
|
| 32 |
"cross-env": "^7.0.3",
|
| 33 |
"prettier": "^3.2.4",
|
|
|
|
| 3480 |
}
|
| 3481 |
},
|
| 3482 |
"node_modules/@umijs/lint": {
|
| 3483 |
+
"version": "4.1.1",
|
| 3484 |
+
"resolved": "https://registry.npmmirror.com/@umijs/lint/-/lint-4.1.1.tgz",
|
| 3485 |
+
"integrity": "sha512-fy2edKuYw42eM3LuH/2AiH0ZKdembFx3SR8dIGKxf7BmEQOSfUhskLiNGE8tSRubCiVzGUWvZQDw1YQcU0bsHg==",
|
| 3486 |
+
"dev": true,
|
| 3487 |
"dependencies": {
|
| 3488 |
"@babel/core": "7.23.6",
|
| 3489 |
"@babel/eslint-parser": "7.23.3",
|
| 3490 |
"@stylelint/postcss-css-in-js": "^0.38.0",
|
| 3491 |
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
| 3492 |
"@typescript-eslint/parser": "^5.62.0",
|
| 3493 |
+
"@umijs/babel-preset-umi": "4.1.1",
|
| 3494 |
"eslint-plugin-jest": "27.2.3",
|
| 3495 |
"eslint-plugin-react": "7.33.2",
|
| 3496 |
"eslint-plugin-react-hooks": "4.6.0",
|
|
|
|
| 3503 |
"version": "7.23.6",
|
| 3504 |
"resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.23.6.tgz",
|
| 3505 |
"integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==",
|
| 3506 |
+
"dev": true,
|
| 3507 |
"dependencies": {
|
| 3508 |
"@ampproject/remapping": "^2.2.0",
|
| 3509 |
"@babel/code-frame": "^7.23.5",
|
|
|
|
| 3525 |
"node": ">=6.9.0"
|
| 3526 |
}
|
| 3527 |
},
|
| 3528 |
+
"node_modules/@umijs/lint/node_modules/@babel/runtime": {
|
| 3529 |
+
"version": "7.23.6",
|
| 3530 |
+
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.6.tgz",
|
| 3531 |
+
"integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
|
| 3532 |
+
"dev": true,
|
| 3533 |
+
"dependencies": {
|
| 3534 |
+
"regenerator-runtime": "^0.14.0"
|
| 3535 |
+
},
|
| 3536 |
+
"engines": {
|
| 3537 |
+
"node": ">=6.9.0"
|
| 3538 |
+
}
|
| 3539 |
+
},
|
| 3540 |
+
"node_modules/@umijs/lint/node_modules/@umijs/babel-preset-umi": {
|
| 3541 |
+
"version": "4.1.1",
|
| 3542 |
+
"resolved": "https://registry.npmmirror.com/@umijs/babel-preset-umi/-/babel-preset-umi-4.1.1.tgz",
|
| 3543 |
+
"integrity": "sha512-6pYZnF03euAJGZN3VLe8PKKRNMH6Zxj4GKNooLvJ0Wz0eMufmYDcA4CpbR6h8i1JpgcQ0Sngr8bqHLb7oMqrvw==",
|
| 3544 |
+
"dev": true,
|
| 3545 |
+
"dependencies": {
|
| 3546 |
+
"@babel/runtime": "7.23.6",
|
| 3547 |
+
"@bloomberg/record-tuple-polyfill": "0.0.4",
|
| 3548 |
+
"@umijs/bundler-utils": "4.1.1",
|
| 3549 |
+
"@umijs/utils": "4.1.1",
|
| 3550 |
+
"core-js": "3.34.0"
|
| 3551 |
+
}
|
| 3552 |
+
},
|
| 3553 |
+
"node_modules/@umijs/lint/node_modules/@umijs/bundler-utils": {
|
| 3554 |
+
"version": "4.1.1",
|
| 3555 |
+
"resolved": "https://registry.npmmirror.com/@umijs/bundler-utils/-/bundler-utils-4.1.1.tgz",
|
| 3556 |
+
"integrity": "sha512-k1I1tjDePgB1XqpQHZiLJ/5gS4EykY8hqqzEzD1CSbd5KFE614+q6W/gcpFZ0YLJDWY1GdjOYpRokvuI/MSRfg==",
|
| 3557 |
+
"dev": true,
|
| 3558 |
+
"dependencies": {
|
| 3559 |
+
"@umijs/utils": "4.1.1",
|
| 3560 |
+
"esbuild": "0.17.19",
|
| 3561 |
+
"regenerate": "^1.4.2",
|
| 3562 |
+
"regenerate-unicode-properties": "10.1.1",
|
| 3563 |
+
"spdy": "^4.0.2"
|
| 3564 |
+
}
|
| 3565 |
+
},
|
| 3566 |
+
"node_modules/@umijs/lint/node_modules/@umijs/utils": {
|
| 3567 |
+
"version": "4.1.1",
|
| 3568 |
+
"resolved": "https://registry.npmmirror.com/@umijs/utils/-/utils-4.1.1.tgz",
|
| 3569 |
+
"integrity": "sha512-hbnbJR3RA7fu4E7q4JFZ47XMYArr6Zn5bftr8YZ+o6hzJlomr4gzoOXE+XxM7rVMK4AFZoc+QZgNTJyISd08Pg==",
|
| 3570 |
+
"dev": true,
|
| 3571 |
+
"dependencies": {
|
| 3572 |
+
"chokidar": "3.5.3",
|
| 3573 |
+
"pino": "7.11.0"
|
| 3574 |
+
}
|
| 3575 |
+
},
|
| 3576 |
"node_modules/@umijs/mfsu": {
|
| 3577 |
"version": "4.1.0",
|
| 3578 |
"resolved": "https://registry.npmmirror.com/@umijs/mfsu/-/mfsu-4.1.0.tgz",
|
|
|
|
| 16370 |
"qs": "^6.9.1"
|
| 16371 |
}
|
| 16372 |
},
|
| 16373 |
+
"node_modules/umi/node_modules/@babel/core": {
|
| 16374 |
+
"version": "7.23.6",
|
| 16375 |
+
"resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.23.6.tgz",
|
| 16376 |
+
"integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==",
|
| 16377 |
+
"dependencies": {
|
| 16378 |
+
"@ampproject/remapping": "^2.2.0",
|
| 16379 |
+
"@babel/code-frame": "^7.23.5",
|
| 16380 |
+
"@babel/generator": "^7.23.6",
|
| 16381 |
+
"@babel/helper-compilation-targets": "^7.23.6",
|
| 16382 |
+
"@babel/helper-module-transforms": "^7.23.3",
|
| 16383 |
+
"@babel/helpers": "^7.23.6",
|
| 16384 |
+
"@babel/parser": "^7.23.6",
|
| 16385 |
+
"@babel/template": "^7.22.15",
|
| 16386 |
+
"@babel/traverse": "^7.23.6",
|
| 16387 |
+
"@babel/types": "^7.23.6",
|
| 16388 |
+
"convert-source-map": "^2.0.0",
|
| 16389 |
+
"debug": "^4.1.0",
|
| 16390 |
+
"gensync": "^1.0.0-beta.2",
|
| 16391 |
+
"json5": "^2.2.3",
|
| 16392 |
+
"semver": "^6.3.1"
|
| 16393 |
+
},
|
| 16394 |
+
"engines": {
|
| 16395 |
+
"node": ">=6.9.0"
|
| 16396 |
+
}
|
| 16397 |
+
},
|
| 16398 |
"node_modules/umi/node_modules/@babel/runtime": {
|
| 16399 |
"version": "7.23.6",
|
| 16400 |
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.6.tgz",
|
|
|
|
| 16406 |
"node": ">=6.9.0"
|
| 16407 |
}
|
| 16408 |
},
|
| 16409 |
+
"node_modules/umi/node_modules/@umijs/lint": {
|
| 16410 |
+
"version": "4.1.0",
|
| 16411 |
+
"resolved": "https://registry.npmmirror.com/@umijs/lint/-/lint-4.1.0.tgz",
|
| 16412 |
+
"integrity": "sha512-drXkAeBJGMLrPr/dDiOZ2Z+3VKkAf53MzoOIhwHy5atq+PFNG9Y7e6YuWrK3qVF75zg9culQzlHTvinCjDK97Q==",
|
| 16413 |
+
"dependencies": {
|
| 16414 |
+
"@babel/core": "7.23.6",
|
| 16415 |
+
"@babel/eslint-parser": "7.23.3",
|
| 16416 |
+
"@stylelint/postcss-css-in-js": "^0.38.0",
|
| 16417 |
+
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
| 16418 |
+
"@typescript-eslint/parser": "^5.62.0",
|
| 16419 |
+
"@umijs/babel-preset-umi": "4.1.0",
|
| 16420 |
+
"eslint-plugin-jest": "27.2.3",
|
| 16421 |
+
"eslint-plugin-react": "7.33.2",
|
| 16422 |
+
"eslint-plugin-react-hooks": "4.6.0",
|
| 16423 |
+
"postcss": "^8.4.21",
|
| 16424 |
+
"postcss-syntax": "0.36.2",
|
| 16425 |
+
"stylelint-config-standard": "25.0.0"
|
| 16426 |
+
}
|
| 16427 |
+
},
|
| 16428 |
"node_modules/umi/node_modules/fast-glob": {
|
| 16429 |
"version": "3.3.2",
|
| 16430 |
"resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz",
|
web/package.json
CHANGED
|
@@ -5,6 +5,7 @@
|
|
| 5 |
"build": "umi build",
|
| 6 |
"dev": "cross-env PORT=9000 umi dev",
|
| 7 |
"postinstall": "umi setup",
|
|
|
|
| 8 |
"setup": "umi setup",
|
| 9 |
"start": "npm run dev"
|
| 10 |
},
|
|
@@ -30,6 +31,7 @@
|
|
| 30 |
"@types/lodash": "^4.14.202",
|
| 31 |
"@types/react": "^18.0.33",
|
| 32 |
"@types/react-dom": "^18.0.11",
|
|
|
|
| 33 |
"@umijs/plugins": "^4.1.0",
|
| 34 |
"cross-env": "^7.0.3",
|
| 35 |
"prettier": "^3.2.4",
|
|
|
|
| 5 |
"build": "umi build",
|
| 6 |
"dev": "cross-env PORT=9000 umi dev",
|
| 7 |
"postinstall": "umi setup",
|
| 8 |
+
"lint": "umi lint --eslint-only",
|
| 9 |
"setup": "umi setup",
|
| 10 |
"start": "npm run dev"
|
| 11 |
},
|
|
|
|
| 31 |
"@types/lodash": "^4.14.202",
|
| 32 |
"@types/react": "^18.0.33",
|
| 33 |
"@types/react-dom": "^18.0.11",
|
| 34 |
+
"@umijs/lint": "^4.1.1",
|
| 35 |
"@umijs/plugins": "^4.1.0",
|
| 36 |
"cross-env": "^7.0.3",
|
| 37 |
"prettier": "^3.2.4",
|
web/src/app.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
-
import React, { ReactNode } from
|
| 2 |
-
import { Inspector } from
|
| 3 |
|
| 4 |
export function rootContainer(container: ReactNode) {
|
| 5 |
return React.createElement(Inspector, null, container);
|
|
|
|
| 1 |
+
import React, { ReactNode } from 'react';
|
| 2 |
+
import { Inspector } from 'react-dev-inspector';
|
| 3 |
|
| 4 |
export function rootContainer(container: ReactNode) {
|
| 5 |
return React.createElement(Inspector, null, container);
|
web/src/interfaces/common.ts
CHANGED
|
@@ -5,4 +5,5 @@ export interface Pagination {
|
|
| 5 |
|
| 6 |
export interface BaseState {
|
| 7 |
pagination: Pagination;
|
|
|
|
| 8 |
}
|
|
|
|
| 5 |
|
| 6 |
export interface BaseState {
|
| 7 |
pagination: Pagination;
|
| 8 |
+
searchString: string;
|
| 9 |
}
|
web/src/interfaces/database/knowledge.ts
CHANGED
|
@@ -65,3 +65,13 @@ export interface ITenantInfo {
|
|
| 65 |
chat_id: string;
|
| 66 |
speech2text_id: string;
|
| 67 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
chat_id: string;
|
| 66 |
speech2text_id: string;
|
| 67 |
}
|
| 68 |
+
|
| 69 |
+
export interface IChunk {
|
| 70 |
+
available_int: number; // Whether to enable, 0: not enabled, 1: enabled
|
| 71 |
+
chunk_id: string;
|
| 72 |
+
content_with_weight: string;
|
| 73 |
+
doc_id: string;
|
| 74 |
+
docnm_kwd: string;
|
| 75 |
+
img_id: string;
|
| 76 |
+
important_kwd: any[];
|
| 77 |
+
}
|
web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.less
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.image {
|
| 2 |
+
width: 100px !important;
|
| 3 |
+
min-width: 100px;
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
.imagePreview {
|
| 7 |
+
width: 600px;
|
| 8 |
+
}
|
web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.tsx
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { IChunk } from '@/interfaces/database/knowledge';
|
| 2 |
+
import { api_host } from '@/utils/api';
|
| 3 |
+
import { Card, Checkbox, CheckboxProps, Flex, Popover, Switch } from 'antd';
|
| 4 |
+
import { useDispatch } from 'umi';
|
| 5 |
+
|
| 6 |
+
import { useState } from 'react';
|
| 7 |
+
import styles from './index.less';
|
| 8 |
+
|
| 9 |
+
interface IProps {
|
| 10 |
+
item: IChunk;
|
| 11 |
+
checked: boolean;
|
| 12 |
+
handleCheckboxClick: (chunkId: string, checked: boolean) => void;
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
interface IImage {
|
| 16 |
+
id: string;
|
| 17 |
+
className: string;
|
| 18 |
+
}
|
| 19 |
+
// Pass onMouseEnter and onMouseLeave to img tag using props
|
| 20 |
+
const Image = ({ id, className, ...props }: IImage) => {
|
| 21 |
+
return (
|
| 22 |
+
<img
|
| 23 |
+
{...props}
|
| 24 |
+
src={`${api_host}/document/image/${id}`}
|
| 25 |
+
alt=""
|
| 26 |
+
className={className}
|
| 27 |
+
/>
|
| 28 |
+
);
|
| 29 |
+
};
|
| 30 |
+
|
| 31 |
+
const ChunkCard = ({ item, checked, handleCheckboxClick }: IProps) => {
|
| 32 |
+
const dispatch = useDispatch();
|
| 33 |
+
|
| 34 |
+
const available = Number(item.available_int);
|
| 35 |
+
const [enabled, setEnabled] = useState(available === 1);
|
| 36 |
+
|
| 37 |
+
const switchChunk = () => {
|
| 38 |
+
dispatch({
|
| 39 |
+
type: 'chunkModel/switch_chunk',
|
| 40 |
+
payload: {
|
| 41 |
+
chunk_ids: [item.chunk_id],
|
| 42 |
+
available_int: available === 0 ? 1 : 0,
|
| 43 |
+
doc_id: item.doc_id,
|
| 44 |
+
},
|
| 45 |
+
});
|
| 46 |
+
};
|
| 47 |
+
|
| 48 |
+
const onChange = (checked: boolean) => {
|
| 49 |
+
setEnabled(checked);
|
| 50 |
+
switchChunk();
|
| 51 |
+
};
|
| 52 |
+
|
| 53 |
+
const handleCheck: CheckboxProps['onChange'] = (e) => {
|
| 54 |
+
handleCheckboxClick(item.chunk_id, e.target.checked);
|
| 55 |
+
};
|
| 56 |
+
|
| 57 |
+
return (
|
| 58 |
+
<div>
|
| 59 |
+
<Card>
|
| 60 |
+
<Flex gap={'middle'} justify={'space-between'}>
|
| 61 |
+
<Checkbox onChange={handleCheck} checked={checked}></Checkbox>
|
| 62 |
+
{item.img_id && (
|
| 63 |
+
<Popover
|
| 64 |
+
placement="topRight"
|
| 65 |
+
content={
|
| 66 |
+
<Image id={item.img_id} className={styles.imagePreview}></Image>
|
| 67 |
+
}
|
| 68 |
+
>
|
| 69 |
+
<img
|
| 70 |
+
src={`${api_host}/document/image/${item.img_id}`}
|
| 71 |
+
alt=""
|
| 72 |
+
className={styles.image}
|
| 73 |
+
/>
|
| 74 |
+
<Image id={item.img_id} className={styles.image}></Image>
|
| 75 |
+
</Popover>
|
| 76 |
+
)}
|
| 77 |
+
|
| 78 |
+
<section>{item.content_with_weight}</section>
|
| 79 |
+
<div>
|
| 80 |
+
<Switch checked={enabled} onChange={onChange} />
|
| 81 |
+
</div>
|
| 82 |
+
</Flex>
|
| 83 |
+
</Card>
|
| 84 |
+
</div>
|
| 85 |
+
);
|
| 86 |
+
};
|
| 87 |
+
|
| 88 |
+
export default ChunkCard;
|
web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-toolbar/index.tsx
CHANGED
|
@@ -1,4 +1,6 @@
|
|
| 1 |
import { ReactComponent as FilterIcon } from '@/assets/filter.svg';
|
|
|
|
|
|
|
| 2 |
import {
|
| 3 |
ArrowLeftOutlined,
|
| 4 |
CheckCircleOutlined,
|
|
@@ -9,17 +11,50 @@ import {
|
|
| 9 |
PlusOutlined,
|
| 10 |
SearchOutlined,
|
| 11 |
} from '@ant-design/icons';
|
| 12 |
-
import {
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
-
const ChunkToolBar = () => {
|
| 16 |
const items: MenuProps['items'] = useMemo(() => {
|
| 17 |
return [
|
| 18 |
{
|
| 19 |
key: '1',
|
| 20 |
label: (
|
| 21 |
<>
|
| 22 |
-
<Checkbox>
|
| 23 |
<b>Select All</b>
|
| 24 |
</Checkbox>
|
| 25 |
</>
|
|
@@ -55,47 +90,49 @@ const ChunkToolBar = () => {
|
|
| 55 |
),
|
| 56 |
},
|
| 57 |
];
|
| 58 |
-
}, []);
|
| 59 |
|
| 60 |
const content = (
|
| 61 |
<Menu style={{ width: 200 }} items={items} selectable={false} />
|
| 62 |
);
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
return (
|
| 65 |
<Flex justify="space-between" align="center">
|
| 66 |
-
<Space>
|
| 67 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
<FilePdfOutlined />
|
| 69 |
-
|
| 70 |
</Space>
|
| 71 |
<Space>
|
| 72 |
-
{
|
| 73 |
-
defaultValue="lucy"
|
| 74 |
-
style={{ width: 100 }}
|
| 75 |
-
popupMatchSelectWidth={false}
|
| 76 |
-
optionRender={() => null}
|
| 77 |
-
dropdownRender={(menu) => (
|
| 78 |
-
<div style={{ width: 300 }}>
|
| 79 |
-
{menu}
|
| 80 |
-
<Menu
|
| 81 |
-
// onClick={onClick}
|
| 82 |
-
style={{ width: 256 }}
|
| 83 |
-
// defaultSelectedKeys={['1']}
|
| 84 |
-
// defaultOpenKeys={['sub1']}
|
| 85 |
-
// mode="inline"
|
| 86 |
-
items={actionItems}
|
| 87 |
-
/>
|
| 88 |
-
</div>
|
| 89 |
-
)}
|
| 90 |
-
></Select> */}
|
| 91 |
-
<Popover content={content} placement="bottomLeft" arrow={false}>
|
| 92 |
<Button>
|
| 93 |
Bulk
|
| 94 |
<DownOutlined />
|
| 95 |
</Button>
|
| 96 |
</Popover>
|
| 97 |
<Button icon={<SearchOutlined />} />
|
| 98 |
-
<
|
|
|
|
|
|
|
| 99 |
<Button icon={<DeleteOutlined />} />
|
| 100 |
<Button icon={<PlusOutlined />} type="primary" />
|
| 101 |
</Space>
|
|
|
|
| 1 |
import { ReactComponent as FilterIcon } from '@/assets/filter.svg';
|
| 2 |
+
import { KnowledgeRouteKey } from '@/constants/knowledge';
|
| 3 |
+
import { useKnowledgeBaseId } from '@/hooks/knowledgeHook';
|
| 4 |
import {
|
| 5 |
ArrowLeftOutlined,
|
| 6 |
CheckCircleOutlined,
|
|
|
|
| 11 |
PlusOutlined,
|
| 12 |
SearchOutlined,
|
| 13 |
} from '@ant-design/icons';
|
| 14 |
+
import {
|
| 15 |
+
Button,
|
| 16 |
+
Checkbox,
|
| 17 |
+
Flex,
|
| 18 |
+
Menu,
|
| 19 |
+
MenuProps,
|
| 20 |
+
Popover,
|
| 21 |
+
Radio,
|
| 22 |
+
RadioChangeEvent,
|
| 23 |
+
Space,
|
| 24 |
+
} from 'antd';
|
| 25 |
+
import { useCallback, useMemo } from 'react';
|
| 26 |
+
import { Link, useDispatch, useSelector } from 'umi';
|
| 27 |
+
import { ChunkModelState } from '../../model';
|
| 28 |
+
|
| 29 |
+
interface IProps {
|
| 30 |
+
checked: boolean;
|
| 31 |
+
getChunkList: () => void;
|
| 32 |
+
selectAllChunk: (checked: boolean) => void;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
const ChunkToolBar = ({ getChunkList, selectAllChunk, checked }: IProps) => {
|
| 36 |
+
const { documentInfo, available }: ChunkModelState = useSelector(
|
| 37 |
+
(state: any) => state.chunkModel,
|
| 38 |
+
);
|
| 39 |
+
const dispatch = useDispatch();
|
| 40 |
+
|
| 41 |
+
const knowledgeBaseId = useKnowledgeBaseId();
|
| 42 |
+
|
| 43 |
+
const handleSelectAllCheck = useCallback(
|
| 44 |
+
(e: any) => {
|
| 45 |
+
// console.info(e.target.checked);
|
| 46 |
+
selectAllChunk(e.target.checked);
|
| 47 |
+
},
|
| 48 |
+
[selectAllChunk],
|
| 49 |
+
);
|
| 50 |
|
|
|
|
| 51 |
const items: MenuProps['items'] = useMemo(() => {
|
| 52 |
return [
|
| 53 |
{
|
| 54 |
key: '1',
|
| 55 |
label: (
|
| 56 |
<>
|
| 57 |
+
<Checkbox onChange={handleSelectAllCheck} checked={checked}>
|
| 58 |
<b>Select All</b>
|
| 59 |
</Checkbox>
|
| 60 |
</>
|
|
|
|
| 90 |
),
|
| 91 |
},
|
| 92 |
];
|
| 93 |
+
}, [checked, handleSelectAllCheck]);
|
| 94 |
|
| 95 |
const content = (
|
| 96 |
<Menu style={{ width: 200 }} items={items} selectable={false} />
|
| 97 |
);
|
| 98 |
|
| 99 |
+
const handleFilterChange = (e: RadioChangeEvent) => {
|
| 100 |
+
dispatch({ type: 'chunkModel/setAvailable', payload: e.target.value });
|
| 101 |
+
getChunkList();
|
| 102 |
+
};
|
| 103 |
+
|
| 104 |
+
const filterContent = (
|
| 105 |
+
<Radio.Group onChange={handleFilterChange} value={available}>
|
| 106 |
+
<Space direction="vertical">
|
| 107 |
+
<Radio value={undefined}>All</Radio>
|
| 108 |
+
<Radio value={1}>Enabled</Radio>
|
| 109 |
+
<Radio value={0}>Disabled</Radio>
|
| 110 |
+
</Space>
|
| 111 |
+
</Radio.Group>
|
| 112 |
+
);
|
| 113 |
+
|
| 114 |
return (
|
| 115 |
<Flex justify="space-between" align="center">
|
| 116 |
+
<Space size={'middle'}>
|
| 117 |
+
<Link
|
| 118 |
+
to={`/knowledge/${KnowledgeRouteKey.Dataset}?id=${knowledgeBaseId}`}
|
| 119 |
+
>
|
| 120 |
+
<ArrowLeftOutlined />
|
| 121 |
+
</Link>
|
| 122 |
<FilePdfOutlined />
|
| 123 |
+
{documentInfo.name}
|
| 124 |
</Space>
|
| 125 |
<Space>
|
| 126 |
+
<Popover content={content} placement="bottom" arrow={false}>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
<Button>
|
| 128 |
Bulk
|
| 129 |
<DownOutlined />
|
| 130 |
</Button>
|
| 131 |
</Popover>
|
| 132 |
<Button icon={<SearchOutlined />} />
|
| 133 |
+
<Popover content={filterContent} placement="bottom" arrow={false}>
|
| 134 |
+
<Button icon={<FilterIcon />} />
|
| 135 |
+
</Popover>
|
| 136 |
<Button icon={<DeleteOutlined />} />
|
| 137 |
<Button icon={<PlusOutlined />} type="primary" />
|
| 138 |
</Space>
|
web/src/pages/add-knowledge/components/knowledge-chunk/index.less
CHANGED
|
@@ -1,70 +1,69 @@
|
|
| 1 |
.chunkPage {
|
| 2 |
-
|
| 3 |
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
}
|
| 24 |
}
|
|
|
|
| 25 |
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
}
|
| 30 |
|
| 31 |
.container {
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
display: flex;
|
| 34 |
-
flex-direction: column;
|
| 35 |
justify-content: space-between;
|
| 36 |
|
| 37 |
-
.
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
flex: 1;
|
| 43 |
-
// width: 207px;
|
| 44 |
-
height: 88px;
|
| 45 |
-
overflow: hidden;
|
| 46 |
-
}
|
| 47 |
}
|
|
|
|
| 48 |
|
| 49 |
-
|
| 50 |
-
|
| 51 |
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
}
|
| 55 |
}
|
|
|
|
| 56 |
}
|
| 57 |
|
| 58 |
.card {
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
}
|
| 64 |
-
|
| 65 |
-
margin-bottom: 10px;
|
| 66 |
}
|
| 67 |
|
| 68 |
-
|
|
|
|
| 69 |
|
| 70 |
-
|
|
|
|
|
|
| 1 |
.chunkPage {
|
| 2 |
+
padding: 24px;
|
| 3 |
|
| 4 |
+
display: flex;
|
| 5 |
+
// height: calc(100vh - 112px);
|
| 6 |
+
flex-direction: column;
|
| 7 |
|
| 8 |
+
.filter {
|
| 9 |
+
margin: 10px 0;
|
| 10 |
+
display: flex;
|
| 11 |
+
height: 32px;
|
| 12 |
+
justify-content: space-between;
|
| 13 |
+
}
|
| 14 |
|
| 15 |
+
.pageContent {
|
| 16 |
+
flex: 1;
|
| 17 |
+
width: 100%;
|
| 18 |
+
padding-right: 12px;
|
| 19 |
+
overflow-y: auto;
|
| 20 |
|
| 21 |
+
.spin {
|
| 22 |
+
min-height: 400px;
|
|
|
|
| 23 |
}
|
| 24 |
+
}
|
| 25 |
|
| 26 |
+
.pageFooter {
|
| 27 |
+
height: 32px;
|
| 28 |
+
}
|
| 29 |
}
|
| 30 |
|
| 31 |
.container {
|
| 32 |
+
height: 100px;
|
| 33 |
+
display: flex;
|
| 34 |
+
flex-direction: column;
|
| 35 |
+
justify-content: space-between;
|
| 36 |
+
|
| 37 |
+
.content {
|
| 38 |
display: flex;
|
|
|
|
| 39 |
justify-content: space-between;
|
| 40 |
|
| 41 |
+
.context {
|
| 42 |
+
flex: 1;
|
| 43 |
+
// width: 207px;
|
| 44 |
+
height: 88px;
|
| 45 |
+
overflow: hidden;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
}
|
| 47 |
+
}
|
| 48 |
|
| 49 |
+
.footer {
|
| 50 |
+
height: 20px;
|
| 51 |
|
| 52 |
+
.text {
|
| 53 |
+
margin-left: 10px;
|
|
|
|
| 54 |
}
|
| 55 |
+
}
|
| 56 |
}
|
| 57 |
|
| 58 |
.card {
|
| 59 |
+
:global {
|
| 60 |
+
.ant-card-body {
|
| 61 |
+
padding: 10px;
|
| 62 |
+
margin: 0;
|
|
|
|
|
|
|
|
|
|
| 63 |
}
|
| 64 |
|
| 65 |
+
margin-bottom: 10px;
|
| 66 |
+
}
|
| 67 |
|
| 68 |
+
cursor: pointer;
|
| 69 |
+
}
|
web/src/pages/add-knowledge/components/knowledge-chunk/index.tsx
CHANGED
|
@@ -1,41 +1,36 @@
|
|
| 1 |
-
import { api_host } from '@/utils/api';
|
| 2 |
import { getOneNamespaceEffectsLoading } from '@/utils/storeUtil';
|
| 3 |
-
import { DeleteOutlined, MinusSquareOutlined } from '@ant-design/icons';
|
| 4 |
import type { PaginationProps } from 'antd';
|
| 5 |
-
import {
|
| 6 |
-
Button,
|
| 7 |
-
Card,
|
| 8 |
-
Col,
|
| 9 |
-
Input,
|
| 10 |
-
Pagination,
|
| 11 |
-
Popconfirm,
|
| 12 |
-
Row,
|
| 13 |
-
Select,
|
| 14 |
-
Spin,
|
| 15 |
-
Switch,
|
| 16 |
-
} from 'antd';
|
| 17 |
import { debounce } from 'lodash';
|
| 18 |
import React, { useCallback, useEffect, useState } from 'react';
|
| 19 |
import { useDispatch, useSearchParams, useSelector } from 'umi';
|
| 20 |
import CreateModal from './components/createModal';
|
| 21 |
|
|
|
|
| 22 |
import ChunkToolBar from './components/chunk-toolbar';
|
| 23 |
import styles from './index.less';
|
|
|
|
| 24 |
|
| 25 |
interface PayloadType {
|
| 26 |
doc_id: string;
|
| 27 |
keywords?: string;
|
| 28 |
-
available_int?: number;
|
| 29 |
}
|
| 30 |
|
| 31 |
const Chunk = () => {
|
| 32 |
const dispatch = useDispatch();
|
| 33 |
-
const chunkModel = useSelector(
|
|
|
|
|
|
|
| 34 |
const [keywords, SetKeywords] = useState('');
|
| 35 |
-
const [
|
| 36 |
const [searchParams] = useSearchParams();
|
| 37 |
-
const
|
| 38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
const effects = useSelector((state: any) => state.loading.effects);
|
| 40 |
const loading = getOneNamespaceEffectsLoading('chunkModel', effects, [
|
| 41 |
'create_hunk',
|
|
@@ -44,23 +39,19 @@ const Chunk = () => {
|
|
| 44 |
]);
|
| 45 |
const documentId: string = searchParams.get('doc_id') || '';
|
| 46 |
|
| 47 |
-
const getChunkList = (
|
| 48 |
const payload: PayloadType = {
|
| 49 |
doc_id: documentId,
|
| 50 |
-
keywords: value || keywords,
|
| 51 |
-
available_int,
|
| 52 |
};
|
| 53 |
-
|
| 54 |
-
delete payload.available_int;
|
| 55 |
-
}
|
| 56 |
dispatch({
|
| 57 |
type: 'chunkModel/chunk_list',
|
| 58 |
payload: {
|
| 59 |
...payload,
|
| 60 |
-
...pagination,
|
| 61 |
},
|
| 62 |
});
|
| 63 |
};
|
|
|
|
| 64 |
const confirm = async (id: string) => {
|
| 65 |
const retcode = await dispatch<any>({
|
| 66 |
type: 'chunkModel/rm_chunk',
|
|
@@ -84,29 +75,55 @@ const Chunk = () => {
|
|
| 84 |
getChunkList();
|
| 85 |
};
|
| 86 |
|
| 87 |
-
const
|
| 88 |
page,
|
| 89 |
size,
|
| 90 |
) => {
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
const switchChunk = async (id: string, available_int: boolean) => {
|
| 95 |
-
const retcode = await dispatch<any>({
|
| 96 |
-
type: 'chunkModel/switch_chunk',
|
| 97 |
payload: {
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
doc_id: documentId,
|
| 101 |
},
|
| 102 |
});
|
| 103 |
-
|
| 104 |
-
retcode === 0 && getChunkList();
|
| 105 |
};
|
| 106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
useEffect(() => {
|
| 108 |
getChunkList();
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
|
| 111 |
const debounceChange = debounce(getChunkList, 300);
|
| 112 |
const debounceCallback = useCallback(
|
|
@@ -117,17 +134,20 @@ const Chunk = () => {
|
|
| 117 |
const handleInputChange = (
|
| 118 |
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
| 119 |
) => {
|
|
|
|
| 120 |
const value = e.target.value;
|
| 121 |
SetKeywords(value);
|
| 122 |
debounceCallback(value);
|
| 123 |
};
|
| 124 |
-
|
| 125 |
-
setAvailableInt(value);
|
| 126 |
-
};
|
| 127 |
return (
|
| 128 |
<>
|
| 129 |
<div className={styles.chunkPage}>
|
| 130 |
-
<ChunkToolBar
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
<div className={styles.filter}>
|
| 132 |
<div>
|
| 133 |
<Input
|
|
@@ -137,28 +157,6 @@ const Chunk = () => {
|
|
| 137 |
allowClear
|
| 138 |
onChange={handleInputChange}
|
| 139 |
/>
|
| 140 |
-
<Select
|
| 141 |
-
showSearch
|
| 142 |
-
placeholder="是否启用"
|
| 143 |
-
optionFilterProp="children"
|
| 144 |
-
value={available_int}
|
| 145 |
-
onChange={handleSelectChange}
|
| 146 |
-
style={{ width: 220 }}
|
| 147 |
-
options={[
|
| 148 |
-
{
|
| 149 |
-
value: -1,
|
| 150 |
-
label: '全部',
|
| 151 |
-
},
|
| 152 |
-
{
|
| 153 |
-
value: 1,
|
| 154 |
-
label: '启用',
|
| 155 |
-
},
|
| 156 |
-
{
|
| 157 |
-
value: 0,
|
| 158 |
-
label: '未启用',
|
| 159 |
-
},
|
| 160 |
-
]}
|
| 161 |
-
/>
|
| 162 |
</div>
|
| 163 |
<Button
|
| 164 |
onClick={() => {
|
|
@@ -171,86 +169,16 @@ const Chunk = () => {
|
|
| 171 |
</div>
|
| 172 |
<div className={styles.pageContent}>
|
| 173 |
<Spin spinning={loading} className={styles.spin} size="large">
|
| 174 |
-
<
|
| 175 |
-
{data.map((item
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
>
|
| 185 |
-
<Card
|
| 186 |
-
className={styles.card}
|
| 187 |
-
onClick={() => {
|
| 188 |
-
handleEditchunk(item.chunk_id);
|
| 189 |
-
}}
|
| 190 |
-
>
|
| 191 |
-
<img
|
| 192 |
-
style={{ width: '50px' }}
|
| 193 |
-
src={`${api_host}/document/image/${item.img_id}`}
|
| 194 |
-
alt=""
|
| 195 |
-
/>
|
| 196 |
-
<div className={styles.container}>
|
| 197 |
-
<div className={styles.content}>
|
| 198 |
-
<span className={styles.context}>
|
| 199 |
-
{item.content_ltks}
|
| 200 |
-
</span>
|
| 201 |
-
<span className={styles.delete}>
|
| 202 |
-
<Switch
|
| 203 |
-
size="small"
|
| 204 |
-
defaultValue={item.available_int == '1'}
|
| 205 |
-
onChange={(checked: boolean, e: any) => {
|
| 206 |
-
e.stopPropagation();
|
| 207 |
-
e.nativeEvent.stopImmediatePropagation();
|
| 208 |
-
switchChunk(item.chunk_id, checked);
|
| 209 |
-
}}
|
| 210 |
-
/>
|
| 211 |
-
</span>
|
| 212 |
-
</div>
|
| 213 |
-
<div className={styles.footer}>
|
| 214 |
-
<span className={styles.text}>
|
| 215 |
-
<MinusSquareOutlined />
|
| 216 |
-
{item.doc_num}文档
|
| 217 |
-
</span>
|
| 218 |
-
<span className={styles.text}>
|
| 219 |
-
<MinusSquareOutlined />
|
| 220 |
-
{item.chunk_num}个
|
| 221 |
-
</span>
|
| 222 |
-
<span className={styles.text}>
|
| 223 |
-
<MinusSquareOutlined />
|
| 224 |
-
{item.token_num}千字符
|
| 225 |
-
</span>
|
| 226 |
-
<span style={{ float: 'right' }}>
|
| 227 |
-
<Popconfirm
|
| 228 |
-
title="Delete the task"
|
| 229 |
-
description="Are you sure to delete this task?"
|
| 230 |
-
onConfirm={(e: any) => {
|
| 231 |
-
e.stopPropagation();
|
| 232 |
-
e.nativeEvent.stopImmediatePropagation();
|
| 233 |
-
console.log(confirm);
|
| 234 |
-
confirm(item.chunk_id);
|
| 235 |
-
}}
|
| 236 |
-
okText="Yes"
|
| 237 |
-
cancelText="No"
|
| 238 |
-
>
|
| 239 |
-
<DeleteOutlined
|
| 240 |
-
onClick={(e) => {
|
| 241 |
-
e.stopPropagation();
|
| 242 |
-
e.nativeEvent.stopImmediatePropagation();
|
| 243 |
-
}}
|
| 244 |
-
/>
|
| 245 |
-
</Popconfirm>
|
| 246 |
-
</span>
|
| 247 |
-
</div>
|
| 248 |
-
</div>
|
| 249 |
-
</Card>
|
| 250 |
-
</Col>
|
| 251 |
-
);
|
| 252 |
-
})}
|
| 253 |
-
</Row>
|
| 254 |
</Spin>
|
| 255 |
</div>
|
| 256 |
<div className={styles.pageFooter}>
|
|
@@ -259,10 +187,10 @@ const Chunk = () => {
|
|
| 259 |
showLessItems
|
| 260 |
showQuickJumper
|
| 261 |
showSizeChanger
|
| 262 |
-
onChange={
|
| 263 |
-
defaultPageSize={
|
| 264 |
-
pageSizeOptions={[30, 60, 90]}
|
| 265 |
-
defaultCurrent={pagination.
|
| 266 |
total={total}
|
| 267 |
/>
|
| 268 |
</div>
|
|
|
|
|
|
|
| 1 |
import { getOneNamespaceEffectsLoading } from '@/utils/storeUtil';
|
|
|
|
| 2 |
import type { PaginationProps } from 'antd';
|
| 3 |
+
import { Button, Input, Pagination, Space, Spin } from 'antd';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
import { debounce } from 'lodash';
|
| 5 |
import React, { useCallback, useEffect, useState } from 'react';
|
| 6 |
import { useDispatch, useSearchParams, useSelector } from 'umi';
|
| 7 |
import CreateModal from './components/createModal';
|
| 8 |
|
| 9 |
+
import ChunkCard from './components/chunk-card';
|
| 10 |
import ChunkToolBar from './components/chunk-toolbar';
|
| 11 |
import styles from './index.less';
|
| 12 |
+
import { ChunkModelState } from './model';
|
| 13 |
|
| 14 |
interface PayloadType {
|
| 15 |
doc_id: string;
|
| 16 |
keywords?: string;
|
|
|
|
| 17 |
}
|
| 18 |
|
| 19 |
const Chunk = () => {
|
| 20 |
const dispatch = useDispatch();
|
| 21 |
+
const chunkModel: ChunkModelState = useSelector(
|
| 22 |
+
(state: any) => state.chunkModel,
|
| 23 |
+
);
|
| 24 |
const [keywords, SetKeywords] = useState('');
|
| 25 |
+
const [selectedChunkIds, setSelectedChunkIds] = useState<string[]>([]);
|
| 26 |
const [searchParams] = useSearchParams();
|
| 27 |
+
const {
|
| 28 |
+
data = [],
|
| 29 |
+
total,
|
| 30 |
+
chunk_id,
|
| 31 |
+
isShowCreateModal,
|
| 32 |
+
pagination,
|
| 33 |
+
} = chunkModel;
|
| 34 |
const effects = useSelector((state: any) => state.loading.effects);
|
| 35 |
const loading = getOneNamespaceEffectsLoading('chunkModel', effects, [
|
| 36 |
'create_hunk',
|
|
|
|
| 39 |
]);
|
| 40 |
const documentId: string = searchParams.get('doc_id') || '';
|
| 41 |
|
| 42 |
+
const getChunkList = () => {
|
| 43 |
const payload: PayloadType = {
|
| 44 |
doc_id: documentId,
|
|
|
|
|
|
|
| 45 |
};
|
| 46 |
+
|
|
|
|
|
|
|
| 47 |
dispatch({
|
| 48 |
type: 'chunkModel/chunk_list',
|
| 49 |
payload: {
|
| 50 |
...payload,
|
|
|
|
| 51 |
},
|
| 52 |
});
|
| 53 |
};
|
| 54 |
+
|
| 55 |
const confirm = async (id: string) => {
|
| 56 |
const retcode = await dispatch<any>({
|
| 57 |
type: 'chunkModel/rm_chunk',
|
|
|
|
| 75 |
getChunkList();
|
| 76 |
};
|
| 77 |
|
| 78 |
+
const onPaginationChange: PaginationProps['onShowSizeChange'] = (
|
| 79 |
page,
|
| 80 |
size,
|
| 81 |
) => {
|
| 82 |
+
setSelectedChunkIds([]);
|
| 83 |
+
dispatch({
|
| 84 |
+
type: 'chunkModel/setPagination',
|
|
|
|
|
|
|
|
|
|
| 85 |
payload: {
|
| 86 |
+
current: page,
|
| 87 |
+
pageSize: size,
|
|
|
|
| 88 |
},
|
| 89 |
});
|
| 90 |
+
getChunkList();
|
|
|
|
| 91 |
};
|
| 92 |
|
| 93 |
+
const selectAllChunk = useCallback(
|
| 94 |
+
(checked: boolean) => {
|
| 95 |
+
setSelectedChunkIds(checked ? data.map((x) => x.chunk_id) : []);
|
| 96 |
+
// setSelectedChunkIds((previousIds) => {
|
| 97 |
+
// return checked ? [...previousIds, ...data.map((x) => x.chunk_id)] : [];
|
| 98 |
+
// });
|
| 99 |
+
},
|
| 100 |
+
[data],
|
| 101 |
+
);
|
| 102 |
+
|
| 103 |
+
const handleSingleCheckboxClick = useCallback(
|
| 104 |
+
(chunkId: string, checked: boolean) => {
|
| 105 |
+
setSelectedChunkIds((previousIds) => {
|
| 106 |
+
const idx = previousIds.findIndex((x) => x === chunkId);
|
| 107 |
+
const nextIds = [...previousIds];
|
| 108 |
+
if (checked && idx === -1) {
|
| 109 |
+
nextIds.push(chunkId);
|
| 110 |
+
} else if (!checked && idx !== -1) {
|
| 111 |
+
nextIds.splice(idx, 1);
|
| 112 |
+
}
|
| 113 |
+
return nextIds;
|
| 114 |
+
});
|
| 115 |
+
},
|
| 116 |
+
[],
|
| 117 |
+
);
|
| 118 |
+
|
| 119 |
useEffect(() => {
|
| 120 |
getChunkList();
|
| 121 |
+
return () => {
|
| 122 |
+
dispatch({
|
| 123 |
+
type: 'chunkModel/resetFilter', // TODO: need to reset state uniformly
|
| 124 |
+
});
|
| 125 |
+
};
|
| 126 |
+
}, [documentId]);
|
| 127 |
|
| 128 |
const debounceChange = debounce(getChunkList, 300);
|
| 129 |
const debounceCallback = useCallback(
|
|
|
|
| 134 |
const handleInputChange = (
|
| 135 |
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
| 136 |
) => {
|
| 137 |
+
setSelectedChunkIds([]);
|
| 138 |
const value = e.target.value;
|
| 139 |
SetKeywords(value);
|
| 140 |
debounceCallback(value);
|
| 141 |
};
|
| 142 |
+
|
|
|
|
|
|
|
| 143 |
return (
|
| 144 |
<>
|
| 145 |
<div className={styles.chunkPage}>
|
| 146 |
+
<ChunkToolBar
|
| 147 |
+
getChunkList={getChunkList}
|
| 148 |
+
selectAllChunk={selectAllChunk}
|
| 149 |
+
checked={selectedChunkIds.length === data.length}
|
| 150 |
+
></ChunkToolBar>
|
| 151 |
<div className={styles.filter}>
|
| 152 |
<div>
|
| 153 |
<Input
|
|
|
|
| 157 |
allowClear
|
| 158 |
onChange={handleInputChange}
|
| 159 |
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
</div>
|
| 161 |
<Button
|
| 162 |
onClick={() => {
|
|
|
|
| 169 |
</div>
|
| 170 |
<div className={styles.pageContent}>
|
| 171 |
<Spin spinning={loading} className={styles.spin} size="large">
|
| 172 |
+
<Space direction="vertical" size={'middle'}>
|
| 173 |
+
{data.map((item) => (
|
| 174 |
+
<ChunkCard
|
| 175 |
+
item={item}
|
| 176 |
+
key={item.chunk_id}
|
| 177 |
+
checked={selectedChunkIds.some((x) => x === item.chunk_id)}
|
| 178 |
+
handleCheckboxClick={handleSingleCheckboxClick}
|
| 179 |
+
></ChunkCard>
|
| 180 |
+
))}
|
| 181 |
+
</Space>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
</Spin>
|
| 183 |
</div>
|
| 184 |
<div className={styles.pageFooter}>
|
|
|
|
| 187 |
showLessItems
|
| 188 |
showQuickJumper
|
| 189 |
showSizeChanger
|
| 190 |
+
onChange={onPaginationChange}
|
| 191 |
+
defaultPageSize={10}
|
| 192 |
+
pageSizeOptions={[10, 30, 60, 90]}
|
| 193 |
+
defaultCurrent={pagination.current}
|
| 194 |
total={total}
|
| 195 |
/>
|
| 196 |
</div>
|
web/src/pages/add-knowledge/components/knowledge-chunk/model.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
|
|
|
|
|
| 1 |
import kbService from '@/services/kbService';
|
|
|
|
|
|
|
| 2 |
import { DvaModel } from 'umi';
|
| 3 |
|
| 4 |
-
export interface ChunkModelState {
|
| 5 |
data: any[];
|
| 6 |
total: number;
|
| 7 |
isShowCreateModal: boolean;
|
| 8 |
chunk_id: string;
|
| 9 |
doc_id: string;
|
| 10 |
chunkInfo: any;
|
|
|
|
|
|
|
| 11 |
}
|
| 12 |
|
| 13 |
const model: DvaModel<ChunkModelState> = {
|
|
@@ -19,6 +25,13 @@ const model: DvaModel<ChunkModelState> = {
|
|
| 19 |
chunk_id: '',
|
| 20 |
doc_id: '',
|
| 21 |
chunkInfo: {},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
},
|
| 23 |
reducers: {
|
| 24 |
updateState(state, { payload }) {
|
|
@@ -27,33 +40,56 @@ const model: DvaModel<ChunkModelState> = {
|
|
| 27 |
...payload,
|
| 28 |
};
|
| 29 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
},
|
| 31 |
-
// subscriptions: {
|
| 32 |
-
// setup({ dispatch, history }) {
|
| 33 |
-
// history.listen(location => {
|
| 34 |
-
// console.log(location)
|
| 35 |
-
// });
|
| 36 |
-
// }
|
| 37 |
-
// },
|
| 38 |
effects: {
|
| 39 |
-
*chunk_list({ payload = {} }, { call, put }) {
|
| 40 |
-
const {
|
| 41 |
-
|
| 42 |
-
const {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
if (retcode === 0) {
|
| 44 |
-
console.log(res);
|
| 45 |
yield put({
|
| 46 |
type: 'updateState',
|
| 47 |
payload: {
|
| 48 |
data: res.chunks,
|
| 49 |
total: res.total,
|
|
|
|
| 50 |
},
|
| 51 |
});
|
| 52 |
}
|
| 53 |
},
|
| 54 |
*switch_chunk({ payload = {} }, { call, put }) {
|
| 55 |
-
const { data
|
| 56 |
-
const { retcode
|
|
|
|
|
|
|
|
|
|
| 57 |
return retcode;
|
| 58 |
},
|
| 59 |
*rm_chunk({ payload = {} }, { call, put }) {
|
|
|
|
| 1 |
+
import { BaseState } from '@/interfaces/common';
|
| 2 |
+
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
| 3 |
import kbService from '@/services/kbService';
|
| 4 |
+
import { message } from 'antd';
|
| 5 |
+
// import { delay } from '@/utils/storeUtil';
|
| 6 |
import { DvaModel } from 'umi';
|
| 7 |
|
| 8 |
+
export interface ChunkModelState extends BaseState {
|
| 9 |
data: any[];
|
| 10 |
total: number;
|
| 11 |
isShowCreateModal: boolean;
|
| 12 |
chunk_id: string;
|
| 13 |
doc_id: string;
|
| 14 |
chunkInfo: any;
|
| 15 |
+
documentInfo: Partial<IKnowledgeFile>;
|
| 16 |
+
available?: number;
|
| 17 |
}
|
| 18 |
|
| 19 |
const model: DvaModel<ChunkModelState> = {
|
|
|
|
| 25 |
chunk_id: '',
|
| 26 |
doc_id: '',
|
| 27 |
chunkInfo: {},
|
| 28 |
+
documentInfo: {},
|
| 29 |
+
pagination: {
|
| 30 |
+
current: 1,
|
| 31 |
+
pageSize: 10,
|
| 32 |
+
},
|
| 33 |
+
searchString: '',
|
| 34 |
+
available: undefined, // set to undefined to select all
|
| 35 |
},
|
| 36 |
reducers: {
|
| 37 |
updateState(state, { payload }) {
|
|
|
|
| 40 |
...payload,
|
| 41 |
};
|
| 42 |
},
|
| 43 |
+
setAvailable(state, { payload }) {
|
| 44 |
+
return { ...state, available: payload };
|
| 45 |
+
},
|
| 46 |
+
setSearchString(state, { payload }) {
|
| 47 |
+
return { ...state, searchString: payload };
|
| 48 |
+
},
|
| 49 |
+
setPagination(state, { payload }) {
|
| 50 |
+
return { ...state, pagination: { ...state.pagination, ...payload } };
|
| 51 |
+
},
|
| 52 |
+
resetFilter(state, { payload }) {
|
| 53 |
+
return {
|
| 54 |
+
...state,
|
| 55 |
+
pagination: {
|
| 56 |
+
current: 1,
|
| 57 |
+
pageSize: 10,
|
| 58 |
+
},
|
| 59 |
+
searchString: '',
|
| 60 |
+
available: undefined,
|
| 61 |
+
};
|
| 62 |
+
},
|
| 63 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
effects: {
|
| 65 |
+
*chunk_list({ payload = {} }, { call, put, select }) {
|
| 66 |
+
const { available, searchString, pagination }: ChunkModelState =
|
| 67 |
+
yield select((state: any) => state.chunkModel);
|
| 68 |
+
const { data } = yield call(kbService.chunk_list, {
|
| 69 |
+
...payload,
|
| 70 |
+
available_int: available,
|
| 71 |
+
keywords: searchString,
|
| 72 |
+
page: pagination.current,
|
| 73 |
+
size: pagination.pageSize,
|
| 74 |
+
});
|
| 75 |
+
const { retcode, data: res } = data;
|
| 76 |
if (retcode === 0) {
|
|
|
|
| 77 |
yield put({
|
| 78 |
type: 'updateState',
|
| 79 |
payload: {
|
| 80 |
data: res.chunks,
|
| 81 |
total: res.total,
|
| 82 |
+
documentInfo: res.doc,
|
| 83 |
},
|
| 84 |
});
|
| 85 |
}
|
| 86 |
},
|
| 87 |
*switch_chunk({ payload = {} }, { call, put }) {
|
| 88 |
+
const { data } = yield call(kbService.switch_chunk, payload);
|
| 89 |
+
const { retcode } = data;
|
| 90 |
+
if (retcode === 0) {
|
| 91 |
+
message.success('Modified successfully !');
|
| 92 |
+
}
|
| 93 |
return retcode;
|
| 94 |
},
|
| 95 |
*rm_chunk({ payload = {} }, { call, put }) {
|
web/src/pages/add-knowledge/components/knowledge-file/model.ts
CHANGED
|
@@ -16,7 +16,6 @@ export interface KFModelState extends BaseState {
|
|
| 16 |
data: IKnowledgeFile[];
|
| 17 |
total: number;
|
| 18 |
currentRecord: Nullable<IKnowledgeFile>;
|
| 19 |
-
searchString: string;
|
| 20 |
}
|
| 21 |
|
| 22 |
const model: DvaModel<KFModelState> = {
|
|
|
|
| 16 |
data: IKnowledgeFile[];
|
| 17 |
total: number;
|
| 18 |
currentRecord: Nullable<IKnowledgeFile>;
|
|
|
|
| 19 |
}
|
| 20 |
|
| 21 |
const model: DvaModel<KFModelState> = {
|
web/src/pages/knowledge/knowledge-card/index.tsx
CHANGED
|
@@ -9,7 +9,6 @@ import {
|
|
| 9 |
UserOutlined,
|
| 10 |
} from '@ant-design/icons';
|
| 11 |
import { Avatar, Card, Dropdown, MenuProps, Space } from 'antd';
|
| 12 |
-
import { MouseEvent } from 'react';
|
| 13 |
import { useDispatch, useNavigate } from 'umi';
|
| 14 |
|
| 15 |
import showDeleteConfirm from '@/components/deleting-confirm';
|
|
@@ -23,6 +22,15 @@ const KnowledgeCard = ({ item }: IProps) => {
|
|
| 23 |
const navigate = useNavigate();
|
| 24 |
const dispatch = useDispatch();
|
| 25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
const handleDelete = () => {
|
| 27 |
showDeleteConfirm({ onOk: removeKnowledge });
|
| 28 |
};
|
|
@@ -47,16 +55,7 @@ const KnowledgeCard = ({ item }: IProps) => {
|
|
| 47 |
}
|
| 48 |
};
|
| 49 |
|
| 50 |
-
const
|
| 51 |
-
return dispatch({
|
| 52 |
-
type: 'knowledgeModel/rmKb',
|
| 53 |
-
payload: {
|
| 54 |
-
kb_id: item.id,
|
| 55 |
-
},
|
| 56 |
-
});
|
| 57 |
-
};
|
| 58 |
-
|
| 59 |
-
const handleCardClick = (e: MouseEvent<HTMLElement>) => {
|
| 60 |
navigate(`/knowledge/${KnowledgeRouteKey.Dataset}?id=${item.id}`);
|
| 61 |
};
|
| 62 |
|
|
|
|
| 9 |
UserOutlined,
|
| 10 |
} from '@ant-design/icons';
|
| 11 |
import { Avatar, Card, Dropdown, MenuProps, Space } from 'antd';
|
|
|
|
| 12 |
import { useDispatch, useNavigate } from 'umi';
|
| 13 |
|
| 14 |
import showDeleteConfirm from '@/components/deleting-confirm';
|
|
|
|
| 22 |
const navigate = useNavigate();
|
| 23 |
const dispatch = useDispatch();
|
| 24 |
|
| 25 |
+
const removeKnowledge = () => {
|
| 26 |
+
return dispatch({
|
| 27 |
+
type: 'knowledgeModel/rmKb',
|
| 28 |
+
payload: {
|
| 29 |
+
kb_id: item.id,
|
| 30 |
+
},
|
| 31 |
+
});
|
| 32 |
+
};
|
| 33 |
+
|
| 34 |
const handleDelete = () => {
|
| 35 |
showDeleteConfirm({ onOk: removeKnowledge });
|
| 36 |
};
|
|
|
|
| 55 |
}
|
| 56 |
};
|
| 57 |
|
| 58 |
+
const handleCardClick = () => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
navigate(`/knowledge/${KnowledgeRouteKey.Dataset}?id=${item.id}`);
|
| 60 |
};
|
| 61 |
|
web/src/utils/storeUtil.ts
CHANGED
|
@@ -7,3 +7,8 @@ export const getOneNamespaceEffectsLoading = (
|
|
| 7 |
(effectName) => effects[`${namespace}/${effectName}`],
|
| 8 |
);
|
| 9 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
(effectName) => effects[`${namespace}/${effectName}`],
|
| 8 |
);
|
| 9 |
};
|
| 10 |
+
|
| 11 |
+
export const delay = (ms: number) =>
|
| 12 |
+
new Promise((resolve) => {
|
| 13 |
+
setTimeout(resolve, ms);
|
| 14 |
+
});
|