balibabu
commited on
Commit
·
5e72d47
1
Parent(s):
82bdd9f
feat: Catching errors with IndentedTree #2247 (#2380)
Browse files### What problem does this PR solve?
feat: Catching errors with IndentedTree #2247
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- web/package-lock.json +12 -0
- web/package.json +1 -0
- web/src/components/indented-tree/indented-tree.tsx +24 -10
- web/src/hooks/chat-hooks.ts +1 -1
- web/src/pages/search/index.less +17 -7
- web/src/pages/search/index.tsx +15 -4
web/package-lock.json
CHANGED
@@ -31,6 +31,7 @@
|
|
31 |
"openai-speech-stream-player": "^1.0.8",
|
32 |
"rc-tween-one": "^3.0.6",
|
33 |
"react-copy-to-clipboard": "^5.1.0",
|
|
|
34 |
"react-force-graph": "^1.44.4",
|
35 |
"react-i18next": "^14.0.0",
|
36 |
"react-markdown": "^9.0.1",
|
@@ -23119,6 +23120,17 @@
|
|
23119 |
"node": ">=6"
|
23120 |
}
|
23121 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23122 |
"node_modules/react-error-overlay": {
|
23123 |
"version": "6.0.9",
|
23124 |
"resolved": "https://registry.npmmirror.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
|
|
|
31 |
"openai-speech-stream-player": "^1.0.8",
|
32 |
"rc-tween-one": "^3.0.6",
|
33 |
"react-copy-to-clipboard": "^5.1.0",
|
34 |
+
"react-error-boundary": "^4.0.13",
|
35 |
"react-force-graph": "^1.44.4",
|
36 |
"react-i18next": "^14.0.0",
|
37 |
"react-markdown": "^9.0.1",
|
|
|
23120 |
"node": ">=6"
|
23121 |
}
|
23122 |
},
|
23123 |
+
"node_modules/react-error-boundary": {
|
23124 |
+
"version": "4.0.13",
|
23125 |
+
"resolved": "https://registry.npmmirror.com/react-error-boundary/-/react-error-boundary-4.0.13.tgz",
|
23126 |
+
"integrity": "sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==",
|
23127 |
+
"dependencies": {
|
23128 |
+
"@babel/runtime": "^7.12.5"
|
23129 |
+
},
|
23130 |
+
"peerDependencies": {
|
23131 |
+
"react": ">=16.13.1"
|
23132 |
+
}
|
23133 |
+
},
|
23134 |
"node_modules/react-error-overlay": {
|
23135 |
"version": "6.0.9",
|
23136 |
"resolved": "https://registry.npmmirror.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
|
web/package.json
CHANGED
@@ -42,6 +42,7 @@
|
|
42 |
"openai-speech-stream-player": "^1.0.8",
|
43 |
"rc-tween-one": "^3.0.6",
|
44 |
"react-copy-to-clipboard": "^5.1.0",
|
|
|
45 |
"react-force-graph": "^1.44.4",
|
46 |
"react-i18next": "^14.0.0",
|
47 |
"react-markdown": "^9.0.1",
|
|
|
42 |
"openai-speech-stream-player": "^1.0.8",
|
43 |
"rc-tween-one": "^3.0.6",
|
44 |
"react-copy-to-clipboard": "^5.1.0",
|
45 |
+
"react-error-boundary": "^4.0.13",
|
46 |
"react-force-graph": "^1.44.4",
|
47 |
"react-i18next": "^14.0.0",
|
48 |
"react-markdown": "^9.0.1",
|
web/src/components/indented-tree/indented-tree.tsx
CHANGED
@@ -17,6 +17,7 @@ import {
|
|
17 |
import { TreeData } from '@antv/g6/lib/types';
|
18 |
import isEmpty from 'lodash/isEmpty';
|
19 |
import React, { useCallback, useEffect, useRef } from 'react';
|
|
|
20 |
|
21 |
const rootId = 'root';
|
22 |
|
@@ -297,6 +298,17 @@ interface IProps {
|
|
297 |
style?: React.CSSProperties;
|
298 |
}
|
299 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
const IndentedTree = ({ data, show, style = {} }: IProps) => {
|
301 |
const containerRef = useRef<HTMLDivElement>(null);
|
302 |
const graphRef = useRef<Graph | null>(null);
|
@@ -382,16 +394,18 @@ const IndentedTree = ({ data, show, style = {} }: IProps) => {
|
|
382 |
}, [render, data]);
|
383 |
|
384 |
return (
|
385 |
-
<
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
|
|
|
|
395 |
);
|
396 |
};
|
397 |
|
|
|
17 |
import { TreeData } from '@antv/g6/lib/types';
|
18 |
import isEmpty from 'lodash/isEmpty';
|
19 |
import React, { useCallback, useEffect, useRef } from 'react';
|
20 |
+
import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
|
21 |
|
22 |
const rootId = 'root';
|
23 |
|
|
|
298 |
style?: React.CSSProperties;
|
299 |
}
|
300 |
|
301 |
+
function fallbackRender({ error }: FallbackProps) {
|
302 |
+
// Call resetErrorBoundary() to reset the error boundary and retry the render.
|
303 |
+
|
304 |
+
return (
|
305 |
+
<div role="alert">
|
306 |
+
<p>Something went wrong:</p>
|
307 |
+
<pre style={{ color: 'red' }}>{error.message}</pre>
|
308 |
+
</div>
|
309 |
+
);
|
310 |
+
}
|
311 |
+
|
312 |
const IndentedTree = ({ data, show, style = {} }: IProps) => {
|
313 |
const containerRef = useRef<HTMLDivElement>(null);
|
314 |
const graphRef = useRef<Graph | null>(null);
|
|
|
394 |
}, [render, data]);
|
395 |
|
396 |
return (
|
397 |
+
<ErrorBoundary fallbackRender={fallbackRender}>
|
398 |
+
<div
|
399 |
+
id="tree"
|
400 |
+
ref={containerRef}
|
401 |
+
style={{
|
402 |
+
width: '90vw',
|
403 |
+
height: '80vh',
|
404 |
+
display: show ? 'block' : 'none',
|
405 |
+
...style,
|
406 |
+
}}
|
407 |
+
/>
|
408 |
+
</ErrorBoundary>
|
409 |
);
|
410 |
};
|
411 |
|
web/src/hooks/chat-hooks.ts
CHANGED
@@ -494,7 +494,7 @@ export const useFetchMindMap = () => {
|
|
494 |
mutationFn: async (params: IAskRequestBody) => {
|
495 |
try {
|
496 |
const ret = await chatService.getMindMap(params);
|
497 |
-
return ret?.data?.data ??
|
498 |
} catch (error) {
|
499 |
if (has(error, 'message')) {
|
500 |
message.error(error.message);
|
|
|
494 |
mutationFn: async (params: IAskRequestBody) => {
|
495 |
try {
|
496 |
const ret = await chatService.getMindMap(params);
|
497 |
+
return ret?.data?.data ?? {};
|
498 |
} catch (error) {
|
499 |
if (has(error, 'message')) {
|
500 |
message.error(error.message);
|
web/src/pages/search/index.less
CHANGED
@@ -57,15 +57,22 @@
|
|
57 |
|
58 |
.content {
|
59 |
height: 100%;
|
60 |
-
.
|
61 |
-
|
62 |
-
|
|
|
|
|
63 |
overflow: auto;
|
64 |
padding: 20px 10px 10px;
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
69 |
}
|
70 |
|
71 |
.graph {
|
@@ -111,6 +118,9 @@
|
|
111 |
}
|
112 |
.partialInput {
|
113 |
width: 100%;
|
|
|
|
|
|
|
114 |
.input();
|
115 |
}
|
116 |
|
|
|
57 |
|
58 |
.content {
|
59 |
height: 100%;
|
60 |
+
.hide {
|
61 |
+
display: none;
|
62 |
+
}
|
63 |
+
|
64 |
+
.mainMixin() {
|
65 |
overflow: auto;
|
66 |
padding: 20px 10px 10px;
|
67 |
+
}
|
68 |
+
|
69 |
+
.largeMain {
|
70 |
+
width: 100%;
|
71 |
+
.mainMixin();
|
72 |
+
}
|
73 |
+
.main {
|
74 |
+
width: 60%;
|
75 |
+
.mainMixin();
|
76 |
}
|
77 |
|
78 |
.graph {
|
|
|
118 |
}
|
119 |
.partialInput {
|
120 |
width: 100%;
|
121 |
+
position: sticky;
|
122 |
+
top: 0;
|
123 |
+
z-index: 1;
|
124 |
.input();
|
125 |
}
|
126 |
|
web/src/pages/search/index.tsx
CHANGED
@@ -20,7 +20,7 @@ import {
|
|
20 |
Space,
|
21 |
Tag,
|
22 |
} from 'antd';
|
23 |
-
import { useState } from 'react';
|
24 |
import { useTranslation } from 'react-i18next';
|
25 |
import MarkdownContent from '../chat/markdown-content';
|
26 |
import { useFetchBackgroundImage, useSendQuestion } from './hooks';
|
@@ -35,7 +35,6 @@ const SearchPage = () => {
|
|
35 |
const { t } = useTranslation();
|
36 |
const [checkedList, setCheckedList] = useState<string[]>([]);
|
37 |
const { chunks, total } = useSelectTestingResult();
|
38 |
-
// const appConf = useFetchAppConf();
|
39 |
const {
|
40 |
sendQuestion,
|
41 |
handleClickRelatedQuestion,
|
@@ -62,6 +61,14 @@ const SearchPage = () => {
|
|
62 |
handleTestChunk(selectedDocumentIds, pageNumber, pageSize);
|
63 |
};
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
const InputSearch = (
|
66 |
<Search
|
67 |
value={searchStr}
|
@@ -103,7 +110,9 @@ const SearchPage = () => {
|
|
103 |
</Flex>
|
104 |
) : (
|
105 |
<Flex className={styles.content}>
|
106 |
-
<section
|
|
|
|
|
107 |
{InputSearch}
|
108 |
{answer.answer && (
|
109 |
<div className={styles.answerWrapper}>
|
@@ -165,7 +174,9 @@ const SearchPage = () => {
|
|
165 |
onChange={onChange}
|
166 |
/>
|
167 |
</section>
|
168 |
-
<section
|
|
|
|
|
169 |
{mindMapLoading ? (
|
170 |
<Skeleton active />
|
171 |
) : (
|
|
|
20 |
Space,
|
21 |
Tag,
|
22 |
} from 'antd';
|
23 |
+
import { useMemo, useState } from 'react';
|
24 |
import { useTranslation } from 'react-i18next';
|
25 |
import MarkdownContent from '../chat/markdown-content';
|
26 |
import { useFetchBackgroundImage, useSendQuestion } from './hooks';
|
|
|
35 |
const { t } = useTranslation();
|
36 |
const [checkedList, setCheckedList] = useState<string[]>([]);
|
37 |
const { chunks, total } = useSelectTestingResult();
|
|
|
38 |
const {
|
39 |
sendQuestion,
|
40 |
handleClickRelatedQuestion,
|
|
|
61 |
handleTestChunk(selectedDocumentIds, pageNumber, pageSize);
|
62 |
};
|
63 |
|
64 |
+
const isMindMapEmpty = useMemo(() => {
|
65 |
+
return (
|
66 |
+
!mindMapLoading &&
|
67 |
+
((Array.isArray(mindMap?.children) && mindMap.children.length === 0) ||
|
68 |
+
!Array.isArray(mindMap?.children))
|
69 |
+
);
|
70 |
+
}, [mindMap, mindMapLoading]);
|
71 |
+
|
72 |
const InputSearch = (
|
73 |
<Search
|
74 |
value={searchStr}
|
|
|
110 |
</Flex>
|
111 |
) : (
|
112 |
<Flex className={styles.content}>
|
113 |
+
<section
|
114 |
+
className={isMindMapEmpty ? styles.largeMain : styles.main}
|
115 |
+
>
|
116 |
{InputSearch}
|
117 |
{answer.answer && (
|
118 |
<div className={styles.answerWrapper}>
|
|
|
174 |
onChange={onChange}
|
175 |
/>
|
176 |
</section>
|
177 |
+
<section
|
178 |
+
className={isMindMapEmpty ? styles.hide : styles.graph}
|
179 |
+
>
|
180 |
{mindMapLoading ? (
|
181 |
<Skeleton active />
|
182 |
) : (
|