mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-20 06:34:55 +00:00
[improvement][semantic-fe] Optimizing the logic for setting dimension values and editing data sources, and adding system settings functionality (#383)
* [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
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React, { ReactNode, useEffect, useRef, useState } from 'react';
|
||||
import { Form, Button, Modal, Steps, message } from 'antd';
|
||||
import DataSourceBasicForm from './DataSourceBasicForm';
|
||||
import FieldForm from './DataSourceFieldForm';
|
||||
import { formLayout } from '@/components/FormHelper/utils';
|
||||
import { EnumDataSourceType } from '../constants';
|
||||
// import type { DataInstanceItem } from '../data';
|
||||
import styles from '../style.less';
|
||||
import { createDatasource, updateDatasource, getColumns } from '../../service';
|
||||
import type { Dispatch } from 'umi';
|
||||
@@ -17,13 +16,15 @@ export type CreateFormProps = {
|
||||
dispatch: Dispatch;
|
||||
createModalVisible: boolean;
|
||||
sql?: string;
|
||||
databaseItem?: any;
|
||||
databaseId?: number;
|
||||
dataSourceItem: IDataSource.IDataSourceItem;
|
||||
onCancel?: () => void;
|
||||
onSubmit?: (dataSourceInfo: any) => void;
|
||||
scriptColumns?: any[] | undefined;
|
||||
basicInfoFormMode?: 'normal' | 'fast';
|
||||
onDataBaseTableChange?: (tableName: string) => void;
|
||||
onDataSourceBtnClick?: () => void;
|
||||
// modalSolt: ReactNode;
|
||||
};
|
||||
const { Step } = Steps;
|
||||
|
||||
@@ -41,8 +42,10 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
sql = '',
|
||||
onSubmit,
|
||||
dataSourceItem,
|
||||
databaseItem,
|
||||
databaseId,
|
||||
basicInfoFormMode,
|
||||
onDataSourceBtnClick,
|
||||
children,
|
||||
}) => {
|
||||
const isEdit = !!dataSourceItem?.id;
|
||||
const [fields, setFields] = useState<any[]>([]);
|
||||
@@ -145,7 +148,7 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
);
|
||||
return classify;
|
||||
};
|
||||
const handleNext = async () => {
|
||||
const handleNext = async (saveState: boolean = false) => {
|
||||
const fieldsValue = await form.validateFields();
|
||||
|
||||
const fieldsClassify = getFieldsClassify(fields);
|
||||
@@ -155,7 +158,7 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
...fieldsClassify,
|
||||
};
|
||||
updateFormVal(submitForm);
|
||||
if (currentStep < 1) {
|
||||
if (!saveState && currentStep < 1) {
|
||||
forward();
|
||||
} else {
|
||||
setSaveLoading(true);
|
||||
@@ -163,7 +166,7 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
const queryParams = {
|
||||
...submitForm,
|
||||
sqlQuery: sql,
|
||||
databaseId: databaseItem?.key || dataSourceItem?.databaseId || formDatabaseId,
|
||||
databaseId: databaseId || dataSourceItem?.databaseId || formDatabaseId,
|
||||
queryType: basicInfoFormMode === 'fast' ? 'table_query' : 'sql_query',
|
||||
tableQuery: dbName && tableName ? `${dbName}.${tableName}` : '',
|
||||
modelId: isEdit ? dataSourceItem.modelId : modelId,
|
||||
@@ -191,7 +194,6 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
return {
|
||||
...oldItem,
|
||||
bizName: nameEn,
|
||||
// name,
|
||||
sqlType: type,
|
||||
};
|
||||
});
|
||||
@@ -264,7 +266,7 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
} else {
|
||||
initFields([], fieldColumns);
|
||||
}
|
||||
}, [dataSourceItem]);
|
||||
}, [dataSourceItem, fieldColumns]);
|
||||
|
||||
const handleFieldChange = (fieldName: string, data: any) => {
|
||||
const result = fields.map((field) => {
|
||||
@@ -285,7 +287,6 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
const { code, data, msg } = await getColumns(databaseId, dbName, tableName);
|
||||
if (code === 200) {
|
||||
const list = data?.resultList || [];
|
||||
// setTableNameList(list);
|
||||
const columns = list.map((item: any) => {
|
||||
const { dataType, name } = item;
|
||||
return {
|
||||
@@ -293,7 +294,6 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
type: dataType,
|
||||
};
|
||||
});
|
||||
// setFields(columns);
|
||||
initFields([], columns);
|
||||
setFieldColumns(columns);
|
||||
return columns;
|
||||
@@ -327,14 +327,25 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
<Button style={{ float: 'left' }} onClick={backward}>
|
||||
上一步
|
||||
</Button>
|
||||
<Button onClick={onCancel}>取消</Button>
|
||||
<Button onClick={onCancel}>取 消</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
onDataSourceBtnClick?.();
|
||||
}}
|
||||
>
|
||||
数据源编辑
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="primary"
|
||||
loading={saveLoading}
|
||||
onClick={handleNext}
|
||||
onClick={() => {
|
||||
handleNext(true);
|
||||
}}
|
||||
disabled={hasEmptyNameField}
|
||||
>
|
||||
完成
|
||||
保 存
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
@@ -342,9 +353,26 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
return (
|
||||
<>
|
||||
<Button onClick={onCancel}>取消</Button>
|
||||
<Button type="primary" onClick={handleNext}>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
handleNext();
|
||||
}}
|
||||
>
|
||||
下一步
|
||||
</Button>
|
||||
{isEdit && (
|
||||
<Button
|
||||
type="primary"
|
||||
loading={saveLoading}
|
||||
onClick={() => {
|
||||
handleNext(true);
|
||||
}}
|
||||
// disabled={hasEmptyNameField}
|
||||
>
|
||||
保 存
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -383,6 +411,7 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
>
|
||||
{renderContent()}
|
||||
</Form>
|
||||
{children}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ 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 DataSourceCreateForm from './DataSourceCreateForm';
|
||||
import type { Dispatch } from 'umi';
|
||||
import type { StateType } from '../../model';
|
||||
import styles from '../style.less';
|
||||
@@ -29,13 +29,19 @@ import 'ace-builds/src-min-noconflict/theme-monokai';
|
||||
import 'ace-builds/src-min-noconflict/mode-sql';
|
||||
import { IDataSource, ISemantic } from '../../data';
|
||||
|
||||
export type DataSourceSubmitData = {
|
||||
sql: string;
|
||||
databaseId: number;
|
||||
columns: any[];
|
||||
};
|
||||
|
||||
type IProps = {
|
||||
domainManger: StateType;
|
||||
dispatch: Dispatch;
|
||||
dataSourceItem: IDataSource.IDataSourceItem;
|
||||
onUpdateSql?: (sql: string) => void;
|
||||
sql?: string;
|
||||
onSubmitSuccess?: (dataSourceInfo: any) => void;
|
||||
onSubmitSuccess?: (dataSourceInfo: DataSourceSubmitData) => void;
|
||||
};
|
||||
|
||||
type ResultTableItem = Record<string, any>;
|
||||
@@ -48,7 +54,7 @@ type ResultColItem = {
|
||||
|
||||
type ScreenSize = 'small' | 'middle' | 'large';
|
||||
|
||||
type JdbcSourceItems = {
|
||||
type DatabaseItem = {
|
||||
label: string;
|
||||
key: number;
|
||||
};
|
||||
@@ -60,7 +66,7 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
sql = '',
|
||||
onUpdateSql,
|
||||
}) => {
|
||||
const { databaseConfigList, selectModelId: modelId } = domainManger;
|
||||
const { databaseConfigList } = domainManger;
|
||||
const [resultTable, setResultTable] = useState<ResultTableItem[]>([]);
|
||||
const [resultTableLoading, setResultTableLoading] = useState(false);
|
||||
const [resultCols, setResultCols] = useState<ResultColItem[]>([]);
|
||||
@@ -69,9 +75,9 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
});
|
||||
const [jdbcSourceItems, setJdbcSourceItems] = useState<JdbcSourceItems[]>([]);
|
||||
const [currentJdbcSourceItem, setCurrentJdbcSourceItem] = useState<JdbcSourceItems>();
|
||||
const [dataSourceModalVisible, setDataSourceModalVisible] = useState(false);
|
||||
const [dataBaseItems, setDataBaseItems] = useState<DatabaseItem[]>([]);
|
||||
const [currentDatabaseItem, setCurrentDatabaseItem] = useState<DatabaseItem>();
|
||||
// const [dataSourceModalVisible, setDataSourceModalVisible] = useState(false);
|
||||
|
||||
const [tableScroll, setTableScroll] = useState({
|
||||
scrollToFirstRowOnChange: true,
|
||||
@@ -107,7 +113,7 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
disabled: !item.hasUsePermission,
|
||||
};
|
||||
});
|
||||
setJdbcSourceItems(list);
|
||||
setDataBaseItems(list);
|
||||
let targetDataBase = list[0];
|
||||
if (dataSourceItem?.id) {
|
||||
const { databaseId } = dataSourceItem;
|
||||
@@ -116,12 +122,12 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
targetDataBase = target;
|
||||
}
|
||||
}
|
||||
setCurrentJdbcSourceItem(targetDataBase);
|
||||
setCurrentDatabaseItem(targetDataBase);
|
||||
}, [dataSourceItem, databaseConfigList]);
|
||||
|
||||
useEffect(() => {
|
||||
setRunState(undefined);
|
||||
}, [currentJdbcSourceItem]);
|
||||
}, [currentDatabaseItem, sql]);
|
||||
|
||||
function creatCalcItem(key: string, data: string) {
|
||||
const line = document.createElement('div'); // 需要每条数据一行,这样避免数据换行的时候获得的宽度不准确
|
||||
@@ -223,18 +229,16 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
};
|
||||
|
||||
const separateSql = async (value: string) => {
|
||||
if (!currentJdbcSourceItem?.key) {
|
||||
if (!currentDatabaseItem?.key) {
|
||||
return;
|
||||
}
|
||||
setResultTableLoading(true);
|
||||
const { code, data, msg } = await excuteSql({
|
||||
sql: value,
|
||||
// modelId,
|
||||
id: currentJdbcSourceItem.key,
|
||||
id: currentDatabaseItem.key,
|
||||
});
|
||||
setResultTableLoading(false);
|
||||
if (code === 200) {
|
||||
// setDataSourceResult(data);
|
||||
fetchTaskResult(data);
|
||||
setRunState(true);
|
||||
} else {
|
||||
@@ -268,13 +272,13 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
return isPartial ? separateSql(partialSql) : separateSql(sql);
|
||||
};
|
||||
|
||||
const showDataSetModal = () => {
|
||||
setDataSourceModalVisible(true);
|
||||
};
|
||||
// const showDataSetModal = () => {
|
||||
// setDataSourceModalVisible(true);
|
||||
// };
|
||||
|
||||
const startCreatDataSource = async () => {
|
||||
showDataSetModal();
|
||||
};
|
||||
// const startCreatDataSource = async () => {
|
||||
// showDataSetModal();
|
||||
// };
|
||||
|
||||
const updateNormalResScroll = () => {
|
||||
const node = resultInnerWrap?.current;
|
||||
@@ -386,14 +390,14 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
<Tooltip title="数据类型">
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: jdbcSourceItems,
|
||||
items: dataBaseItems,
|
||||
onClick: (e) => {
|
||||
const value = e.key;
|
||||
const target: any = jdbcSourceItems.filter((item: any) => {
|
||||
const target: any = dataBaseItems.filter((item: any) => {
|
||||
return item.key === Number(value);
|
||||
})[0];
|
||||
if (target) {
|
||||
setCurrentJdbcSourceItem(target);
|
||||
setCurrentDatabaseItem(target);
|
||||
}
|
||||
},
|
||||
}}
|
||||
@@ -402,7 +406,7 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
<Button style={{ marginRight: '15px', minWidth: '140px' }}>
|
||||
<Space>
|
||||
<CloudServerOutlined className={styles.sqlOprIcon} style={{ marginRight: 0 }} />
|
||||
<span>{currentJdbcSourceItem?.label}</span>
|
||||
<span>{currentDatabaseItem?.label}</span>
|
||||
</Space>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
@@ -464,7 +468,7 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
<div className={`${styles.sqlBottmWrap} ${screenSize}`}>
|
||||
<div className={styles.sqlResultWrap}>
|
||||
<div className={styles.sqlToolBar}>
|
||||
{
|
||||
{/* {
|
||||
<Button
|
||||
className={styles.sqlToolBtn}
|
||||
type="primary"
|
||||
@@ -473,7 +477,21 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
>
|
||||
生成数据源
|
||||
</Button>
|
||||
}
|
||||
} */}
|
||||
<Button
|
||||
className={styles.sqlToolBtn}
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
onSubmitSuccess?.({
|
||||
columns: scriptColumns,
|
||||
databaseId: currentDatabaseItem?.key || 0,
|
||||
sql,
|
||||
});
|
||||
}}
|
||||
disabled={!runState}
|
||||
>
|
||||
完成
|
||||
</Button>
|
||||
<Button
|
||||
className={styles.sqlToolBtn}
|
||||
type="primary"
|
||||
@@ -498,23 +516,6 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
</SplitPane>
|
||||
|
||||
{dataSourceModalVisible && (
|
||||
<DataSourceCreateForm
|
||||
sql={sql}
|
||||
databaseItem={currentJdbcSourceItem}
|
||||
dataSourceItem={dataSourceItem}
|
||||
scriptColumns={scriptColumns}
|
||||
onCancel={() => {
|
||||
setDataSourceModalVisible(false);
|
||||
}}
|
||||
onSubmit={(dataSourceInfo: any) => {
|
||||
setDataSourceModalVisible(false);
|
||||
onSubmitSuccess?.(dataSourceInfo);
|
||||
}}
|
||||
createModalVisible={dataSourceModalVisible}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import { Tabs } from 'antd';
|
||||
import SqlDetail from './SqlDetail';
|
||||
import SqlDetail, { DataSourceSubmitData } from './SqlDetail';
|
||||
|
||||
import styles from '../style.less';
|
||||
|
||||
@@ -22,7 +22,7 @@ type TableRef = {
|
||||
|
||||
type Props = {
|
||||
initialValues: any;
|
||||
onSubmitSuccess?: (dataSourceInfo: any) => void;
|
||||
onSubmitSuccess?: (dataSourceInfo: DataSourceSubmitData) => void;
|
||||
};
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
@@ -105,7 +105,6 @@ const SqlSide: React.FC<Props> = ({ initialValues, onSubmitSuccess }) => {
|
||||
})}
|
||||
</Tabs>
|
||||
</div>
|
||||
{/* </SplitPane> */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,10 +4,11 @@ import SqlSide from './components/SqlSide';
|
||||
import Pane from 'react-split-pane/lib/Pane';
|
||||
import styles from './style.less';
|
||||
import { RightOutlined, LeftOutlined } from '@ant-design/icons';
|
||||
import { DataSourceSubmitData } from './components/SqlDetail';
|
||||
|
||||
type Props = {
|
||||
initialValues: any;
|
||||
onSubmitSuccess?: (dataSourceInfo: any) => void;
|
||||
onSubmitSuccess?: (dataSourceInfo: DataSourceSubmitData) => void;
|
||||
};
|
||||
|
||||
const DEFAULT_RIGHT_SIZE = '300px';
|
||||
|
||||
Reference in New Issue
Block a user