balibabu
commited on
Commit
·
0109a6b
1
Parent(s):
f511e07
feat: Add component ExecSQL #1739 (#1982)
Browse files### What problem does this PR solve?
feat: Add component ExecSQL #1739
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- web/src/assets/svg/exesql.svg +6 -0
- web/src/components/top-n-item.tsx +3 -2
- web/src/locales/en.ts +9 -0
- web/src/locales/zh-traditional.ts +9 -0
- web/src/locales/zh.ts +9 -0
- web/src/pages/flow/constant.tsx +26 -0
- web/src/pages/flow/exesql-form/index.tsx +61 -0
- web/src/pages/flow/flow-drawer/index.tsx +3 -2
- web/src/pages/flow/generate-form/hooks.ts +6 -1
- web/src/pages/flow/hooks.ts +2 -0
- web/src/pages/user-setting/setting-model/ollama-modal/index.tsx +1 -1
web/src/assets/svg/exesql.svg
ADDED
|
web/src/components/top-n-item.tsx
CHANGED
@@ -7,9 +7,10 @@ type FieldType = {
|
|
7 |
|
8 |
interface IProps {
|
9 |
initialValue?: number;
|
|
|
10 |
}
|
11 |
|
12 |
-
const TopNItem = ({ initialValue = 8 }: IProps) => {
|
13 |
const { t } = useTranslate('chat');
|
14 |
|
15 |
return (
|
@@ -19,7 +20,7 @@ const TopNItem = ({ initialValue = 8 }: IProps) => {
|
|
19 |
initialValue={initialValue}
|
20 |
tooltip={t('topNTip')}
|
21 |
>
|
22 |
-
<Slider max={
|
23 |
</Form.Item>
|
24 |
);
|
25 |
};
|
|
|
7 |
|
8 |
interface IProps {
|
9 |
initialValue?: number;
|
10 |
+
max?: number;
|
11 |
}
|
12 |
|
13 |
+
const TopNItem = ({ initialValue = 8, max = 30 }: IProps) => {
|
14 |
const { t } = useTranslate('chat');
|
15 |
|
16 |
return (
|
|
|
20 |
initialValue={initialValue}
|
21 |
tooltip={t('topNTip')}
|
22 |
>
|
23 |
+
<Slider max={max} />
|
24 |
</Form.Item>
|
25 |
);
|
26 |
};
|
web/src/locales/en.ts
CHANGED
@@ -795,6 +795,15 @@ The above is the content you need to summarize.`,
|
|
795 |
'30d': '30 days',
|
796 |
},
|
797 |
publish: 'API',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
798 |
},
|
799 |
footer: {
|
800 |
profile: 'All rights reserved @ React',
|
|
|
795 |
'30d': '30 days',
|
796 |
},
|
797 |
publish: 'API',
|
798 |
+
exeSQL: 'ExeSQL',
|
799 |
+
exeSQLDescription:
|
800 |
+
'The component queries the results from the corresponding relational database via SQL statements. Supports MySQL, PostgreSQL, MariaDB. ',
|
801 |
+
dbType: 'Database Type',
|
802 |
+
database: 'Database',
|
803 |
+
username: 'Username',
|
804 |
+
host: 'Host',
|
805 |
+
port: 'Port',
|
806 |
+
password: 'Password',
|
807 |
},
|
808 |
footer: {
|
809 |
profile: 'All rights reserved @ React',
|
web/src/locales/zh-traditional.ts
CHANGED
@@ -753,6 +753,15 @@ export default {
|
|
753 |
'30d': '30天',
|
754 |
},
|
755 |
publish: 'API',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
756 |
},
|
757 |
footer: {
|
758 |
profile: '“保留所有權利 @ react”',
|
|
|
753 |
'30d': '30天',
|
754 |
},
|
755 |
publish: 'API',
|
756 |
+
exeSQL: 'ExeSQL',
|
757 |
+
exeSQLDescription:
|
758 |
+
'此元件透過SQL語句從對應的關聯式資料庫中查詢結果。支援 MySQL、PostgreSQL、MariaDB。 ',
|
759 |
+
dbType: '資料庫類型',
|
760 |
+
database: '資料庫',
|
761 |
+
username: '使用者名稱',
|
762 |
+
host: '主機',
|
763 |
+
port: '端口',
|
764 |
+
password: '密碼',
|
765 |
},
|
766 |
footer: {
|
767 |
profile: '“保留所有權利 @ react”',
|
web/src/locales/zh.ts
CHANGED
@@ -771,6 +771,15 @@ export default {
|
|
771 |
'30d': '30天',
|
772 |
},
|
773 |
publish: 'API',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
774 |
},
|
775 |
footer: {
|
776 |
profile: 'All rights reserved @ React',
|
|
|
771 |
'30d': '30天',
|
772 |
},
|
773 |
publish: 'API',
|
774 |
+
exeSQL: 'ExeSQL',
|
775 |
+
exeSQLDescription:
|
776 |
+
'该组件通过SQL语句从相应的关系数据库中查询结果。支持MySQL,PostgreSQL,MariaDB。',
|
777 |
+
dbType: '数据库类型',
|
778 |
+
database: '数据库',
|
779 |
+
username: '用户名',
|
780 |
+
host: '主机',
|
781 |
+
port: '端口',
|
782 |
+
password: '密码',
|
783 |
},
|
784 |
footer: {
|
785 |
profile: 'All rights reserved @ React',
|
web/src/pages/flow/constant.tsx
CHANGED
@@ -4,6 +4,7 @@ import { ReactComponent as BaiduIcon } from '@/assets/svg/baidu.svg';
|
|
4 |
import { ReactComponent as BingIcon } from '@/assets/svg/bing.svg';
|
5 |
import { ReactComponent as DeepLIcon } from '@/assets/svg/deepl.svg';
|
6 |
import { ReactComponent as DuckIcon } from '@/assets/svg/duck.svg';
|
|
|
7 |
import { ReactComponent as GithubIcon } from '@/assets/svg/github.svg';
|
8 |
import { ReactComponent as GoogleScholarIcon } from '@/assets/svg/google-scholar.svg';
|
9 |
import { ReactComponent as GoogleIcon } from '@/assets/svg/google.svg';
|
@@ -31,6 +32,7 @@ import {
|
|
31 |
SendOutlined,
|
32 |
SlidersOutlined,
|
33 |
} from '@ant-design/icons';
|
|
|
34 |
|
35 |
export enum Operator {
|
36 |
Begin = 'Begin',
|
@@ -54,6 +56,7 @@ export enum Operator {
|
|
54 |
GitHub = 'GitHub',
|
55 |
BaiduFanyi = 'BaiduFanyi',
|
56 |
QWeather = 'QWeather',
|
|
|
57 |
}
|
58 |
|
59 |
export const operatorIconMap = {
|
@@ -78,6 +81,7 @@ export const operatorIconMap = {
|
|
78 |
[Operator.GitHub]: GithubIcon,
|
79 |
[Operator.BaiduFanyi]: baiduFanyiIcon,
|
80 |
[Operator.QWeather]: QWeatherIcon,
|
|
|
81 |
};
|
82 |
|
83 |
export const operatorMap = {
|
@@ -165,6 +169,7 @@ export const operatorMap = {
|
|
165 |
[Operator.GitHub]: {},
|
166 |
[Operator.BaiduFanyi]: {},
|
167 |
[Operator.QWeather]: {},
|
|
|
168 |
};
|
169 |
|
170 |
export const componentMenuList = [
|
@@ -228,6 +233,9 @@ export const componentMenuList = [
|
|
228 |
{
|
229 |
name: Operator.QWeather,
|
230 |
},
|
|
|
|
|
|
|
231 |
];
|
232 |
|
233 |
export const initialRetrievalValues = {
|
@@ -354,6 +362,17 @@ export const initialQWeatherValues = {
|
|
354 |
time_period: 'now',
|
355 |
};
|
356 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
357 |
export const CategorizeAnchorPointPositions = [
|
358 |
{ top: 1, right: 34 },
|
359 |
{ top: 8, right: 18 },
|
@@ -422,6 +441,7 @@ export const RestrictedUpstreamMap = {
|
|
422 |
[Operator.GitHub]: [Operator.Begin, Operator.Retrieval],
|
423 |
[Operator.BaiduFanyi]: [Operator.Begin, Operator.Retrieval],
|
424 |
[Operator.QWeather]: [Operator.Begin, Operator.Retrieval],
|
|
|
425 |
};
|
426 |
|
427 |
export const NodeMap = {
|
@@ -446,6 +466,7 @@ export const NodeMap = {
|
|
446 |
[Operator.GitHub]: 'ragNode',
|
447 |
[Operator.BaiduFanyi]: 'ragNode',
|
448 |
[Operator.QWeather]: 'ragNode',
|
|
|
449 |
};
|
450 |
|
451 |
export const LanguageOptions = [
|
@@ -2576,3 +2597,8 @@ export const QWeatherTimePeriodOptions = [
|
|
2576 |
'15d',
|
2577 |
'30d',
|
2578 |
];
|
|
|
|
|
|
|
|
|
|
|
|
4 |
import { ReactComponent as BingIcon } from '@/assets/svg/bing.svg';
|
5 |
import { ReactComponent as DeepLIcon } from '@/assets/svg/deepl.svg';
|
6 |
import { ReactComponent as DuckIcon } from '@/assets/svg/duck.svg';
|
7 |
+
import { ReactComponent as ExeSqlIcon } from '@/assets/svg/exesql.svg';
|
8 |
import { ReactComponent as GithubIcon } from '@/assets/svg/github.svg';
|
9 |
import { ReactComponent as GoogleScholarIcon } from '@/assets/svg/google-scholar.svg';
|
10 |
import { ReactComponent as GoogleIcon } from '@/assets/svg/google.svg';
|
|
|
32 |
SendOutlined,
|
33 |
SlidersOutlined,
|
34 |
} from '@ant-design/icons';
|
35 |
+
import upperFirst from 'lodash/upperFirst';
|
36 |
|
37 |
export enum Operator {
|
38 |
Begin = 'Begin',
|
|
|
56 |
GitHub = 'GitHub',
|
57 |
BaiduFanyi = 'BaiduFanyi',
|
58 |
QWeather = 'QWeather',
|
59 |
+
ExeSQL = 'ExeSQL',
|
60 |
}
|
61 |
|
62 |
export const operatorIconMap = {
|
|
|
81 |
[Operator.GitHub]: GithubIcon,
|
82 |
[Operator.BaiduFanyi]: baiduFanyiIcon,
|
83 |
[Operator.QWeather]: QWeatherIcon,
|
84 |
+
[Operator.ExeSQL]: ExeSqlIcon,
|
85 |
};
|
86 |
|
87 |
export const operatorMap = {
|
|
|
169 |
[Operator.GitHub]: {},
|
170 |
[Operator.BaiduFanyi]: {},
|
171 |
[Operator.QWeather]: {},
|
172 |
+
[Operator.ExeSQL]: {},
|
173 |
};
|
174 |
|
175 |
export const componentMenuList = [
|
|
|
233 |
{
|
234 |
name: Operator.QWeather,
|
235 |
},
|
236 |
+
{
|
237 |
+
name: Operator.ExeSQL,
|
238 |
+
},
|
239 |
];
|
240 |
|
241 |
export const initialRetrievalValues = {
|
|
|
362 |
time_period: 'now',
|
363 |
};
|
364 |
|
365 |
+
export const initialExeSqlValues = {
|
366 |
+
db_type: 'mysql',
|
367 |
+
database: '',
|
368 |
+
username: '',
|
369 |
+
host: '',
|
370 |
+
port: 3306,
|
371 |
+
password: '',
|
372 |
+
loop: 3,
|
373 |
+
top_n: 30,
|
374 |
+
};
|
375 |
+
|
376 |
export const CategorizeAnchorPointPositions = [
|
377 |
{ top: 1, right: 34 },
|
378 |
{ top: 8, right: 18 },
|
|
|
441 |
[Operator.GitHub]: [Operator.Begin, Operator.Retrieval],
|
442 |
[Operator.BaiduFanyi]: [Operator.Begin, Operator.Retrieval],
|
443 |
[Operator.QWeather]: [Operator.Begin, Operator.Retrieval],
|
444 |
+
[Operator.ExeSQL]: [Operator.Begin],
|
445 |
};
|
446 |
|
447 |
export const NodeMap = {
|
|
|
466 |
[Operator.GitHub]: 'ragNode',
|
467 |
[Operator.BaiduFanyi]: 'ragNode',
|
468 |
[Operator.QWeather]: 'ragNode',
|
469 |
+
[Operator.ExeSQL]: 'ragNode',
|
470 |
};
|
471 |
|
472 |
export const LanguageOptions = [
|
|
|
2597 |
'15d',
|
2598 |
'30d',
|
2599 |
];
|
2600 |
+
|
2601 |
+
export const ExeSQLOptions = ['mysql', 'postgresql', 'mariadb'].map((x) => ({
|
2602 |
+
label: upperFirst(x),
|
2603 |
+
value: x,
|
2604 |
+
}));
|
web/src/pages/flow/exesql-form/index.tsx
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import TopNItem from '@/components/top-n-item';
|
2 |
+
import { useTranslate } from '@/hooks/common-hooks';
|
3 |
+
import { Form, Input, InputNumber, Select } from 'antd';
|
4 |
+
import { ExeSQLOptions } from '../constant';
|
5 |
+
import { IOperatorForm } from '../interface';
|
6 |
+
|
7 |
+
const ExeSQLForm = ({ onValuesChange, form }: IOperatorForm) => {
|
8 |
+
const { t } = useTranslate('flow');
|
9 |
+
|
10 |
+
return (
|
11 |
+
<Form
|
12 |
+
name="basic"
|
13 |
+
labelCol={{ span: 7 }}
|
14 |
+
wrapperCol={{ span: 17 }}
|
15 |
+
autoComplete="off"
|
16 |
+
form={form}
|
17 |
+
onValuesChange={onValuesChange}
|
18 |
+
>
|
19 |
+
<Form.Item
|
20 |
+
label={t('dbType')}
|
21 |
+
name={'db_type'}
|
22 |
+
rules={[{ required: true }]}
|
23 |
+
>
|
24 |
+
<Select options={ExeSQLOptions}></Select>
|
25 |
+
</Form.Item>
|
26 |
+
<Form.Item
|
27 |
+
label={t('database')}
|
28 |
+
name={'database'}
|
29 |
+
rules={[{ required: true }]}
|
30 |
+
>
|
31 |
+
<Input></Input>
|
32 |
+
</Form.Item>
|
33 |
+
<Form.Item
|
34 |
+
label={t('username')}
|
35 |
+
name={'username'}
|
36 |
+
rules={[{ required: true }]}
|
37 |
+
>
|
38 |
+
<Input></Input>
|
39 |
+
</Form.Item>
|
40 |
+
<Form.Item label={t('host')} name={'host'} rules={[{ required: true }]}>
|
41 |
+
<Input></Input>
|
42 |
+
</Form.Item>
|
43 |
+
<Form.Item label={t('port')} name={'port'} rules={[{ required: true }]}>
|
44 |
+
<InputNumber></InputNumber>
|
45 |
+
</Form.Item>
|
46 |
+
<Form.Item
|
47 |
+
label={t('password')}
|
48 |
+
name={'password'}
|
49 |
+
rules={[{ required: true }]}
|
50 |
+
>
|
51 |
+
<Input.Password></Input.Password>
|
52 |
+
</Form.Item>
|
53 |
+
<Form.Item label={t('loop')} name={'loop'} rules={[{ required: true }]}>
|
54 |
+
<InputNumber></InputNumber>
|
55 |
+
</Form.Item>
|
56 |
+
<TopNItem initialValue={30} max={100000}></TopNItem>
|
57 |
+
</Form>
|
58 |
+
);
|
59 |
+
};
|
60 |
+
|
61 |
+
export default ExeSQLForm;
|
web/src/pages/flow/flow-drawer/index.tsx
CHANGED
@@ -11,7 +11,9 @@ import BeginForm from '../begin-form';
|
|
11 |
import BingForm from '../bing-form';
|
12 |
import CategorizeForm from '../categorize-form';
|
13 |
import { Operator } from '../constant';
|
|
|
14 |
import DuckDuckGoForm from '../duckduckgo-form';
|
|
|
15 |
import GenerateForm from '../generate-form';
|
16 |
import GithubForm from '../github-form';
|
17 |
import GoogleForm from '../google-form';
|
@@ -26,8 +28,6 @@ import RelevantForm from '../relevant-form';
|
|
26 |
import RetrievalForm from '../retrieval-form';
|
27 |
import RewriteQuestionForm from '../rewrite-question-form';
|
28 |
import WikipediaForm from '../wikipedia-form';
|
29 |
-
|
30 |
-
import DeepLForm from '../deepl-form';
|
31 |
import styles from './index.less';
|
32 |
|
33 |
interface IProps {
|
@@ -56,6 +56,7 @@ const FormMap = {
|
|
56 |
[Operator.GitHub]: GithubForm,
|
57 |
[Operator.BaiduFanyi]: BaiduFanyiForm,
|
58 |
[Operator.QWeather]: QWeatherForm,
|
|
|
59 |
};
|
60 |
|
61 |
const EmptyContent = () => <div>empty</div>;
|
|
|
11 |
import BingForm from '../bing-form';
|
12 |
import CategorizeForm from '../categorize-form';
|
13 |
import { Operator } from '../constant';
|
14 |
+
import DeepLForm from '../deepl-form';
|
15 |
import DuckDuckGoForm from '../duckduckgo-form';
|
16 |
+
import ExeSQLForm from '../exesql-form';
|
17 |
import GenerateForm from '../generate-form';
|
18 |
import GithubForm from '../github-form';
|
19 |
import GoogleForm from '../google-form';
|
|
|
28 |
import RetrievalForm from '../retrieval-form';
|
29 |
import RewriteQuestionForm from '../rewrite-question-form';
|
30 |
import WikipediaForm from '../wikipedia-form';
|
|
|
|
|
31 |
import styles from './index.less';
|
32 |
|
33 |
interface IProps {
|
|
|
56 |
[Operator.GitHub]: GithubForm,
|
57 |
[Operator.BaiduFanyi]: BaiduFanyiForm,
|
58 |
[Operator.QWeather]: QWeatherForm,
|
59 |
+
[Operator.ExeSQL]: ExeSQLForm,
|
60 |
};
|
61 |
|
62 |
const EmptyContent = () => <div>empty</div>;
|
web/src/pages/flow/generate-form/hooks.ts
CHANGED
@@ -6,7 +6,12 @@ import { IGenerateParameter } from '../interface';
|
|
6 |
import useGraphStore from '../store';
|
7 |
|
8 |
// exclude nodes with branches
|
9 |
-
const ExcludedNodes = [
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
export const useBuildComponentIdSelectOptions = (nodeId?: string) => {
|
12 |
const nodes = useGraphStore((state) => state.nodes);
|
|
|
6 |
import useGraphStore from '../store';
|
7 |
|
8 |
// exclude nodes with branches
|
9 |
+
const ExcludedNodes = [
|
10 |
+
Operator.Categorize,
|
11 |
+
Operator.Relevant,
|
12 |
+
Operator.Begin,
|
13 |
+
Operator.Answer,
|
14 |
+
];
|
15 |
|
16 |
export const useBuildComponentIdSelectOptions = (nodeId?: string) => {
|
17 |
const nodes = useGraphStore((state) => state.nodes);
|
web/src/pages/flow/hooks.ts
CHANGED
@@ -38,6 +38,7 @@ import {
|
|
38 |
initialCategorizeValues,
|
39 |
initialDeepLValues,
|
40 |
initialDuckValues,
|
|
|
41 |
initialGenerateValues,
|
42 |
initialGithubValues,
|
43 |
initialGoogleScholarValues,
|
@@ -107,6 +108,7 @@ export const useInitializeOperatorParams = () => {
|
|
107 |
[Operator.GitHub]: initialGithubValues,
|
108 |
[Operator.BaiduFanyi]: initialBaiduFanyiValues,
|
109 |
[Operator.QWeather]: initialQWeatherValues,
|
|
|
110 |
};
|
111 |
}, [llmId]);
|
112 |
|
|
|
38 |
initialCategorizeValues,
|
39 |
initialDeepLValues,
|
40 |
initialDuckValues,
|
41 |
+
initialExeSqlValues,
|
42 |
initialGenerateValues,
|
43 |
initialGithubValues,
|
44 |
initialGoogleScholarValues,
|
|
|
108 |
[Operator.GitHub]: initialGithubValues,
|
109 |
[Operator.BaiduFanyi]: initialBaiduFanyiValues,
|
110 |
[Operator.QWeather]: initialQWeatherValues,
|
111 |
+
[Operator.ExeSQL]: initialExeSqlValues,
|
112 |
};
|
113 |
}, [llmId]);
|
114 |
|
web/src/pages/user-setting/setting-model/ollama-modal/index.tsx
CHANGED
@@ -47,7 +47,7 @@ const OllamaModal = ({
|
|
47 |
return (
|
48 |
<Flex justify={'space-between'}>
|
49 |
<a
|
50 |
-
href={`https://github.com/infiniflow/ragflow/blob/main/docs/guides/deploy_local_llm.
|
51 |
target="_blank"
|
52 |
rel="noreferrer"
|
53 |
>
|
|
|
47 |
return (
|
48 |
<Flex justify={'space-between'}>
|
49 |
<a
|
50 |
+
href={`https://github.com/infiniflow/ragflow/blob/main/docs/guides/deploy_local_llm.mdx`}
|
51 |
target="_blank"
|
52 |
rel="noreferrer"
|
53 |
>
|