From bdf7df933b495a4b457512824d10a091b8dd467d Mon Sep 17 00:00:00 2001 From: tristanliu <37809633+sevenliu1896@users.noreply.github.com> Date: Mon, 26 Feb 2024 18:40:23 +0800 Subject: [PATCH] [improvement][headless-fe] Restructured the data for the dimension value settings interface. (#760) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [improvement][semantic-fe] Add model alias setting & Add view permission restrictions to the model permission management tab. [improvement][semantic-fe] Add permission control to the action buttons for the main domain; apply high sensitivity filtering to the authorization of metrics/dimensions. [improvement][semantic-fe] Optimize the editing mode in the dimension/metric/datasource components to use the modelId stored in the database for data, instead of relying on the data from the state manager. * [improvement][semantic-fe] Add time granularity setting in the data source configuration. * [improvement][semantic-fe] Dictionary import for dimension values supported in Q&A visibility * [improvement][semantic-fe] Modification of data source creation prompt wording" * [improvement][semantic-fe] metric market experience optimization * [improvement][semantic-fe] enhance the analysis of metric trends * [improvement][semantic-fe] optimize the presentation of metric trend permissions * [improvement][semantic-fe] add metric trend download functionality * [improvement][semantic-fe] fix the dimension initialization issue in metric correlation * [improvement][semantic-fe] Fix the issue of database changes not taking effect when creating based on an SQL data source. * [improvement][semantic-fe] Optimizing pagination logic and some CSS styles * [improvement][semantic-fe] Fixing the API for the indicator list by changing "current" to "pageNum" * [improvement][semantic-fe] Fixing the default value setting for the indicator list * [improvement][semantic-fe] Adding batch operations for indicators/dimensions/models * [improvement][semantic-fe] Replacing the single status update API for indicators/dimensions with a batch update API * [improvement][semantic-fe] Redesigning the indicator homepage to incorporate trend charts and table functionality for indicators * [improvement][semantic-fe] Optimizing the logic for setting dimension values and editing data sources, and adding system settings functionality * [improvement][semantic-fe] Upgrading antd version to 5.x, extracting the batch operation button component, optimizing the interaction for system settings, and expanding the configuration generation types for list-to-select component. * [improvement][semantic-fe] Adding the ability to filter dimensions based on whether they are tags or not. * [improvement][semantic-fe] Adding the ability to edit relationships between models in the canvas. * [improvement][semantic-fe] Updating the datePicker component to use dayjs instead. * [improvement][semantic-fe] Fixing the issue with passing the model ID for dimensions in the indicator market. * [improvement][semantic-fe] Fixing the abnormal state of the popup when creating a model. * [improvement][semantic-fe] Adding permission logic for bulk operations in the indicator market. * [improvement][semantic-fe] Adding the ability to download and transpose data. * [improvement][semantic-fe] Fixing the initialization issue with the date selection component in the indicator details page when switching time granularity. * [improvement][semantic-fe] Fixing the logic error in the dimension value setting. * [improvement][semantic-fe] Fixing the synchronization issue with the question and answer settings information. * [improvement][semantic-fe] Optimizing the canvas functionality for better performance and user experience. * [improvement][semantic-fe] Optimizing the update process for drawing model relationship edges in the canvas. * [improvement][semantic-fe] Changing the line type for canvas connections. * [improvement][semantic-fe] Replacing the initialization variable from "semantic" to "headless". * [improvement][semantic-fe] Fixing the missing migration issue for default drill-down dimension configuration in model editing. Additionally, optimizing the data retrieval method for initializing fields in the model. * [improvement][semantic-fe] Updating the logic for the fieldName. * [improvement][semantic-fe] Adjusting the position of the metrics tab. * [improvement][semantic-fe] Changing the 字段名称 to 英文名称. * [improvement][semantic-fe] Fix metric measurement deletion. * [improvement][semantic-fe] UI optimization for metric details page. * [improvement][semantic-fe] UI optimization for metric details page. * [improvement][semantic-fe] UI adjustment for metric details page. * [improvement][semantic-fe] The granularity field in the time type of model editing now supports setting it as empty. * [improvement][semantic-fe] Added field type and metric type to the metric creation options. * [improvement][semantic-fe] The organization structure selection feature has been added to the permission management. * [improvement][semantic-fe] Improved user experience for the metric list. * [improvement][semantic-fe] fix update the metric list. * [improvement][headless-fe] Added view management functionality. * [improvement][headless-fe] The view management functionality has been added. This feature allows users to create, edit, and manage different views within the system. * [improvement][headless-fe] Added model editing side effect detection. * [improvement][headless-fe] Fixed the logic error in view editing. * [improvement][headless-fe] Fixed the issue with initializing dimension associations in metric settings. * [improvement][headless-fe] Added the ability to hide the Q&A settings entry point. * [improvement][headless-fe] Fixed the issue with selecting search results in metric field creation. * [improvement][headless-fe] Added search functionality to the field list in model editing. * [improvement][headless-fe] fix the field list in model editing * [improvement][headless-fe] Restructured the data for the dimension value settings interface. --- .../packages/supersonic-fe/src/enum/index.ts | 18 - .../SemanticModel/ChatSetting/ChatSetting.tsx | 21 -- .../ChatSetting/ChatSettingSection.tsx | 43 --- .../ChatSetting/ChatSettingTab.tsx | 102 ------ .../Datasource/components/SqlDetail.tsx | 32 +- .../Datasource/components/SqlParams.tsx | 112 +++++++ .../components/SqlParamsDetailModal.tsx | 195 +++++++++++ .../components/SqlParamsSqlEditor.tsx | 132 ++++++++ .../pages/SemanticModel/Datasource/data.d.ts | 7 + .../pages/SemanticModel/OverviewContainer.tsx | 48 +-- .../components/DimensionValueSettingModal.tsx | 2 +- .../components/Entity/DefaultSettingForm.tsx | 244 -------------- .../Entity/DimensionValueSettingForm.tsx | 317 ++++++++++-------- .../components/Entity/EntitySection.tsx | 103 ------ .../src/pages/SemanticModel/data.d.ts | 63 +++- .../src/pages/SemanticModel/enum.ts | 29 +- .../src/pages/SemanticModel/service.ts | 26 +- .../packages/supersonic-fe/src/utils/utils.ts | 19 ++ 18 files changed, 774 insertions(+), 739 deletions(-) delete mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSetting.tsx delete mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSettingSection.tsx delete mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSettingTab.tsx create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlParams.tsx create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlParamsDetailModal.tsx create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlParamsSqlEditor.tsx delete mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/components/Entity/DefaultSettingForm.tsx delete mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/components/Entity/EntitySection.tsx diff --git a/webapp/packages/supersonic-fe/src/enum/index.ts b/webapp/packages/supersonic-fe/src/enum/index.ts index be75e95ce..389953605 100644 --- a/webapp/packages/supersonic-fe/src/enum/index.ts +++ b/webapp/packages/supersonic-fe/src/enum/index.ts @@ -1,22 +1,4 @@ export * from './models/base'; -type ObjToArrayParams = Record; - -const keyTypeTran = { - string: String, - number: Number, -}; -/** - * obj转成value,label的数组 - * @param _obj - */ -export const objToArray = (_obj: ObjToArrayParams, keyType: string = 'string') => { - return Object.keys(_obj).map((key) => { - return { - value: keyTypeTran[keyType](key), - label: _obj[key], - }; - }); -}; type EnumToArrayItem = { value: number; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSetting.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSetting.tsx deleted file mode 100644 index 28a378997..000000000 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSetting.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import { connect } from 'umi'; -import type { StateType } from '../model'; -import OverviewContainer from '../OverviewContainer'; -import type { Dispatch } from 'umi'; - -type Props = { - domainManger: StateType; - dispatch: Dispatch; -}; -const ChatSetting: React.FC = () => { - return ( - <> - - - ); -}; - -export default connect(({ domainManger }: { domainManger: StateType }) => ({ - domainManger, -}))(ChatSetting); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSettingSection.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSettingSection.tsx deleted file mode 100644 index 8e38dd6be..000000000 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSettingSection.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useRef } from 'react'; -import { connect } from 'umi'; -import type { StateType } from '../model'; -import ProCard from '@ant-design/pro-card'; -import EntitySection from '../components/Entity/EntitySection'; -import { ChatConfigType } from '../enum'; -import type { Dispatch } from 'umi'; - -type Props = { - domainManger: StateType; - dispatch: Dispatch; -}; - -const ChatSettingSection: React.FC = () => { - const metricRef = useRef(); - const tagRef = useRef(); - return ( -
- - { - tagRef.current.refreshConfigData(); - }} - /> - - - { - metricRef.current.refreshConfigData(); - }} - /> - -
- ); -}; - -export default connect(({ domainManger }: { domainManger: StateType }) => ({ - domainManger, -}))(ChatSettingSection); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSettingTab.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSettingTab.tsx deleted file mode 100644 index e5913a5e0..000000000 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/ChatSetting/ChatSettingTab.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { Tabs, Button } from 'antd'; -import React from 'react'; -import { connect } from 'umi'; - -import styles from '../components/style.less'; -import type { StateType } from '../model'; -import { LeftOutlined } from '@ant-design/icons'; -import EntitySection from '../components/Entity/EntitySection'; -import RecommendedQuestionsSection from '../components/Entity/RecommendedQuestionsSection'; -import { ISemantic } from '../data'; - -import OverView from '../components/OverView'; -import { ChatConfigType } from '../enum'; -import type { Dispatch } from 'umi'; - -type Props = { - isModel: boolean; - activeKey: string; - modelList: ISemantic.IModelItem[]; - handleModelChange: (model?: ISemantic.IModelItem) => void; - onBackDomainBtnClick?: () => void; - onMenuChange?: (menuKey: string) => void; - domainManger: StateType; - dispatch: Dispatch; -}; - -const ChatSetting: React.FC = ({ - isModel, - activeKey, - modelList, - handleModelChange, - onBackDomainBtnClick, - onMenuChange, -}) => { - const defaultTabKey = 'metric'; - - const isModelItem = [ - { - label: '指标模式', - key: 'metric', - children: , - }, - { - label: '标签模式', - key: 'dimenstion', - children: , - }, - { - label: '推荐问题', - key: 'recommendedQuestions', - children: , - }, - ]; - - const tabItem = [ - { - label: '模型', - key: 'overview', - children: ( - { - handleModelChange(model); - }} - /> - ), - }, - ]; - - return ( - <> - } - onClick={() => { - onBackDomainBtnClick?.(); - }} - style={{ marginRight: 10 }} - > - 返回主题域 - - ) : undefined - } - onChange={(menuKey: string) => { - onMenuChange?.(menuKey); - }} - /> - - ); -}; - -export default connect(({ domainManger }: { domainManger: StateType }) => ({ - domainManger, -}))(ChatSetting); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlDetail.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlDetail.tsx index 8b5ba83c5..665a31a78 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlDetail.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlDetail.tsx @@ -12,17 +12,17 @@ import { SwapOutlined, PlayCircleOutlined, CloudServerOutlined, + ApiOutlined, } from '@ant-design/icons'; import { isFunction } from 'lodash'; import FullScreen from '@/components/FullScreen'; import SqlEditor from '@/components/SqlEditor'; import type { TaskResultItem, TaskResultColumn } from '../data'; import { excuteSql } from '@/pages/SemanticModel/service'; -// import DataSourceCreateForm from './DataSourceCreateForm'; import type { Dispatch } from 'umi'; import type { StateType } from '../../model'; +import SqlParams from './SqlParams'; import styles from '../style.less'; - import 'ace-builds/src-min-noconflict/ext-searchbox'; import 'ace-builds/src-min-noconflict/theme-sqlserver'; import 'ace-builds/src-min-noconflict/theme-monokai'; @@ -77,7 +77,6 @@ const SqlDetail: React.FC = ({ }); const [dataBaseItems, setDataBaseItems] = useState([]); const [currentDatabaseItem, setCurrentDatabaseItem] = useState(); - // const [dataSourceModalVisible, setDataSourceModalVisible] = useState(false); const [tableScroll, setTableScroll] = useState({ scrollToFirstRowOnChange: true, @@ -88,7 +87,7 @@ const SqlDetail: React.FC = ({ const [runState, setRunState] = useState(); const [taskLog, setTaskLog] = useState(''); - const [isSqlExcLocked, setIsSqlExcLocked] = useState(false); + const [isSqlExcLocked, setIsSqlExcLocked] = useState(false); const [screenSize, setScreenSize] = useState('middle'); const [isSqlIdeFullScreen, setIsSqlIdeFullScreen] = useState(false); @@ -100,8 +99,11 @@ const SqlDetail: React.FC = ({ const DEFAULT_FULLSCREEN_TOP = 0; const [partialSql, setPartialSql] = useState(''); - const [isPartial, setIsPartial] = useState(false); - const [isRight, setIsRight] = useState(false); + const [isPartial, setIsPartial] = useState(false); + const [isRight, setIsRight] = useState(false); + + const [variableCollapsed, setVariableCollapsed] = useState(true); + const [sqlParams, setSqlParams] = useState([]); const [scriptColumns, setScriptColumns] = useState([]); @@ -125,6 +127,10 @@ const SqlDetail: React.FC = ({ setCurrentDatabaseItem(targetDataBase); }, [dataSourceItem, databaseConfigList]); + useEffect(() => { + setSqlParams(dataSourceItem?.modelDetail?.sqlVariables || []); + }, [dataSourceItem]); + useEffect(() => { setRunState(undefined); }, [currentDatabaseItem, sql]); @@ -138,6 +144,11 @@ const SqlDetail: React.FC = ({ return line; } + const handleVariable = () => { + const collapsedValue = !variableCollapsed; + setVariableCollapsed(collapsedValue); + }; + // 计算每列的宽度,通过容器插入文档中动态得到该列数据(包括表头)的最长宽度,设为列宽度,保证每列的数据都能一行展示完 function getKeyWidthMap(list: TaskResultItem[]): TaskResultItem { const widthMap = {}; @@ -417,6 +428,9 @@ const SqlDetail: React.FC = ({ + {/* + + */} @@ -463,6 +477,12 @@ const SqlDetail: React.FC = ({ onSelect={onSelect} /> +
+ +
diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlParams.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlParams.tsx new file mode 100644 index 000000000..bde912c90 --- /dev/null +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlParams.tsx @@ -0,0 +1,112 @@ +import { useState } from 'react'; +import type { FC } from 'react'; +import type { SqlParamsItem, OprType } from '../data'; + +import styles from '../style.less'; +import { AppstoreAddOutlined, DeleteTwoTone, EditTwoTone } from '@ant-design/icons'; +import SqlParamsDetailModal from './SqlParamsDetailModal'; +import { List } from 'antd'; + +type Props = { + value?: SqlParamsItem[]; + onChange?: (e: SqlParamsItem[]) => void; +}; + +const defalutItem: SqlParamsItem = { + name: '', + type: 'query', + defaultValues: [], + valueType: 'string', + udf: false, +}; + +const SqlParams: FC = ({ value, onChange }) => { + const [oprType, setOprType] = useState('add'); + const [visible, setVisible] = useState(false); + const [initValue, setInitValue] = useState(); + const paramsChange = (params: SqlParamsItem[]) => { + if (onChange) { + onChange(params); + } + }; + const handleAdd = () => { + setOprType('add'); + setVisible(true); + setInitValue(defalutItem); + }; + const handleSave = async (values: SqlParamsItem) => { + const newValue = value ? [...value] : []; + const { index, ...rest } = values; + if (index || index === 0) { + newValue[index] = rest; + } else { + newValue.push(rest); + } + setVisible(false); + setInitValue(undefined); + paramsChange(newValue); + }; + + const handleDelete = (index: number) => { + const newValue = value ? [...value] : []; + newValue.splice(index, 1); + paramsChange(newValue); + }; + const handleEdit = (index: number) => { + const paramsItem = value ? value[index] : defalutItem; + setInitValue({ ...paramsItem, index }); + setOprType('edit'); + setVisible(true); + }; + return ( + <> +
+
+ 变量 + +
+ ( + + { + handleEdit(index); + }} + /> + { + handleDelete(index); + }} + /> + , + ]} + > +
{item.name}
+
+ )} + /> +
+ item.name)} + oprType={oprType} + modalVisible={visible} + onSave={handleSave} + onCancel={() => { + setVisible(false); + }} + initValue={initValue} + /> + + ); +}; + +export default SqlParams; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlParamsDetailModal.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlParamsDetailModal.tsx new file mode 100644 index 000000000..264a8f3c5 --- /dev/null +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Datasource/components/SqlParamsDetailModal.tsx @@ -0,0 +1,195 @@ +import { useEffect, useState } from 'react'; +import type { FC } from 'react'; +import { Modal, Form, Input, Select, Checkbox } from 'antd'; +import { isFunction } from 'lodash'; +import { objToArray } from '@/utils/utils'; +import type { ParamsItemProps, OprType } from '../data'; +import { IDataSource } from '../../data'; +import TextArea from 'antd/lib/input/TextArea'; +import ParamsSqlEditor from './SqlParamsSqlEditor'; + +const EnumSqlParamsType = { + auth: '权限变量', + query: '查询变量', +}; + +const EnumSqlValueType = { + string: '字符串', + sql: 'SQL表达式', + date: '日期', + boolean: '布尔', + number: '数字', +}; + +const { Option } = Select; + +const ParamsTextArea: FC = ({ value, onChange }) => { + return ( +