From e801c448be902b54aa260dcee4d01a667e42d3eb Mon Sep 17 00:00:00 2001 From: williamhliu <137068196+williamhliu@users.noreply.github.com> Date: Sun, 4 Feb 2024 20:58:33 +0800 Subject: [PATCH] (feature)(webapp) modify model to view (#719) --- webapp/packages/chat-sdk/src/common/type.ts | 4 +- .../src/components/ChatItem/ParseTip.tsx | 10 +- .../src/components/ChatItem/index.tsx | 2 +- .../src/components/ChatMsg/Bar/index.tsx | 2 +- .../components/ChatMsg/MetricCard/index.tsx | 2 +- .../components/ChatMsg/MetricTrend/index.tsx | 2 +- .../src/components/ChatMsg/Table/index.tsx | 2 +- webapp/packages/chat-sdk/src/setupProxy.js | 4 +- webapp/packages/supersonic-fe/package.json | 4 +- .../src/pages/Agent/AgentsSection.tsx | 12 -- .../src/pages/Agent/ToolModal.tsx | 108 +++--------------- .../supersonic-fe/src/pages/Agent/service.ts | 2 +- .../supersonic-fe/src/pages/Agent/type.ts | 2 +- .../src/pages/ChatPlugin/DetailModal.tsx | 30 ++--- .../src/pages/ChatPlugin/index.tsx | 12 +- .../src/pages/ChatPlugin/service.ts | 2 +- .../packages/supersonic-fe/src/utils/utils.ts | 12 +- 17 files changed, 67 insertions(+), 145 deletions(-) diff --git a/webapp/packages/chat-sdk/src/common/type.ts b/webapp/packages/chat-sdk/src/common/type.ts index 06890ff35..9f043d253 100644 --- a/webapp/packages/chat-sdk/src/common/type.ts +++ b/webapp/packages/chat-sdk/src/common/type.ts @@ -28,7 +28,7 @@ export type ModelInfoType = { }; export type EntityInfoType = { - modelInfo: ModelInfoType; + viewInfo: ModelInfoType; dimensions: FieldType[]; metrics: FieldType[]; entityId: number; @@ -83,7 +83,7 @@ export type ChatContextType = { aggType: string; modelId: number; modelName: string; - model: ModelType; + view: ModelType; dateInfo: DateInfoType; dimensions: FieldType[]; metrics: FieldType[]; diff --git a/webapp/packages/chat-sdk/src/components/ChatItem/ParseTip.tsx b/webapp/packages/chat-sdk/src/components/ChatItem/ParseTip.tsx index de6b7ebf5..6e3ef83c6 100644 --- a/webapp/packages/chat-sdk/src/components/ChatItem/ParseTip.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatItem/ParseTip.tsx @@ -89,7 +89,7 @@ const ParseTip: React.FC = ({ const { modelId, - model, + view, dimensions, metrics, aggType, @@ -148,12 +148,8 @@ const ParseTip: React.FC = ({ ) : (
-
数据模型:
-
- {model?.modelNames?.length === 1 - ? model.modelNames[0] - : model?.modelNames?.map(modelName => {modelName})} -
+
数据视图:
+
{view?.name}
)} {(queryType === 'METRIC' || queryType === 'METRIC_TAG' || queryType === 'TAG') && ( diff --git a/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx b/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx index 9fa98f6f5..5f96615b4 100644 --- a/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatItem/index.tsx @@ -84,7 +84,7 @@ const ChatItem: React.FC = ({ let data: MsgDataType | undefined = undefined; const { queryColumns, queryResults, queryState, queryMode, response, chatContext } = res.data || {}; - if (res.code === 401 || res.code === 412) { + if (res.code === 400 || res.code === 401 || res.code === 412) { tip = res.msg; } else if (res.code !== 200) { tip = SEARCH_EXCEPTION_TIP; diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx index cf9ec3ba2..45d64266d 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/Bar/index.tsx @@ -141,7 +141,7 @@ const BarChart: React.FC = ({ data, triggerResize, loading, onApplyAuth } if (metricColumn && !metricColumn?.authorized) { return ( diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricCard/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricCard/index.tsx index f00da255c..4f5134e5e 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricCard/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricCard/index.tsx @@ -48,7 +48,7 @@ const MetricCard: React.FC = ({ data, loading, onApplyAuth }) => {
{indicatorColumn && !indicatorColumn?.authorized ? ( - + ) : (
diff --git a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx index fab650543..30800508a 100644 --- a/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx +++ b/webapp/packages/chat-sdk/src/components/ChatMsg/MetricTrend/index.tsx @@ -109,7 +109,7 @@ const MetricTrend: React.FC = ({ /> ) : ( = ({ data, size, loading, onApplyAuth }) => { title: name || nameEn, render: (value: string | number) => { if (!authorized) { - return ; + return ; } if (dataFormatType === 'percent') { return ( diff --git a/webapp/packages/chat-sdk/src/setupProxy.js b/webapp/packages/chat-sdk/src/setupProxy.js index e9396ab09..477af0f4e 100644 --- a/webapp/packages/chat-sdk/src/setupProxy.js +++ b/webapp/packages/chat-sdk/src/setupProxy.js @@ -1,6 +1,6 @@ const { createProxyMiddleware } = require('http-proxy-middleware'); -module.exports = function(app) { +module.exports = function (app) { app.use( '/api', createProxyMiddleware({ @@ -15,4 +15,4 @@ module.exports = function(app) { changeOrigin: true, }) ); -}; \ No newline at end of file +}; diff --git a/webapp/packages/supersonic-fe/package.json b/webapp/packages/supersonic-fe/package.json index 35e602d05..8aa1191c7 100644 --- a/webapp/packages/supersonic-fe/package.json +++ b/webapp/packages/supersonic-fe/package.json @@ -28,7 +28,7 @@ "lint:style": "stylelint --fix \"src/**/*.less\" --syntax less", "precommit": "lint-staged", "prettier": "prettier -c --write \"src/**/*\"", - "start": "npm run start:osdev", + "start": "NODE_OPTIONS=--openssl-legacy-provider npm run start:osdev", "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none APP_TARGET=inner umi dev", "start:osdev": "cross-env REACT_APP_ENV=dev PORT=9000 MOCK=none APP_TARGET=opensource umi dev", "start:no-mock": "cross-env MOCK=none umi dev", @@ -147,4 +147,4 @@ "@types/react": "17.0.0" }, "__npminstall_done": false -} +} \ No newline at end of file diff --git a/webapp/packages/supersonic-fe/src/pages/Agent/AgentsSection.tsx b/webapp/packages/supersonic-fe/src/pages/Agent/AgentsSection.tsx index 577841f6c..68e27f571 100644 --- a/webapp/packages/supersonic-fe/src/pages/Agent/AgentsSection.tsx +++ b/webapp/packages/supersonic-fe/src/pages/Agent/AgentsSection.tsx @@ -135,18 +135,6 @@ const AgentsSection: React.FC = ({ 新建助理 -
- 切换为卡片 - { - const showTypeValue = value ? 'card' : 'list'; - setShowType(showTypeValue); - localStorage.setItem('AGENT_SHOW_TYPE', showTypeValue); - }} - /> -
{showType === 'list' ? ( diff --git a/webapp/packages/supersonic-fe/src/pages/Agent/ToolModal.tsx b/webapp/packages/supersonic-fe/src/pages/Agent/ToolModal.tsx index 4d5ba8d59..93d5f22bb 100644 --- a/webapp/packages/supersonic-fe/src/pages/Agent/ToolModal.tsx +++ b/webapp/packages/supersonic-fe/src/pages/Agent/ToolModal.tsx @@ -1,18 +1,16 @@ -import { Form, Modal, Input, Select, Button } from 'antd'; +import { Form, Modal, Input, Select, Button, TreeSelect } from 'antd'; import { AgentToolType, AgentToolTypeEnum, AGENT_TOOL_TYPE_LIST, MetricOptionType, - MetricType, - ModelType, QUERY_MODE_LIST, } from './type'; import { useEffect, useState } from 'react'; import { DeleteOutlined, PlusOutlined } from '@ant-design/icons'; import styles from './style.less'; -import { getLeafList, uuid } from '@/utils/utils'; -import { getMetricList, getModelList } from './service'; +import { traverseTree, uuid } from '@/utils/utils'; +import { getModelList } from './service'; import { PluginType } from '../ChatPlugin/type'; import { getPluginList } from '../ChatPlugin/service'; @@ -26,17 +24,22 @@ type Props = { const ToolModal: React.FC = ({ editTool, onSaveTool, onCancel }) => { const [toolType, setToolType] = useState(); - const [modelList, setModelList] = useState([]); + const [modelList, setModelList] = useState([]); const [saveLoading, setSaveLoading] = useState(false); const [examples, setExamples] = useState<{ id: string; question?: string }[]>([]); const [metricOptions, setMetricOptions] = useState([]); - const [modelMetricList, setModelMetricList] = useState([]); const [plugins, setPlugins] = useState([]); const [form] = Form.useForm(); const initModelList = async () => { const res = await getModelList(); - setModelList([{ id: -1, name: '默认' }, ...getLeafList(res.data)]); + const treeData = traverseTree(res.data, (node: any) => { + node.title = node.name; + node.value = node.type === 'DOMAIN' ? `DOMAIN_${node.id}` : node.id; + node.checkable = + node.type === 'VIEW' || (node.type === 'DOMAIN' && node.children?.length > 0); + }); + setModelList([{ title: '默认', value: -1, type: 'VIEW' }, ...treeData]); }; const initPluginList = async () => { @@ -49,11 +52,6 @@ const ToolModal: React.FC = ({ editTool, onSaveTool, onCancel }) => { initPluginList(); }, []); - const initModelMetrics = async (params: any) => { - const res = await getMetricList(params[0].modelId); - setModelMetricList(res.data.list); - }; - useEffect(() => { if (editTool) { form.setFieldsValue({ ...editTool, plugins: editTool.plugins?.[0] }); @@ -62,9 +60,6 @@ const ToolModal: React.FC = ({ editTool, onSaveTool, onCancel }) => { (editTool.exampleQuestions || []).map((item) => ({ id: uuid(), question: item })), ); setMetricOptions(editTool.metricOptions || []); - if (editTool.metricOptions && editTool.metricOptions.length > 0) { - initModelMetrics(editTool.metricOptions || []); - } } else { form.resetFields(); } @@ -88,11 +83,6 @@ const ToolModal: React.FC = ({ editTool, onSaveTool, onCancel }) => { setSaveLoading(false); }; - const updateMetricList = async (value: number) => { - const res = await getMetricList(value); - setModelMetricList(res.data.list); - }; - return ( = ({ editTool, onSaveTool, onCancel }) => { {(toolType === AgentToolTypeEnum.NL2SQL_RULE || toolType === AgentToolTypeEnum.NL2SQL_LLM) && ( - - ({ label: model.name, value: model.id }))} - showSearch - filterOption={(input, option) => - ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase()) - } - placeholder="请选择主题域" - onChange={(value) => { - setMetricOptions([...metricOptions]); - updateMetricList(value); - }} - /> - - -
- {metricOptions.map((filter: any) => { - return ( -
- >('/api/chat/conf/viewList', { + return request>('/api/chat/conf/getDomainViewTree', { method: 'GET', }); } diff --git a/webapp/packages/supersonic-fe/src/pages/Agent/type.ts b/webapp/packages/supersonic-fe/src/pages/Agent/type.ts index 11dbb3cdb..b11d9e219 100644 --- a/webapp/packages/supersonic-fe/src/pages/Agent/type.ts +++ b/webapp/packages/supersonic-fe/src/pages/Agent/type.ts @@ -8,7 +8,6 @@ export enum AgentToolTypeEnum { NL2SQL_RULE = 'NL2SQL_RULE', NL2SQL_LLM = 'NL2SQL_LLM', PLUGIN = 'PLUGIN', - ANALYTICS = 'ANALYTICS', } export const AGENT_TOOL_TYPE_LIST = [ @@ -76,6 +75,7 @@ export type ModelType = { parentId: number; name: string; bizName: string; + type: 'DOMAIN' | 'VIEW'; }; export type MetricType = { diff --git a/webapp/packages/supersonic-fe/src/pages/ChatPlugin/DetailModal.tsx b/webapp/packages/supersonic-fe/src/pages/ChatPlugin/DetailModal.tsx index 3127d05e6..f5cd87752 100644 --- a/webapp/packages/supersonic-fe/src/pages/ChatPlugin/DetailModal.tsx +++ b/webapp/packages/supersonic-fe/src/pages/ChatPlugin/DetailModal.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { Modal, Select, Form, Input, InputNumber, message, Button, Radio } from 'antd'; +import { Modal, Select, Form, Input, InputNumber, message, Button, Radio, TreeSelect } from 'antd'; import { getDimensionList, getModelList, savePlugin } from './service'; import { DimensionType, @@ -10,7 +10,7 @@ import { FunctionParamFormItemType, PluginTypeEnum, } from './type'; -import { getLeafList, uuid } from '@/utils/utils'; +import { getLeafList, traverseTree, uuid } from '@/utils/utils'; import styles from './style.less'; import { PLUGIN_TYPE_MAP } from './constants'; import { DeleteOutlined, PlusOutlined } from '@ant-design/icons'; @@ -38,7 +38,13 @@ const DetailModal: React.FC = ({ detail, onSubmit, onCancel }) => { const initModelList = async () => { const res = await getModelList(); - setModelList([{ id: -1, name: '默认' }, ...getLeafList(res.data)]); + const treeData = traverseTree(res.data, (node: any) => { + node.title = node.name; + node.value = node.type === 'DOMAIN' ? `DOMAIN_${node.id}` : node.id; + node.checkable = + node.type === 'VIEW' || (node.type === 'DOMAIN' && node.children?.length > 0); + }); + setModelList([{ title: '默认', value: -1, type: 'VIEW' }, ...treeData]); }; useEffect(() => { @@ -181,18 +187,12 @@ const DetailModal: React.FC = ({ detail, onSubmit, onCancel }) => { onCancel={onCancel} >
- -