mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-20 06:34:55 +00:00
[improvement][semantic-fe] Refactor database settings functionality.
This commit is contained in:
@@ -2,30 +2,27 @@ import React, { useEffect, useState } from 'react';
|
||||
import { Form, Input, Spin, Select, message } from 'antd';
|
||||
import type { FormInstance } from 'antd/lib/form';
|
||||
import { getDbNames, getTables } from '../../service';
|
||||
import { ISemantic } from '../../data';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const { TextArea } = Input;
|
||||
|
||||
type Props = {
|
||||
isEdit?: boolean;
|
||||
dataBaseConfig: any;
|
||||
databaseConfigList: ISemantic.IDatabaseItemList;
|
||||
form: FormInstance<any>;
|
||||
tableLoading?: boolean;
|
||||
mode?: 'normal' | 'fast';
|
||||
};
|
||||
|
||||
const DataSourceBasicForm: React.FC<Props> = ({
|
||||
isEdit,
|
||||
dataBaseConfig,
|
||||
tableLoading = false,
|
||||
mode = 'normal',
|
||||
}) => {
|
||||
const DataSourceBasicForm: React.FC<Props> = ({ isEdit, databaseConfigList, mode = 'normal' }) => {
|
||||
const [currentDbLinkConfigId, setCurrentDbLinkConfigId] = useState<number>();
|
||||
const [dbNameList, setDbNameList] = useState<any[]>([]);
|
||||
const [tableNameList, setTableNameList] = useState<any[]>([]);
|
||||
const [currentDbName, setCurrentDbName] = useState<string>('');
|
||||
const [currentTableName, setCurrentTableName] = useState<string>('');
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const queryDbNameList = async (databaseId: number) => {
|
||||
setLoading(true);
|
||||
const { code, data, msg } = await getDbNames(databaseId);
|
||||
setLoading(false);
|
||||
if (code === 200) {
|
||||
const list = data?.resultList || [];
|
||||
setDbNameList(list);
|
||||
@@ -34,7 +31,12 @@ const DataSourceBasicForm: React.FC<Props> = ({
|
||||
}
|
||||
};
|
||||
const queryTableNameList = async (databaseName: string) => {
|
||||
const { code, data, msg } = await getTables(dataBaseConfig.id, databaseName);
|
||||
if (!currentDbLinkConfigId) {
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
const { code, data, msg } = await getTables(currentDbLinkConfigId, databaseName);
|
||||
setLoading(false);
|
||||
if (code === 200) {
|
||||
const list = data?.resultList || [];
|
||||
setTableNameList(list);
|
||||
@@ -42,16 +44,32 @@ const DataSourceBasicForm: React.FC<Props> = ({
|
||||
message.error(msg);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
if (dataBaseConfig?.id) {
|
||||
queryDbNameList(dataBaseConfig.id);
|
||||
}
|
||||
}, [dataBaseConfig]);
|
||||
|
||||
return (
|
||||
<Spin spinning={tableLoading}>
|
||||
<Spin spinning={loading}>
|
||||
{mode === 'fast' && (
|
||||
<>
|
||||
<FormItem
|
||||
name="databaseId"
|
||||
label="数据库连接"
|
||||
rules={[{ required: true, message: '请选择数据库连接' }]}
|
||||
>
|
||||
<Select
|
||||
showSearch
|
||||
placeholder="请选择数据库连接"
|
||||
disabled={isEdit}
|
||||
onChange={(dbLinkConfigId: number) => {
|
||||
queryDbNameList(dbLinkConfigId);
|
||||
setCurrentDbLinkConfigId(dbLinkConfigId);
|
||||
}}
|
||||
>
|
||||
{databaseConfigList.map((item) => (
|
||||
<Select.Option key={item.id} value={item.id} disabled={!item.hasUsePermission}>
|
||||
{item.name}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
name="dbName"
|
||||
label="数据库名"
|
||||
@@ -59,11 +77,10 @@ const DataSourceBasicForm: React.FC<Props> = ({
|
||||
>
|
||||
<Select
|
||||
showSearch
|
||||
placeholder="请选择数据库/表"
|
||||
placeholder="请先选择一个数据库连接"
|
||||
disabled={isEdit}
|
||||
onChange={(dbName: string) => {
|
||||
queryTableNameList(dbName);
|
||||
setCurrentDbName(dbName);
|
||||
}}
|
||||
>
|
||||
{dbNameList.map((item) => (
|
||||
@@ -78,15 +95,7 @@ const DataSourceBasicForm: React.FC<Props> = ({
|
||||
label="数据表名"
|
||||
rules={[{ required: true, message: '请选择数据库/表' }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择数据库/表"
|
||||
disabled={isEdit}
|
||||
showSearch
|
||||
onChange={(tableName: string) => {
|
||||
// queryTableNameList(tableName);
|
||||
setCurrentTableName(tableName);
|
||||
}}
|
||||
>
|
||||
<Select placeholder="请选择数据库/表" disabled={isEdit} showSearch>
|
||||
{tableNameList.map((item) => (
|
||||
<Select.Option key={item.name} value={item.name}>
|
||||
{item.name}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Form, Button, Modal, Steps, message } from 'antd';
|
||||
import BasicInfoForm from './DataSourceBasicForm';
|
||||
import DataSourceBasicForm from './DataSourceBasicForm';
|
||||
import FieldForm from './DataSourceFieldForm';
|
||||
import { formLayout } from '@/components/FormHelper/utils';
|
||||
import { EnumDataSourceType } from '../constants';
|
||||
@@ -46,9 +46,10 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
const [currentStep, setCurrentStep] = useState(0);
|
||||
const [saveLoading, setSaveLoading] = useState(false);
|
||||
const [hasEmptyNameField, setHasEmptyNameField] = useState<boolean>(false);
|
||||
const [formDatabaseId, setFormDatabaseId] = useState<number>();
|
||||
const formValRef = useRef(initFormVal as any);
|
||||
const [form] = Form.useForm();
|
||||
const { dataBaseConfig, selectModelId: modelId } = domainManger;
|
||||
const { databaseConfigList, selectModelId: modelId } = domainManger;
|
||||
const updateFormVal = (val: any) => {
|
||||
formValRef.current = val;
|
||||
};
|
||||
@@ -82,11 +83,13 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
bizName,
|
||||
timeGranularity,
|
||||
agg,
|
||||
isCreateDimension,
|
||||
isCreateDimension: createDimension,
|
||||
name,
|
||||
isCreateMetric,
|
||||
isCreateMetric: createMetric,
|
||||
dateFormat,
|
||||
} = item;
|
||||
const isCreateDimension = createDimension ? 1 : 0;
|
||||
const isCreateMetric = createMetric ? 1 : 0;
|
||||
switch (type) {
|
||||
case EnumDataSourceType.CATEGORICAL:
|
||||
fieldsClassify.dimensions.push({
|
||||
@@ -157,7 +160,7 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
const queryParams = {
|
||||
...submitForm,
|
||||
sqlQuery: sql,
|
||||
databaseId: dataSourceItem?.databaseId || dataBaseConfig.id,
|
||||
databaseId: dataSourceItem?.databaseId || formDatabaseId,
|
||||
queryType: basicInfoFormMode === 'fast' ? 'table_query' : 'sql_query',
|
||||
tableQuery: dbName && tableName ? `${dbName}.${tableName}` : '',
|
||||
modelId,
|
||||
@@ -217,7 +220,7 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
if (queryType === 'table_query') {
|
||||
const tableQueryString = tableQuery || '';
|
||||
const [dbName, tableName] = tableQueryString.split('.');
|
||||
columns = await queryTableColumnList(dbName, tableName);
|
||||
columns = await queryTableColumnList(dataSourceItem.databaseId, dbName, tableName);
|
||||
tableQueryInitValue = {
|
||||
dbName,
|
||||
tableName,
|
||||
@@ -227,13 +230,14 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
};
|
||||
|
||||
const formatterInitData = (columns: any[], extendParams: Record<string, any> = {}) => {
|
||||
const { id, name, bizName, description, datasourceDetail } = dataSourceItem as any;
|
||||
const { id, name, bizName, description, datasourceDetail, databaseId } = dataSourceItem as any;
|
||||
const { dimensions, identifiers, measures } = datasourceDetail;
|
||||
const initValue = {
|
||||
id,
|
||||
name,
|
||||
bizName,
|
||||
description,
|
||||
databaseId,
|
||||
...extendParams,
|
||||
// ...tableQueryInitValue,
|
||||
};
|
||||
@@ -274,11 +278,8 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
setFields(result);
|
||||
};
|
||||
|
||||
const queryTableColumnList = async (dbName: string, tableName: string) => {
|
||||
if (!dataBaseConfig?.id) {
|
||||
return;
|
||||
}
|
||||
const { code, data, msg } = await getColumns(dataBaseConfig.id, dbName, tableName);
|
||||
const queryTableColumnList = async (databaseId: number, dbName: string, tableName: string) => {
|
||||
const { code, data, msg } = await getColumns(databaseId, dbName, tableName);
|
||||
if (code === 200) {
|
||||
const list = data?.resultList || [];
|
||||
// setTableNameList(list);
|
||||
@@ -299,16 +300,20 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
};
|
||||
|
||||
const renderContent = () => {
|
||||
if (currentStep === 1) {
|
||||
return <FieldForm fields={fields} onFieldChange={handleFieldChange} />;
|
||||
}
|
||||
return (
|
||||
<BasicInfoForm
|
||||
form={form}
|
||||
isEdit={isEdit}
|
||||
mode={basicInfoFormMode}
|
||||
dataBaseConfig={dataBaseConfig}
|
||||
/>
|
||||
<>
|
||||
<div style={{ display: currentStep === 1 ? 'block' : 'none' }}>
|
||||
<FieldForm fields={fields} onFieldChange={handleFieldChange} />;
|
||||
</div>
|
||||
<div style={{ display: currentStep !== 1 ? 'block' : 'none' }}>
|
||||
<DataSourceBasicForm
|
||||
form={form}
|
||||
isEdit={isEdit}
|
||||
mode={basicInfoFormMode}
|
||||
databaseConfigList={databaseConfigList}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -365,9 +370,10 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
||||
}}
|
||||
onValuesChange={(value, values) => {
|
||||
const { tableName } = value;
|
||||
const { dbName } = values;
|
||||
const { dbName, databaseId } = values;
|
||||
setFormDatabaseId(databaseId);
|
||||
if (tableName) {
|
||||
queryTableColumnList(dbName, tableName);
|
||||
queryTableColumnList(databaseId, dbName, tableName);
|
||||
}
|
||||
}}
|
||||
className={styles.form}
|
||||
|
||||
@@ -230,9 +230,12 @@ const FieldForm: React.FC<Props> = ({ fields, onFieldChange }) => {
|
||||
style={{ marginBottom: '10px' }}
|
||||
banner
|
||||
message={
|
||||
<Marquee pauseOnHover gradient={false}>
|
||||
为了保障同一个主题域下维度/指标列表唯一,消除歧义,若本主题域下的多个数据源存在相同的字段名并且都勾选了快速创建,系统默认这些相同字段的指标维度是同一个,同时列表中将只显示最后一次创建的指标/维度。
|
||||
</Marquee>
|
||||
<div>
|
||||
为了保障同一个模型下维度/指标列表唯一,消除歧义,若本模型下的多个数据源存在相同的字段名并且都勾选了快速创建,系统默认这些相同字段的指标维度是同一个,同时列表中将只显示最后一次创建的指标/维度。
|
||||
</div>
|
||||
// <Marquee pauseOnHover gradient={false}>
|
||||
// 为了保障同一个主题域下维度/指标列表唯一,消除歧义,若本主题域下的多个数据源存在相同的字段名并且都勾选了快速创建,系统默认这些相同字段的指标维度是同一个,同时列表中将只显示最后一次创建的指标/维度。
|
||||
// </Marquee>
|
||||
}
|
||||
/>
|
||||
<Table<FieldItem>
|
||||
|
||||
@@ -27,11 +27,12 @@ import 'ace-builds/src-min-noconflict/ext-searchbox';
|
||||
import 'ace-builds/src-min-noconflict/theme-sqlserver';
|
||||
import 'ace-builds/src-min-noconflict/theme-monokai';
|
||||
import 'ace-builds/src-min-noconflict/mode-sql';
|
||||
import { IDataSource, ISemantic } from '../../data';
|
||||
|
||||
type IProps = {
|
||||
domainManger: StateType;
|
||||
dispatch: Dispatch;
|
||||
dataSourceItem: DataInstanceItem;
|
||||
dataSourceItem: IDataSource.IDataSourceItem;
|
||||
onUpdateSql?: (sql: string) => void;
|
||||
sql?: string;
|
||||
onSubmitSuccess?: (dataSourceInfo: any) => void;
|
||||
@@ -61,7 +62,7 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
onUpdateSql,
|
||||
onJdbcSourceChange,
|
||||
}) => {
|
||||
const { dataBaseConfig, selectModelId: modelId } = domainManger;
|
||||
const { databaseConfigList, selectModelId: modelId } = domainManger;
|
||||
const [resultTable, setResultTable] = useState<ResultTableItem[]>([]);
|
||||
const [resultTableLoading, setResultTableLoading] = useState(false);
|
||||
const [resultCols, setResultCols] = useState<ResultColItem[]>([]);
|
||||
@@ -71,6 +72,7 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
total: 0,
|
||||
});
|
||||
const [jdbcSourceItems, setJdbcSourceItems] = useState<JdbcSourceItems[]>([]);
|
||||
const [currentJdbcSourceItem, setCurrentJdbcSourceItem] = useState<JdbcSourceItems>();
|
||||
const [dataSourceModalVisible, setDataSourceModalVisible] = useState(false);
|
||||
|
||||
const [tableScroll, setTableScroll] = useState({
|
||||
@@ -99,15 +101,40 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
|
||||
const [scriptColumns, setScriptColumns] = useState<any[]>([]);
|
||||
|
||||
// useEffect(() => {
|
||||
// const list = databaseConfigList.map((item: ISemantic.IDatabaseItem) => {
|
||||
// return {
|
||||
// label: item.name,
|
||||
// key: item.id,
|
||||
// disabled: !item.hasUsePermission,
|
||||
// };
|
||||
// });
|
||||
// setJdbcSourceItems(list);
|
||||
// const config = list[0];
|
||||
// setCurrentJdbcSourceItem(config);
|
||||
// onJdbcSourceChange?.(config?.key && Number(config?.key));
|
||||
// }, [databaseConfigList]);
|
||||
|
||||
useEffect(() => {
|
||||
setJdbcSourceItems([
|
||||
{
|
||||
label: dataBaseConfig?.name,
|
||||
key: dataBaseConfig?.id,
|
||||
},
|
||||
]);
|
||||
onJdbcSourceChange?.(dataBaseConfig?.id && Number(dataBaseConfig?.id));
|
||||
}, [dataBaseConfig]);
|
||||
const list = databaseConfigList.map((item: ISemantic.IDatabaseItem) => {
|
||||
return {
|
||||
label: item.name,
|
||||
key: item.id,
|
||||
disabled: !item.hasUsePermission,
|
||||
};
|
||||
});
|
||||
setJdbcSourceItems(list);
|
||||
let targetDataBase = list[0];
|
||||
if (dataSourceItem?.id) {
|
||||
const { databaseId } = dataSourceItem;
|
||||
const target = list.find((item) => item.key === databaseId);
|
||||
if (target) {
|
||||
targetDataBase = target;
|
||||
}
|
||||
}
|
||||
setCurrentJdbcSourceItem(targetDataBase);
|
||||
// onJdbcSourceChange?.(targetDataBase?.key && Number(targetDataBase?.key));
|
||||
}, [dataSourceItem, databaseConfigList]);
|
||||
|
||||
function creatCalcItem(key: string, data: string) {
|
||||
const line = document.createElement('div'); // 需要每条数据一行,这样避免数据换行的时候获得的宽度不准确
|
||||
@@ -209,10 +236,14 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
};
|
||||
|
||||
const separateSql = async (value: string) => {
|
||||
if (!currentJdbcSourceItem?.key) {
|
||||
return;
|
||||
}
|
||||
setResultTableLoading(true);
|
||||
const { code, data, msg } = await excuteSql({
|
||||
sql: value,
|
||||
modelId,
|
||||
// modelId,
|
||||
id: currentJdbcSourceItem.key,
|
||||
});
|
||||
setResultTableLoading(false);
|
||||
if (code === 200) {
|
||||
@@ -378,6 +409,7 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
})[0];
|
||||
if (target) {
|
||||
// setJdbcSourceName(target.label);
|
||||
setCurrentJdbcSourceItem(target);
|
||||
onJdbcSourceChange?.(Number(value));
|
||||
}
|
||||
},
|
||||
@@ -387,7 +419,7 @@ const SqlDetail: React.FC<IProps> = ({
|
||||
<Button style={{ marginRight: '15px', minWidth: '140px' }}>
|
||||
<Space>
|
||||
<CloudServerOutlined className={styles.sqlOprIcon} style={{ marginRight: 0 }} />
|
||||
<span>{jdbcSourceItems[0]?.label}</span>
|
||||
<span>{currentJdbcSourceItem?.label}</span>
|
||||
</Space>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
|
||||
@@ -29,10 +29,10 @@ export const TYPE_OPTIONS = [
|
||||
label: '主键',
|
||||
value: EnumDataSourceType.PRIMARY,
|
||||
},
|
||||
{
|
||||
label: '外键',
|
||||
value: EnumDataSourceType.FOREIGN,
|
||||
},
|
||||
// {
|
||||
// label: '外键',
|
||||
// value: EnumDataSourceType.FOREIGN,
|
||||
// },
|
||||
];
|
||||
|
||||
export const AGG_OPTIONS = [
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
// 数据类型
|
||||
export type DataInstanceItem = {
|
||||
sourceInstanceId: number; // 数据实例id
|
||||
sourceInstanceName: string; // 数据实例名
|
||||
defaultSourceId: number; // 查询表需要的默认datasource id
|
||||
bindSourceId: number;
|
||||
};
|
||||
|
||||
// 任务查询结果列
|
||||
export type TaskResultColumn = {
|
||||
name: string;
|
||||
|
||||
Reference in New Issue
Block a user