From 3738dd71ab6618d923e99824926f8ea4fc380489 Mon Sep 17 00:00:00 2001 From: balibabu Date: Fri, 16 Aug 2024 17:44:10 +0800 Subject: [PATCH] feat: Add component ExecSQL #1739 (#1982) ### 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 ++ web/src/components/top-n-item.tsx | 5 +- web/src/locales/en.ts | 9 +++ web/src/locales/zh-traditional.ts | 9 +++ web/src/locales/zh.ts | 9 +++ web/src/pages/flow/constant.tsx | 26 ++++++++ web/src/pages/flow/exesql-form/index.tsx | 61 +++++++++++++++++++ web/src/pages/flow/flow-drawer/index.tsx | 5 +- web/src/pages/flow/generate-form/hooks.ts | 7 ++- web/src/pages/flow/hooks.ts | 2 + .../setting-model/ollama-modal/index.tsx | 2 +- 11 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 web/src/assets/svg/exesql.svg create mode 100644 web/src/pages/flow/exesql-form/index.tsx diff --git a/web/src/assets/svg/exesql.svg b/web/src/assets/svg/exesql.svg new file mode 100644 index 000000000..e10498b49 --- /dev/null +++ b/web/src/assets/svg/exesql.svg @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/web/src/components/top-n-item.tsx b/web/src/components/top-n-item.tsx index 51be09315..86afdb823 100644 --- a/web/src/components/top-n-item.tsx +++ b/web/src/components/top-n-item.tsx @@ -7,9 +7,10 @@ type FieldType = { interface IProps { initialValue?: number; + max?: number; } -const TopNItem = ({ initialValue = 8 }: IProps) => { +const TopNItem = ({ initialValue = 8, max = 30 }: IProps) => { const { t } = useTranslate('chat'); return ( @@ -19,7 +20,7 @@ const TopNItem = ({ initialValue = 8 }: IProps) => { initialValue={initialValue} tooltip={t('topNTip')} > - + ); }; diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index 8fa8dd143..8860a2280 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -795,6 +795,15 @@ The above is the content you need to summarize.`, '30d': '30 days', }, publish: 'API', + exeSQL: 'ExeSQL', + exeSQLDescription: + 'The component queries the results from the corresponding relational database via SQL statements. Supports MySQL, PostgreSQL, MariaDB. ', + dbType: 'Database Type', + database: 'Database', + username: 'Username', + host: 'Host', + port: 'Port', + password: 'Password', }, footer: { profile: 'All rights reserved @ React', diff --git a/web/src/locales/zh-traditional.ts b/web/src/locales/zh-traditional.ts index b8b982ea9..8346cc4aa 100644 --- a/web/src/locales/zh-traditional.ts +++ b/web/src/locales/zh-traditional.ts @@ -753,6 +753,15 @@ export default { '30d': '30天', }, publish: 'API', + exeSQL: 'ExeSQL', + exeSQLDescription: + '此元件透過SQL語句從對應的關聯式資料庫中查詢結果。支援 MySQL、PostgreSQL、MariaDB。 ', + dbType: '資料庫類型', + database: '資料庫', + username: '使用者名稱', + host: '主機', + port: '端口', + password: '密碼', }, footer: { profile: '“保留所有權利 @ react”', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 9c0bafeee..d641fda4b 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -771,6 +771,15 @@ export default { '30d': '30天', }, publish: 'API', + exeSQL: 'ExeSQL', + exeSQLDescription: + '该组件通过SQL语句从相应的关系数据库中查询结果。支持MySQL,PostgreSQL,MariaDB。', + dbType: '数据库类型', + database: '数据库', + username: '用户名', + host: '主机', + port: '端口', + password: '密码', }, footer: { profile: 'All rights reserved @ React', diff --git a/web/src/pages/flow/constant.tsx b/web/src/pages/flow/constant.tsx index 7bb300010..275caa1ca 100644 --- a/web/src/pages/flow/constant.tsx +++ b/web/src/pages/flow/constant.tsx @@ -4,6 +4,7 @@ import { ReactComponent as BaiduIcon } from '@/assets/svg/baidu.svg'; import { ReactComponent as BingIcon } from '@/assets/svg/bing.svg'; import { ReactComponent as DeepLIcon } from '@/assets/svg/deepl.svg'; import { ReactComponent as DuckIcon } from '@/assets/svg/duck.svg'; +import { ReactComponent as ExeSqlIcon } from '@/assets/svg/exesql.svg'; import { ReactComponent as GithubIcon } from '@/assets/svg/github.svg'; import { ReactComponent as GoogleScholarIcon } from '@/assets/svg/google-scholar.svg'; import { ReactComponent as GoogleIcon } from '@/assets/svg/google.svg'; @@ -31,6 +32,7 @@ import { SendOutlined, SlidersOutlined, } from '@ant-design/icons'; +import upperFirst from 'lodash/upperFirst'; export enum Operator { Begin = 'Begin', @@ -54,6 +56,7 @@ export enum Operator { GitHub = 'GitHub', BaiduFanyi = 'BaiduFanyi', QWeather = 'QWeather', + ExeSQL = 'ExeSQL', } export const operatorIconMap = { @@ -78,6 +81,7 @@ export const operatorIconMap = { [Operator.GitHub]: GithubIcon, [Operator.BaiduFanyi]: baiduFanyiIcon, [Operator.QWeather]: QWeatherIcon, + [Operator.ExeSQL]: ExeSqlIcon, }; export const operatorMap = { @@ -165,6 +169,7 @@ export const operatorMap = { [Operator.GitHub]: {}, [Operator.BaiduFanyi]: {}, [Operator.QWeather]: {}, + [Operator.ExeSQL]: {}, }; export const componentMenuList = [ @@ -228,6 +233,9 @@ export const componentMenuList = [ { name: Operator.QWeather, }, + { + name: Operator.ExeSQL, + }, ]; export const initialRetrievalValues = { @@ -354,6 +362,17 @@ export const initialQWeatherValues = { time_period: 'now', }; +export const initialExeSqlValues = { + db_type: 'mysql', + database: '', + username: '', + host: '', + port: 3306, + password: '', + loop: 3, + top_n: 30, +}; + export const CategorizeAnchorPointPositions = [ { top: 1, right: 34 }, { top: 8, right: 18 }, @@ -422,6 +441,7 @@ export const RestrictedUpstreamMap = { [Operator.GitHub]: [Operator.Begin, Operator.Retrieval], [Operator.BaiduFanyi]: [Operator.Begin, Operator.Retrieval], [Operator.QWeather]: [Operator.Begin, Operator.Retrieval], + [Operator.ExeSQL]: [Operator.Begin], }; export const NodeMap = { @@ -446,6 +466,7 @@ export const NodeMap = { [Operator.GitHub]: 'ragNode', [Operator.BaiduFanyi]: 'ragNode', [Operator.QWeather]: 'ragNode', + [Operator.ExeSQL]: 'ragNode', }; export const LanguageOptions = [ @@ -2576,3 +2597,8 @@ export const QWeatherTimePeriodOptions = [ '15d', '30d', ]; + +export const ExeSQLOptions = ['mysql', 'postgresql', 'mariadb'].map((x) => ({ + label: upperFirst(x), + value: x, +})); diff --git a/web/src/pages/flow/exesql-form/index.tsx b/web/src/pages/flow/exesql-form/index.tsx new file mode 100644 index 000000000..4a2465ed2 --- /dev/null +++ b/web/src/pages/flow/exesql-form/index.tsx @@ -0,0 +1,61 @@ +import TopNItem from '@/components/top-n-item'; +import { useTranslate } from '@/hooks/common-hooks'; +import { Form, Input, InputNumber, Select } from 'antd'; +import { ExeSQLOptions } from '../constant'; +import { IOperatorForm } from '../interface'; + +const ExeSQLForm = ({ onValuesChange, form }: IOperatorForm) => { + const { t } = useTranslate('flow'); + + return ( +
+ + + + + + + + + + + + + + + + + + + + + + +
+ ); +}; + +export default ExeSQLForm; diff --git a/web/src/pages/flow/flow-drawer/index.tsx b/web/src/pages/flow/flow-drawer/index.tsx index 2253a54f2..cf90877ff 100644 --- a/web/src/pages/flow/flow-drawer/index.tsx +++ b/web/src/pages/flow/flow-drawer/index.tsx @@ -11,7 +11,9 @@ import BeginForm from '../begin-form'; import BingForm from '../bing-form'; import CategorizeForm from '../categorize-form'; import { Operator } from '../constant'; +import DeepLForm from '../deepl-form'; import DuckDuckGoForm from '../duckduckgo-form'; +import ExeSQLForm from '../exesql-form'; import GenerateForm from '../generate-form'; import GithubForm from '../github-form'; import GoogleForm from '../google-form'; @@ -26,8 +28,6 @@ import RelevantForm from '../relevant-form'; import RetrievalForm from '../retrieval-form'; import RewriteQuestionForm from '../rewrite-question-form'; import WikipediaForm from '../wikipedia-form'; - -import DeepLForm from '../deepl-form'; import styles from './index.less'; interface IProps { @@ -56,6 +56,7 @@ const FormMap = { [Operator.GitHub]: GithubForm, [Operator.BaiduFanyi]: BaiduFanyiForm, [Operator.QWeather]: QWeatherForm, + [Operator.ExeSQL]: ExeSQLForm, }; const EmptyContent = () =>
empty
; diff --git a/web/src/pages/flow/generate-form/hooks.ts b/web/src/pages/flow/generate-form/hooks.ts index 4876b607e..11d16f34b 100644 --- a/web/src/pages/flow/generate-form/hooks.ts +++ b/web/src/pages/flow/generate-form/hooks.ts @@ -6,7 +6,12 @@ import { IGenerateParameter } from '../interface'; import useGraphStore from '../store'; // exclude nodes with branches -const ExcludedNodes = [Operator.Categorize, Operator.Relevant]; +const ExcludedNodes = [ + Operator.Categorize, + Operator.Relevant, + Operator.Begin, + Operator.Answer, +]; export const useBuildComponentIdSelectOptions = (nodeId?: string) => { const nodes = useGraphStore((state) => state.nodes); diff --git a/web/src/pages/flow/hooks.ts b/web/src/pages/flow/hooks.ts index 1eb0101a8..128273b56 100644 --- a/web/src/pages/flow/hooks.ts +++ b/web/src/pages/flow/hooks.ts @@ -38,6 +38,7 @@ import { initialCategorizeValues, initialDeepLValues, initialDuckValues, + initialExeSqlValues, initialGenerateValues, initialGithubValues, initialGoogleScholarValues, @@ -107,6 +108,7 @@ export const useInitializeOperatorParams = () => { [Operator.GitHub]: initialGithubValues, [Operator.BaiduFanyi]: initialBaiduFanyiValues, [Operator.QWeather]: initialQWeatherValues, + [Operator.ExeSQL]: initialExeSqlValues, }; }, [llmId]); diff --git a/web/src/pages/user-setting/setting-model/ollama-modal/index.tsx b/web/src/pages/user-setting/setting-model/ollama-modal/index.tsx index d102d6572..1cf961139 100644 --- a/web/src/pages/user-setting/setting-model/ollama-modal/index.tsx +++ b/web/src/pages/user-setting/setting-model/ollama-modal/index.tsx @@ -47,7 +47,7 @@ const OllamaModal = ({ return (