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 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={30} />
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 = [Operator.Categorize, Operator.Relevant];
 
 
 
 
 
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.md`}
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
  >