balibabu
commited on
Commit
·
3054c20
1
Parent(s):
64a0633
feat: locate the specific location of the document based on the coordinates of the chunk and add Upload to AssistantSetting (#92)
Browse files* feat: add Upload to AssistantSetting
* feat: locate the specific location of the document based on the coordinates of the chunk
- web/src/interfaces/database/knowledge.ts +1 -0
- web/src/less/variable.less +2 -0
- web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.less +22 -0
- web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.tsx +1 -3
- web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/hightlights.ts +68 -12
- web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/index.less +4 -1
- web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/preview.tsx +30 -27
- web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts +45 -2
- web/src/pages/add-knowledge/components/knowledge-file/index.tsx +13 -9
- web/src/pages/chat/chat-configuration-modal/assistant-setting.tsx +25 -3
- web/src/pages/chat/chat-configuration-modal/index.tsx +17 -2
- web/src/pages/chat/index.tsx +3 -2
web/src/interfaces/database/knowledge.ts
CHANGED
@@ -74,6 +74,7 @@ export interface IChunk {
|
|
74 |
docnm_kwd: string;
|
75 |
img_id: string;
|
76 |
important_kwd: any[];
|
|
|
77 |
}
|
78 |
|
79 |
export interface ITestingChunk {
|
|
|
74 |
docnm_kwd: string;
|
75 |
img_id: string;
|
76 |
important_kwd: any[];
|
77 |
+
positions: number[][];
|
78 |
}
|
79 |
|
80 |
export interface ITestingChunk {
|
web/src/less/variable.less
CHANGED
@@ -8,6 +8,8 @@
|
|
8 |
@gray11: rgba(232, 232, 234, 1);
|
9 |
@purple: rgba(127, 86, 217, 1);
|
10 |
@selectedBackgroundColor: rgba(239, 248, 255, 1);
|
|
|
|
|
11 |
|
12 |
@fontSize12: 12px;
|
13 |
@fontSize14: 14px;
|
|
|
8 |
@gray11: rgba(232, 232, 234, 1);
|
9 |
@purple: rgba(127, 86, 217, 1);
|
10 |
@selectedBackgroundColor: rgba(239, 248, 255, 1);
|
11 |
+
@blurBackground: rgba(22, 119, 255, 0.5);
|
12 |
+
@blurBackgroundHover: rgba(22, 119, 255, 0.2);
|
13 |
|
14 |
@fontSize12: 12px;
|
15 |
@fontSize14: 14px;
|
web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.less
CHANGED
@@ -13,6 +13,28 @@
|
|
13 |
color: red;
|
14 |
font-style: normal;
|
15 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
}
|
17 |
|
18 |
.cardSelected {
|
|
|
13 |
color: red;
|
14 |
font-style: normal;
|
15 |
}
|
16 |
+
|
17 |
+
caption {
|
18 |
+
color: @blurBackground;
|
19 |
+
font-size: 20px;
|
20 |
+
height: 50px;
|
21 |
+
line-height: 50px;
|
22 |
+
font-weight: 600;
|
23 |
+
margin-bottom: 10px;
|
24 |
+
}
|
25 |
+
|
26 |
+
th {
|
27 |
+
color: #fff;
|
28 |
+
background-color: @blurBackground;
|
29 |
+
}
|
30 |
+
|
31 |
+
td:hover {
|
32 |
+
background: @blurBackgroundHover;
|
33 |
+
}
|
34 |
+
|
35 |
+
tr:nth-child(even) {
|
36 |
+
background-color: #f2f2f2;
|
37 |
+
}
|
38 |
}
|
39 |
|
40 |
.cardSelected {
|
web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-card/index.tsx
CHANGED
@@ -64,9 +64,7 @@ const ChunkCard = ({
|
|
64 |
onClick={handleContentClick}
|
65 |
className={styles.content}
|
66 |
dangerouslySetInnerHTML={{ __html: item.content_with_weight }}
|
67 |
-
>
|
68 |
-
{/* {item.content_with_weight} */}
|
69 |
-
</section>
|
70 |
<div>
|
71 |
<Switch checked={enabled} onChange={onChange} />
|
72 |
</div>
|
|
|
64 |
onClick={handleContentClick}
|
65 |
className={styles.content}
|
66 |
dangerouslySetInnerHTML={{ __html: item.content_with_weight }}
|
67 |
+
></section>
|
|
|
|
|
68 |
<div>
|
69 |
<Switch checked={enabled} onChange={onChange} />
|
70 |
</div>
|
web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/hightlights.ts
CHANGED
@@ -6,21 +6,27 @@ export const testHighlights = [
|
|
6 |
position: {
|
7 |
boundingRect: {
|
8 |
x1: 219.7,
|
|
|
9 |
y1: 204.3,
|
|
|
10 |
x2: 547.0,
|
|
|
11 |
y2: 264.0,
|
12 |
-
|
13 |
-
height: 1200,
|
14 |
},
|
15 |
rects: [
|
16 |
-
{
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
24 |
],
|
25 |
pageNumber: 9,
|
26 |
},
|
@@ -28,6 +34,56 @@ export const testHighlights = [
|
|
28 |
text: 'Flow or TypeScript?',
|
29 |
emoji: '🔥',
|
30 |
},
|
31 |
-
id: '
|
32 |
},
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
position: {
|
7 |
boundingRect: {
|
8 |
x1: 219.7,
|
9 |
+
// x1: 419.7,
|
10 |
y1: 204.3,
|
11 |
+
// y1: 304.3,
|
12 |
x2: 547.0,
|
13 |
+
// x2: 747.0,
|
14 |
y2: 264.0,
|
15 |
+
// y2: 364.0,
|
|
|
16 |
},
|
17 |
rects: [
|
18 |
+
// {
|
19 |
+
// x1: 219.7,
|
20 |
+
// // x1: 419.7,
|
21 |
+
// y1: 204.3,
|
22 |
+
// // y1: 304.3,
|
23 |
+
// x2: 547.0,
|
24 |
+
// // x2: 747.0,
|
25 |
+
// y2: 264.0,
|
26 |
+
// // y2: 364.0,
|
27 |
+
// width: 849,
|
28 |
+
// height: 1200,
|
29 |
+
// },
|
30 |
],
|
31 |
pageNumber: 9,
|
32 |
},
|
|
|
34 |
text: 'Flow or TypeScript?',
|
35 |
emoji: '🔥',
|
36 |
},
|
37 |
+
id: 'jsdlihdkghergjl',
|
38 |
},
|
39 |
+
{
|
40 |
+
content: {
|
41 |
+
text: '图2:乘联会预计6 月新能源乘用车厂商批发销量74 万辆,环比增长10%,同比增长30%。',
|
42 |
+
},
|
43 |
+
position: {
|
44 |
+
boundingRect: {
|
45 |
+
x1: 219.0,
|
46 |
+
x2: 546.0,
|
47 |
+
y1: 616.0,
|
48 |
+
y2: 674.7,
|
49 |
+
},
|
50 |
+
rects: [],
|
51 |
+
pageNumber: 6,
|
52 |
+
},
|
53 |
+
comment: {
|
54 |
+
text: 'Flow or TypeScript?',
|
55 |
+
emoji: '🔥',
|
56 |
+
},
|
57 |
+
id: 'bfdbtymkhjildbfghserrgrt',
|
58 |
+
},
|
59 |
+
{
|
60 |
+
content: {
|
61 |
+
text: '图2:乘联会预计6 月新能源乘用车厂商批发销量74 万辆,环比增长10%,同比增长30%。',
|
62 |
+
},
|
63 |
+
position: {
|
64 |
+
boundingRect: {
|
65 |
+
x1: 73.7,
|
66 |
+
x2: 391.7,
|
67 |
+
y1: 570.3,
|
68 |
+
y2: 676.3,
|
69 |
+
},
|
70 |
+
rects: [],
|
71 |
+
pageNumber: 1,
|
72 |
+
},
|
73 |
+
comment: {
|
74 |
+
text: '',
|
75 |
+
emoji: '',
|
76 |
+
},
|
77 |
+
id: 'fgnhxdvsesgmghyu',
|
78 |
+
},
|
79 |
+
].map((x) => {
|
80 |
+
const boundingRect = x.position.boundingRect;
|
81 |
+
const ret: any = {
|
82 |
+
width: 849,
|
83 |
+
height: 1200,
|
84 |
+
};
|
85 |
+
Object.entries(boundingRect).forEach(([key, value]) => {
|
86 |
+
ret[key] = value / 0.7;
|
87 |
+
});
|
88 |
+
return { ...x, position: { ...x.position, boundingRect: ret, rects: [ret] } };
|
89 |
+
});
|
web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/index.less
CHANGED
@@ -6,6 +6,9 @@
|
|
6 |
position: relative;
|
7 |
:global(.PdfHighlighter) {
|
8 |
overflow-x: hidden;
|
9 |
-
|
|
|
|
|
|
|
10 |
}
|
11 |
}
|
|
|
6 |
position: relative;
|
7 |
:global(.PdfHighlighter) {
|
8 |
overflow-x: hidden;
|
9 |
+
}
|
10 |
+
:global(.Highlight--scrolledTo .Highlight__part) {
|
11 |
+
overflow-x: hidden;
|
12 |
+
background-color: rgba(255, 226, 143, 1);
|
13 |
}
|
14 |
}
|
web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/preview.tsx
CHANGED
@@ -1,16 +1,15 @@
|
|
1 |
import { Spin } from 'antd';
|
2 |
-
import {
|
3 |
-
import type { NewHighlight } from 'react-pdf-highlighter';
|
4 |
import {
|
5 |
AreaHighlight,
|
6 |
Highlight,
|
|
|
7 |
PdfHighlighter,
|
8 |
PdfLoader,
|
9 |
Popup,
|
10 |
Tip,
|
11 |
} from 'react-pdf-highlighter';
|
12 |
-
import { useGetSelectedChunk } from '../../hooks';
|
13 |
-
import { testHighlights } from './hightlights';
|
14 |
import { useGetDocumentUrl } from './hooks';
|
15 |
|
16 |
import styles from './index.less';
|
@@ -36,7 +35,9 @@ const Preview = ({ selectedChunkId }: IProps) => {
|
|
36 |
const url = useGetDocumentUrl();
|
37 |
const selectedChunk = useGetSelectedChunk(selectedChunkId);
|
38 |
|
39 |
-
const [state, setState] = useState<any>(testHighlights);
|
|
|
|
|
40 |
const ref = useRef((highlight: any) => {});
|
41 |
|
42 |
const parseIdFromHash = () =>
|
@@ -67,7 +68,7 @@ const Preview = ({ selectedChunkId }: IProps) => {
|
|
67 |
|
68 |
console.log('Saving highlight', highlight);
|
69 |
|
70 |
-
setState([{ ...highlight, id: getNextId() }, ...highlights]);
|
71 |
};
|
72 |
|
73 |
const updateHighlight = (
|
@@ -77,29 +78,31 @@ const Preview = ({ selectedChunkId }: IProps) => {
|
|
77 |
) => {
|
78 |
console.log('Updating highlight', highlightId, position, content);
|
79 |
|
80 |
-
setState(
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
);
|
98 |
};
|
99 |
|
100 |
-
|
101 |
-
|
102 |
-
|
|
|
|
|
103 |
|
104 |
return (
|
105 |
<div className={styles.documentContainer}>
|
|
|
1 |
import { Spin } from 'antd';
|
2 |
+
import { useEffect, useRef } from 'react';
|
|
|
3 |
import {
|
4 |
AreaHighlight,
|
5 |
Highlight,
|
6 |
+
NewHighlight,
|
7 |
PdfHighlighter,
|
8 |
PdfLoader,
|
9 |
Popup,
|
10 |
Tip,
|
11 |
} from 'react-pdf-highlighter';
|
12 |
+
import { useGetChunkHighlights, useGetSelectedChunk } from '../../hooks';
|
|
|
13 |
import { useGetDocumentUrl } from './hooks';
|
14 |
|
15 |
import styles from './index.less';
|
|
|
35 |
const url = useGetDocumentUrl();
|
36 |
const selectedChunk = useGetSelectedChunk(selectedChunkId);
|
37 |
|
38 |
+
// const [state, setState] = useState<any>(testHighlights);
|
39 |
+
const state = useGetChunkHighlights(selectedChunkId);
|
40 |
+
|
41 |
const ref = useRef((highlight: any) => {});
|
42 |
|
43 |
const parseIdFromHash = () =>
|
|
|
68 |
|
69 |
console.log('Saving highlight', highlight);
|
70 |
|
71 |
+
// setState([{ ...highlight, id: getNextId() }, ...highlights]);
|
72 |
};
|
73 |
|
74 |
const updateHighlight = (
|
|
|
78 |
) => {
|
79 |
console.log('Updating highlight', highlightId, position, content);
|
80 |
|
81 |
+
// setState(
|
82 |
+
// state.map((h: any) => {
|
83 |
+
// const {
|
84 |
+
// id,
|
85 |
+
// position: originalPosition,
|
86 |
+
// content: originalContent,
|
87 |
+
// ...rest
|
88 |
+
// } = h;
|
89 |
+
// return id === highlightId
|
90 |
+
// ? {
|
91 |
+
// id,
|
92 |
+
// position: { ...originalPosition, ...position },
|
93 |
+
// content: { ...originalContent, ...content },
|
94 |
+
// ...rest,
|
95 |
+
// }
|
96 |
+
// : h;
|
97 |
+
// }),
|
98 |
+
// );
|
99 |
};
|
100 |
|
101 |
+
useEffect(() => {
|
102 |
+
if (state.length > 0) {
|
103 |
+
ref.current(state[0]);
|
104 |
+
}
|
105 |
+
}, [state]);
|
106 |
|
107 |
return (
|
108 |
<div className={styles.documentContainer}>
|
web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts
CHANGED
@@ -1,6 +1,8 @@
|
|
1 |
import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge';
|
2 |
-
import { useCallback, useState } from 'react';
|
|
|
3 |
import { useSelector } from 'umi';
|
|
|
4 |
|
5 |
export const useSelectDocumentInfo = () => {
|
6 |
const documentInfo: IKnowledgeFile = useSelector(
|
@@ -28,5 +30,46 @@ export const useHandleChunkCardClick = () => {
|
|
28 |
|
29 |
export const useGetSelectedChunk = (selectedChunkId: string) => {
|
30 |
const chunkList: IChunk[] = useSelectChunkList();
|
31 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
};
|
|
|
1 |
import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge';
|
2 |
+
import { useCallback, useMemo, useState } from 'react';
|
3 |
+
import { IHighlight } from 'react-pdf-highlighter';
|
4 |
import { useSelector } from 'umi';
|
5 |
+
import { v4 as uuid } from 'uuid';
|
6 |
|
7 |
export const useSelectDocumentInfo = () => {
|
8 |
const documentInfo: IKnowledgeFile = useSelector(
|
|
|
30 |
|
31 |
export const useGetSelectedChunk = (selectedChunkId: string) => {
|
32 |
const chunkList: IChunk[] = useSelectChunkList();
|
33 |
+
return (
|
34 |
+
chunkList.find((x) => x.chunk_id === selectedChunkId) ?? ({} as IChunk)
|
35 |
+
);
|
36 |
+
};
|
37 |
+
|
38 |
+
export const useGetChunkHighlights = (
|
39 |
+
selectedChunkId: string,
|
40 |
+
): IHighlight[] => {
|
41 |
+
const selectedChunk: IChunk = useGetSelectedChunk(selectedChunkId);
|
42 |
+
|
43 |
+
const highlights: IHighlight[] = useMemo(() => {
|
44 |
+
return Array.isArray(selectedChunk?.positions)
|
45 |
+
? selectedChunk?.positions?.map((x) => {
|
46 |
+
const actualPositions = x.map((y, index) =>
|
47 |
+
index !== 0 ? y / 0.7 : y,
|
48 |
+
);
|
49 |
+
const boundingRect = {
|
50 |
+
width: 849,
|
51 |
+
height: 1200,
|
52 |
+
x1: actualPositions[1],
|
53 |
+
x2: actualPositions[2],
|
54 |
+
y1: actualPositions[3],
|
55 |
+
y2: actualPositions[4],
|
56 |
+
};
|
57 |
+
return {
|
58 |
+
id: uuid(),
|
59 |
+
comment: {
|
60 |
+
text: '',
|
61 |
+
emoji: '',
|
62 |
+
},
|
63 |
+
content: { text: selectedChunk.content_with_weight },
|
64 |
+
position: {
|
65 |
+
boundingRect: boundingRect,
|
66 |
+
rects: [boundingRect],
|
67 |
+
pageNumber: x[0],
|
68 |
+
},
|
69 |
+
};
|
70 |
+
})
|
71 |
+
: [];
|
72 |
+
}, [selectedChunk]);
|
73 |
+
|
74 |
+
return highlights;
|
75 |
};
|
web/src/pages/add-knowledge/components/knowledge-file/index.tsx
CHANGED
@@ -23,7 +23,7 @@ import {
|
|
23 |
import type { ColumnsType } from 'antd/es/table';
|
24 |
import { PaginationProps } from 'antd/lib';
|
25 |
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
26 |
-
import {
|
27 |
import CreateEPModal from './createEFileModal';
|
28 |
import styles from './index.less';
|
29 |
import ParsingActionCell from './parsing-action-cell';
|
@@ -144,19 +144,22 @@ const KnowledgeFile = () => {
|
|
144 |
});
|
145 |
}, [dispatch]);
|
146 |
|
|
|
|
|
|
|
|
|
147 |
const actionItems: MenuProps['items'] = useMemo(() => {
|
148 |
return [
|
149 |
{
|
150 |
key: '1',
|
|
|
151 |
label: (
|
152 |
<div>
|
153 |
<Button type="link">
|
154 |
-
<
|
155 |
-
<
|
156 |
-
|
157 |
-
|
158 |
-
</Space>
|
159 |
-
</Link>
|
160 |
</Button>
|
161 |
</div>
|
162 |
),
|
@@ -164,9 +167,10 @@ const KnowledgeFile = () => {
|
|
164 |
{ type: 'divider' },
|
165 |
{
|
166 |
key: '2',
|
|
|
167 |
label: (
|
168 |
<div>
|
169 |
-
<Button type="link"
|
170 |
<FileOutlined />
|
171 |
Create empty file
|
172 |
</Button>
|
@@ -175,7 +179,7 @@ const KnowledgeFile = () => {
|
|
175 |
// disabled: true,
|
176 |
},
|
177 |
];
|
178 |
-
}, [
|
179 |
|
180 |
const toChunk = (id: string) => {
|
181 |
navigate(
|
|
|
23 |
import type { ColumnsType } from 'antd/es/table';
|
24 |
import { PaginationProps } from 'antd/lib';
|
25 |
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
26 |
+
import { useDispatch, useNavigate, useSelector } from 'umi';
|
27 |
import CreateEPModal from './createEFileModal';
|
28 |
import styles from './index.less';
|
29 |
import ParsingActionCell from './parsing-action-cell';
|
|
|
144 |
});
|
145 |
}, [dispatch]);
|
146 |
|
147 |
+
const linkToUploadPage = useCallback(() => {
|
148 |
+
navigate(`/knowledge/dataset/upload?id=${knowledgeBaseId}`);
|
149 |
+
}, [navigate, knowledgeBaseId]);
|
150 |
+
|
151 |
const actionItems: MenuProps['items'] = useMemo(() => {
|
152 |
return [
|
153 |
{
|
154 |
key: '1',
|
155 |
+
onClick: linkToUploadPage,
|
156 |
label: (
|
157 |
<div>
|
158 |
<Button type="link">
|
159 |
+
<Space>
|
160 |
+
<FileTextOutlined />
|
161 |
+
Local files
|
162 |
+
</Space>
|
|
|
|
|
163 |
</Button>
|
164 |
</div>
|
165 |
),
|
|
|
167 |
{ type: 'divider' },
|
168 |
{
|
169 |
key: '2',
|
170 |
+
onClick: showCEFModal,
|
171 |
label: (
|
172 |
<div>
|
173 |
+
<Button type="link">
|
174 |
<FileOutlined />
|
175 |
Create empty file
|
176 |
</Button>
|
|
|
179 |
// disabled: true,
|
180 |
},
|
181 |
];
|
182 |
+
}, [linkToUploadPage, showCEFModal]);
|
183 |
|
184 |
const toChunk = (id: string) => {
|
185 |
navigate(
|
web/src/pages/chat/chat-configuration-modal/assistant-setting.tsx
CHANGED
@@ -1,9 +1,10 @@
|
|
1 |
-
import { Form, Input, Select } from 'antd';
|
2 |
|
3 |
import classNames from 'classnames';
|
4 |
import { ISegmentedContentProps } from '../interface';
|
5 |
|
6 |
import { useFetchKnowledgeList } from '@/hooks/knowledgeHook';
|
|
|
7 |
import styles from './index.less';
|
8 |
|
9 |
const AssistantSetting = ({ show }: ISegmentedContentProps) => {
|
@@ -13,6 +14,13 @@ const AssistantSetting = ({ show }: ISegmentedContentProps) => {
|
|
13 |
value: x.id,
|
14 |
}));
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
return (
|
17 |
<section
|
18 |
className={classNames({
|
@@ -26,8 +34,22 @@ const AssistantSetting = ({ show }: ISegmentedContentProps) => {
|
|
26 |
>
|
27 |
<Input placeholder="e.g. Resume Jarvis" />
|
28 |
</Form.Item>
|
29 |
-
<Form.Item
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
</Form.Item>
|
32 |
<Form.Item name={'language'} label="Language" initialValue={'Chinese'}>
|
33 |
<Select
|
|
|
1 |
+
import { Form, Input, Select, Upload } from 'antd';
|
2 |
|
3 |
import classNames from 'classnames';
|
4 |
import { ISegmentedContentProps } from '../interface';
|
5 |
|
6 |
import { useFetchKnowledgeList } from '@/hooks/knowledgeHook';
|
7 |
+
import { PlusOutlined } from '@ant-design/icons';
|
8 |
import styles from './index.less';
|
9 |
|
10 |
const AssistantSetting = ({ show }: ISegmentedContentProps) => {
|
|
|
14 |
value: x.id,
|
15 |
}));
|
16 |
|
17 |
+
const normFile = (e: any) => {
|
18 |
+
if (Array.isArray(e)) {
|
19 |
+
return e;
|
20 |
+
}
|
21 |
+
return e?.fileList;
|
22 |
+
};
|
23 |
+
|
24 |
return (
|
25 |
<section
|
26 |
className={classNames({
|
|
|
34 |
>
|
35 |
<Input placeholder="e.g. Resume Jarvis" />
|
36 |
</Form.Item>
|
37 |
+
<Form.Item
|
38 |
+
name="icon"
|
39 |
+
label="Assistant avatar"
|
40 |
+
valuePropName="fileList"
|
41 |
+
getValueFromEvent={normFile}
|
42 |
+
>
|
43 |
+
<Upload
|
44 |
+
listType="picture-card"
|
45 |
+
maxCount={1}
|
46 |
+
showUploadList={{ showPreviewIcon: false, showRemoveIcon: false }}
|
47 |
+
>
|
48 |
+
<button style={{ border: 0, background: 'none' }} type="button">
|
49 |
+
<PlusOutlined />
|
50 |
+
<div style={{ marginTop: 8 }}>Upload</div>
|
51 |
+
</button>
|
52 |
+
</Upload>
|
53 |
</Form.Item>
|
54 |
<Form.Item name={'language'} label="Language" initialValue={'Chinese'}>
|
55 |
<Select
|
web/src/pages/chat/chat-configuration-modal/index.tsx
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
import { ReactComponent as ChatConfigurationAtom } from '@/assets/svg/chat-configuration-atom.svg';
|
2 |
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
3 |
-
import { Divider, Flex, Form, Modal, Segmented } from 'antd';
|
4 |
import { SegmentedValue } from 'antd/es/segmented';
|
5 |
import omit from 'lodash/omit';
|
6 |
import { useEffect, useRef, useState } from 'react';
|
@@ -67,6 +67,14 @@ const ChatConfigurationModal = ({ visible, hideModal, id }: IProps) => {
|
|
67 |
...excludeUnEnabledVariables(values),
|
68 |
]);
|
69 |
const emptyResponse = nextValues.prompt_config?.empty_response ?? '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
const finalValues = {
|
71 |
dialog_id: id,
|
72 |
...nextValues,
|
@@ -75,6 +83,7 @@ const ChatConfigurationModal = ({ visible, hideModal, id }: IProps) => {
|
|
75 |
parameters: promptEngineRef.current,
|
76 |
empty_response: emptyResponse,
|
77 |
},
|
|
|
78 |
};
|
79 |
console.info(promptEngineRef.current);
|
80 |
console.info(nextValues);
|
@@ -112,7 +121,13 @@ const ChatConfigurationModal = ({ visible, hideModal, id }: IProps) => {
|
|
112 |
);
|
113 |
|
114 |
useEffect(() => {
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
}, [currentDialog, form]);
|
117 |
|
118 |
return (
|
|
|
1 |
import { ReactComponent as ChatConfigurationAtom } from '@/assets/svg/chat-configuration-atom.svg';
|
2 |
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
3 |
+
import { Divider, Flex, Form, Modal, Segmented, UploadFile } from 'antd';
|
4 |
import { SegmentedValue } from 'antd/es/segmented';
|
5 |
import omit from 'lodash/omit';
|
6 |
import { useEffect, useRef, useState } from 'react';
|
|
|
67 |
...excludeUnEnabledVariables(values),
|
68 |
]);
|
69 |
const emptyResponse = nextValues.prompt_config?.empty_response ?? '';
|
70 |
+
|
71 |
+
const fileList = values.icon;
|
72 |
+
let icon;
|
73 |
+
|
74 |
+
if (Array.isArray(fileList) && fileList.length > 0) {
|
75 |
+
icon = fileList[0].thumbUrl;
|
76 |
+
}
|
77 |
+
|
78 |
const finalValues = {
|
79 |
dialog_id: id,
|
80 |
...nextValues,
|
|
|
83 |
parameters: promptEngineRef.current,
|
84 |
empty_response: emptyResponse,
|
85 |
},
|
86 |
+
icon,
|
87 |
};
|
88 |
console.info(promptEngineRef.current);
|
89 |
console.info(nextValues);
|
|
|
121 |
);
|
122 |
|
123 |
useEffect(() => {
|
124 |
+
const icon = currentDialog.icon;
|
125 |
+
let fileList: UploadFile[] = [];
|
126 |
+
|
127 |
+
if (icon) {
|
128 |
+
fileList = [{ uid: '1', name: 'file', thumbUrl: icon, status: 'done' }];
|
129 |
+
}
|
130 |
+
form.setFieldsValue({ ...currentDialog, icon: fileList });
|
131 |
}, [currentDialog, form]);
|
132 |
|
133 |
return (
|
web/src/pages/chat/index.tsx
CHANGED
@@ -2,6 +2,7 @@ import { ReactComponent as ChatAppCube } from '@/assets/svg/chat-app-cube.svg';
|
|
2 |
import { useSetModalState } from '@/hooks/commonHooks';
|
3 |
import { DeleteOutlined, EditOutlined, FormOutlined } from '@ant-design/icons';
|
4 |
import {
|
|
|
5 |
Button,
|
6 |
Card,
|
7 |
Divider,
|
@@ -208,8 +209,8 @@ const Chat = () => {
|
|
208 |
onClick={handleDialogCardClick(x.id)}
|
209 |
>
|
210 |
<Flex justify="space-between" align="center">
|
211 |
-
<Space>
|
212 |
-
{x.icon}
|
213 |
<section>
|
214 |
<b>{x.name}</b>
|
215 |
<div>{x.description}</div>
|
|
|
2 |
import { useSetModalState } from '@/hooks/commonHooks';
|
3 |
import { DeleteOutlined, EditOutlined, FormOutlined } from '@ant-design/icons';
|
4 |
import {
|
5 |
+
Avatar,
|
6 |
Button,
|
7 |
Card,
|
8 |
Divider,
|
|
|
209 |
onClick={handleDialogCardClick(x.id)}
|
210 |
>
|
211 |
<Flex justify="space-between" align="center">
|
212 |
+
<Space size={15}>
|
213 |
+
<Avatar src={x.icon} shape={'square'} />
|
214 |
<section>
|
215 |
<b>{x.name}</b>
|
216 |
<div>{x.description}</div>
|