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 |
+
});
|