diff --git a/packages/base/src/data/EmitterKey.ts b/packages/base/src/data/EmitterKey.ts
index 1dfe88a44..492004229 100644
--- a/packages/base/src/data/EmitterKey.ts
+++ b/packages/base/src/data/EmitterKey.ts
@@ -12,7 +12,8 @@ enum EmitterKey {
DMS_Sync_Project_Archived_Status = 'DMS_Sync_Project_Archived_Status',
DMS_Refresh_Export_Data_Workflow = 'DMS_Refresh_Export_Data_Workflow',
DMS_Refresh_Sync_Data_Source = 'DMS_Refresh_Sync_Data_Source',
- DMS_Refresh_Global_Data_Source = 'DMS_Refresh_Global_Data_Source'
+ DMS_Refresh_Global_Data_Source = 'DMS_Refresh_Global_Data_Source',
+ DMS_Batch_Test_Data_Source_Connection = 'DMS_Batch_Test_Data_Source_Connection'
}
export default EmitterKey;
diff --git a/packages/base/src/hooks/useStaticTips/index.data.ts b/packages/base/src/hooks/useStaticTips/index.data.ts
new file mode 100644
index 000000000..c61673f82
--- /dev/null
+++ b/packages/base/src/hooks/useStaticTips/index.data.ts
@@ -0,0 +1,16 @@
+import { ListDBServicesFilterLastConnectionTestStatusEnum } from '@actiontech/shared/lib/api/base/service/DBService/index.enum';
+import { t } from '../../locale';
+
+type IStaticEnumDictionary = {
+ [key in T]: string;
+};
+
+export const databaseTestConnectionStatusDictionary: IStaticEnumDictionary =
+ {
+ [ListDBServicesFilterLastConnectionTestStatusEnum.connect_failed]: t(
+ 'dmsDataSource.batchTestConnection.connectFailed'
+ ),
+ [ListDBServicesFilterLastConnectionTestStatusEnum.connect_success]: t(
+ 'dmsDataSource.batchTestConnection.connectSucceed'
+ )
+ };
diff --git a/packages/base/src/hooks/useStaticTips/index.ts b/packages/base/src/hooks/useStaticTips/index.ts
new file mode 100644
index 000000000..8c39a3651
--- /dev/null
+++ b/packages/base/src/hooks/useStaticTips/index.ts
@@ -0,0 +1,22 @@
+import { ListDBServicesFilterLastConnectionTestStatusEnum } from '@actiontech/shared/lib/api/base/service/DBService/index.enum';
+import { SelectProps } from 'antd';
+import { useMemo } from 'react';
+import { databaseTestConnectionStatusDictionary } from './index.data';
+
+const useStaticTips = () => {
+ const generateDatabaseTestConnectionStatusSelectOptions: SelectProps['options'] =
+ useMemo(() => {
+ return Object.values(
+ ListDBServicesFilterLastConnectionTestStatusEnum
+ ).map((v) => ({
+ label: databaseTestConnectionStatusDictionary[v],
+ value: v
+ }));
+ }, []);
+
+ return {
+ generateDatabaseTestConnectionStatusSelectOptions
+ };
+};
+
+export default useStaticTips;
diff --git a/packages/base/src/locale/zh-CN/dmsDataSource.ts b/packages/base/src/locale/zh-CN/dmsDataSource.ts
index d539007eb..c23a69ebf 100644
--- a/packages/base/src/locale/zh-CN/dmsDataSource.ts
+++ b/packages/base/src/locale/zh-CN/dmsDataSource.ts
@@ -10,6 +10,12 @@ export default {
instanceName: '数据源名',
address: '地址',
describe: '描述',
+ lastTestConnectionStatus: '上一次连接状态',
+ lastTestConnectionTime: '测试连通性时间',
+ lastTestConnectionErrorMessage: '测试失败原因',
+ connectSucceed: '连通性测试成功',
+ connectFailed: '连通性测试失败',
+ testConnectionStatusFilterLabel: '数据源连接状态',
role: '角色',
type: '数据源类型',
enabledScanTypes: '启用的扫描类型',
@@ -25,6 +31,7 @@ export default {
addDatabase: '添加数据源',
addDatabaseSuccess: '添加数据源成功',
addDatabaseSuccessGuide: '到数据源列表查看刚刚添加的数据源',
+ batchTestDataSourceConnection: '批量测试数据源连通性',
updateDatabase: {
title: '编辑数据源',
@@ -72,6 +79,13 @@ export default {
errorTitle: '数据源{{instanceName}}连通性测试失败'
},
+ batchTestConnection: {
+ notFoundData: '当前列表无数据!',
+ connectFailed: '连接失败',
+ connectSucceed: '连接成功',
+ batchTestConnectionSuccessTips: '执行批量测试数据源连通性成功!'
+ },
+
deleteDatabase: {
confirmMessage: '确认删除数据源 "{{name}}"?',
deletingDatabase: '正在删除数据源 "{{name}}"...',
diff --git a/packages/base/src/locale/zh-CN/dmsGlobalDataSource.ts b/packages/base/src/locale/zh-CN/dmsGlobalDataSource.ts
index 7972acb21..c8d596537 100644
--- a/packages/base/src/locale/zh-CN/dmsGlobalDataSource.ts
+++ b/packages/base/src/locale/zh-CN/dmsGlobalDataSource.ts
@@ -8,6 +8,8 @@ export default {
instanceName: '数据源名',
projectName: '项目名称',
address: '地址',
+ lastTestConnectionStatus: '上一次连接状态',
+ testConnectionStatusFilterLabel: '数据源连接状态',
describe: '描述',
role: '角色',
type: '数据源类型',
@@ -29,7 +31,15 @@ export default {
deleteSuccessTips: '删除数据源"{{name}}"成功'
},
+ batchTestConnection: {
+ notFoundData: '当前列表无数据!',
+ connectFailed: '连接失败',
+ connectSucceed: '连接成功',
+ batchTestConnectionSuccessTips: '执行批量测试数据源连通性成功!'
+ },
+
addDatabase: '添加数据源',
+ batchTestDataSourceConnection: '批量测试数据源连通性',
backToList: '返回全局数据源列表',
batchImportDataSource: {
buttonText: '批量导入数据源',
diff --git a/packages/base/src/locale/zh-CN/dmsProject.ts b/packages/base/src/locale/zh-CN/dmsProject.ts
index 401be5dac..395bdb5eb 100644
--- a/packages/base/src/locale/zh-CN/dmsProject.ts
+++ b/packages/base/src/locale/zh-CN/dmsProject.ts
@@ -71,10 +71,6 @@ export default {
title: '批量导入数据源',
successTitle: '批量导入数据源成功',
checkSuccess: '校验通过',
- testConnectLabel: '请测试数据源联通性',
- testConnect: '批量测试数据源连通性',
- testConnectSuccess: '测试连通性成功{{count}}个',
- testConnectFail: '测试连通性失败{{count}}个,数据源为{{name}}',
requestAuditErrorMessage:
'当前导入信息存在校验失败,请结合下载文件中的提示进行修改,并重新导入'
},
diff --git a/packages/base/src/page/DataExportManagement/Detail/components/ExportDetail/OverviewList/column.tsx b/packages/base/src/page/DataExportManagement/Detail/components/ExportDetail/OverviewList/column.tsx
index 200cc674b..23f509747 100644
--- a/packages/base/src/page/DataExportManagement/Detail/components/ExportDetail/OverviewList/column.tsx
+++ b/packages/base/src/page/DataExportManagement/Detail/components/ExportDetail/OverviewList/column.tsx
@@ -13,7 +13,7 @@ import { InfoCircleOutlined } from '@actiontech/icons';
export const OverviewListColumn: () => ActiontechTableColumn<
IGetDataExportTask,
- [],
+ unknown,
'db_service'
> = () => {
return [
@@ -21,7 +21,7 @@ export const OverviewListColumn: () => ActiontechTableColumn<
dataIndex: 'db_service',
title: () =>
t('dmsDataExport.detail.exportResult.overview.column.dbService'),
- render: (_, record: IGetDataExportTask) => {
+ render: (_, record) => {
return record.db_info?.name ?? '-';
}
},
@@ -29,7 +29,7 @@ export const OverviewListColumn: () => ActiontechTableColumn<
dataIndex: 'status',
title: () =>
t('dmsDataExport.detail.exportResult.overview.column.status'),
- render: (status: IGetDataExportTask['status']) => {
+ render: (status) => {
return ;
}
},
@@ -37,25 +37,25 @@ export const OverviewListColumn: () => ActiontechTableColumn<
dataIndex: 'export_type',
title: () =>
t('dmsDataExport.detail.exportResult.overview.column.exportType'),
- render: (type: string) => type ?? '-'
+ render: (type) => type ?? '-'
},
{
dataIndex: 'export_file_type',
title: () =>
t('dmsDataExport.detail.exportResult.overview.column.exportFileType'),
- render: (type: string) => type ?? '-'
+ render: (type) => type ?? '-'
},
{
dataIndex: 'export_start_time',
title: () =>
t('dmsDataExport.detail.exportResult.overview.column.exportStartTime'),
- render: (time: string) => formatTime(time, '-')
+ render: (time) => formatTime(time, '-')
},
{
dataIndex: 'export_end_time',
title: () =>
t('dmsDataExport.detail.exportResult.overview.column.exportEndTime'),
- render: (time: string) => formatTime(time, '-')
+ render: (time) => formatTime(time, '-')
}
];
};
diff --git a/packages/base/src/page/DataExportManagement/Detail/components/ExportDetail/OverviewList/index.tsx b/packages/base/src/page/DataExportManagement/Detail/components/ExportDetail/OverviewList/index.tsx
index d98dbedaf..1fb28e90d 100644
--- a/packages/base/src/page/DataExportManagement/Detail/components/ExportDetail/OverviewList/index.tsx
+++ b/packages/base/src/page/DataExportManagement/Detail/components/ExportDetail/OverviewList/index.tsx
@@ -1,7 +1,6 @@
import { ActiontechTable } from '@actiontech/shared/lib/components/ActiontechTable';
import useDataExportDetailReduxManage from '../../../hooks/index.redux';
import { OverviewListAction, OverviewListColumn } from './column';
-import { IGetDataExportTask } from '@actiontech/shared/lib/api/base/service/common';
import DataExportTask from '@actiontech/shared/lib/api/base/service/DataExportTask';
import {
useCurrentProject,
@@ -49,7 +48,7 @@ const OverviewList: React.FC = () => {
? OverviewListAction(downloadLoading, downloadAction)
: undefined
}
- onRow={(record: IGetDataExportTask) => {
+ onRow={(record) => {
return {
onClick() {
updateCurTaskID(record.task_uid ?? '');
diff --git a/packages/base/src/page/DataSource/components/BatchImportDataSource/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataSource/components/BatchImportDataSource/__snapshots__/index.test.tsx.snap
index 3d636a25a..ca48fbfcf 100644
--- a/packages/base/src/page/DataSource/components/BatchImportDataSource/__snapshots__/index.test.tsx.snap
+++ b/packages/base/src/page/DataSource/components/BatchImportDataSource/__snapshots__/index.test.tsx.snap
@@ -288,61 +288,6 @@ exports[`base/DataSource/BatchImportDataSource render check api return csv file
-
@@ -600,61 +545,6 @@ exports[`base/DataSource/BatchImportDataSource render delete file 1`] = `
-
@@ -840,482 +730,6 @@ exports[`base/DataSource/BatchImportDataSource render init snap 1`] = `
-
-
-
-
-
-
-
-
diff --git a/packages/base/src/page/DataSource/components/BatchImportDataSource/index.test.tsx b/packages/base/src/page/DataSource/components/BatchImportDataSource/index.test.tsx
index 4ff843582..18976106b 100644
--- a/packages/base/src/page/DataSource/components/BatchImportDataSource/index.test.tsx
+++ b/packages/base/src/page/DataSource/components/BatchImportDataSource/index.test.tsx
@@ -37,7 +37,6 @@ describe('base/DataSource/BatchImportDataSource', () => {
await act(async () => jest.advanceTimersByTime(300));
expect(baseElement).toMatchSnapshot();
expect(screen.getByText('批量导入数据源')).toBeInTheDocument();
- expect(screen.getByText('批量测试数据源连通性')).toBeInTheDocument();
fireEvent.click(screen.getByText('返回数据源列表'));
});
@@ -114,33 +113,6 @@ describe('base/DataSource/BatchImportDataSource', () => {
expect(baseElement).toMatchSnapshot();
});
- it('render test connection', async () => {
- const { baseElement } = superRender();
- await act(async () => jest.advanceTimersByTime(300));
- expect(
- screen.getByText('批量测试数据源连通性').closest('button')
- ).toBeDisabled();
- const file = new File([''], 'test.csv');
- fireEvent.change(getBySelector('#files', baseElement), {
- target: { files: [file] }
- });
- await act(async () => jest.advanceTimersByTime(100));
- expect(screen.getByText('test.csv')).toBeInTheDocument();
- await act(async () => jest.advanceTimersByTime(3000));
- expect(
- screen.getByText('批量测试数据源连通性').closest('button')
- ).not.toBeDisabled();
- fireEvent.click(screen.getByText('批量测试数据源连通性'));
- await act(async () => jest.advanceTimersByTime(100));
- expect(dbServicesConnectionSpy).toHaveBeenCalledTimes(1);
- await act(async () => jest.advanceTimersByTime(3000));
- expect(screen.getByText('测试连通性成功1个')).toBeInTheDocument();
- expect(
- screen.getByText('测试连通性失败1个,数据源为mysql_1')
- ).toBeInTheDocument();
- expect(baseElement).toMatchSnapshot();
- });
-
it('render upload file', async () => {
const { baseElement } = superRender();
await act(async () => jest.advanceTimersByTime(300));
diff --git a/packages/base/src/page/DataSource/components/BatchImportDataSource/index.tsx b/packages/base/src/page/DataSource/components/BatchImportDataSource/index.tsx
index f04d491f8..81d1a43a4 100644
--- a/packages/base/src/page/DataSource/components/BatchImportDataSource/index.tsx
+++ b/packages/base/src/page/DataSource/components/BatchImportDataSource/index.tsx
@@ -124,7 +124,6 @@ const BatchImportDataSource = () => {
diff --git a/packages/base/src/page/DataSource/components/List/ConnectionResultColumn.tsx b/packages/base/src/page/DataSource/components/List/ConnectionResultColumn.tsx
new file mode 100644
index 000000000..4a94e60dc
--- /dev/null
+++ b/packages/base/src/page/DataSource/components/List/ConnectionResultColumn.tsx
@@ -0,0 +1,74 @@
+import { useTranslation } from 'react-i18next';
+import { BasicTag, BasicToolTips } from '@actiontech/shared';
+import { formatTime } from '@actiontech/shared/lib/utils/Common';
+import { Space, Tag, Typography } from 'antd';
+import { ListDBServiceLastConnectionTestStatusEnum } from '@actiontech/shared/lib/api/base/service/common.enum';
+
+type Props = {
+ connectionStatus?: ListDBServiceLastConnectionTestStatusEnum;
+ connectionTestTime?: string;
+ connectionErrorMessage?: string;
+};
+
+const ConnectionStatusColumn: React.FC = ({
+ connectionStatus,
+ connectionTestTime,
+ connectionErrorMessage
+}) => {
+ const { t } = useTranslation();
+
+ if (
+ connectionStatus ===
+ ListDBServiceLastConnectionTestStatusEnum.connect_success
+ ) {
+ return (
+
+ {t('dmsDataSource.databaseList.lastTestConnectionTime')}:
+ {formatTime(connectionTestTime, '-')}
+
+ }
+ >
+
+ {t('dmsDataSource.databaseList.connectSucceed')}
+
+
+ );
+ }
+
+ if (
+ connectionStatus ===
+ ListDBServiceLastConnectionTestStatusEnum.connect_failed
+ ) {
+ return (
+
+
+ {t('dmsDataSource.databaseList.lastTestConnectionTime')}:
+ {formatTime(connectionTestTime, '-')}
+
+
+
+ {t('dmsDataSource.databaseList.lastTestConnectionErrorMessage')}:
+
+ {connectionErrorMessage}
+
+
+
+ }
+ >
+
+ {t('dmsDataSource.databaseList.connectFailed')}
+
+
+ );
+ }
+
+ return <>->;
+};
+
+export default ConnectionStatusColumn;
diff --git a/packages/base/src/page/DataSource/components/List/__snapshots__/index.ce.test.tsx.snap b/packages/base/src/page/DataSource/components/List/__snapshots__/index.ce.test.tsx.snap
index 61d78f29d..36729d9c3 100644
--- a/packages/base/src/page/DataSource/components/List/__snapshots__/index.ce.test.tsx.snap
+++ b/packages/base/src/page/DataSource/components/List/__snapshots__/index.ce.test.tsx.snap
@@ -17,6 +17,19 @@ exports[`page/DataSource/DataSourceList render list snap 1`] = `
+
+
+
@@ -234,6 +247,7 @@ exports[`page/DataSource/DataSourceList render list snap 1`] = `
+
@@ -254,6 +268,12 @@ exports[`page/DataSource/DataSourceList render list snap 1`] = `
>
地址
+
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
+
@@ -206,6 +210,7 @@ exports[`page/DataSource/DataSourceList render list no permission 1`] = `
+
@@ -226,6 +231,12 @@ exports[`page/DataSource/DataSourceList render list no permission 1`] = `
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
+
+
+
+
@@ -672,6 +706,12 @@ exports[`page/DataSource/DataSourceList render list snap 1`] = `
>
地址
+
+ 上一次连接状态
+ |
| |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+ 数据源连接状态
+
+
+ 请选择{{name}}
+
+
+
+
+
+
+
+
@@ -1273,6 +1394,12 @@ exports[`page/DataSource/DataSourceList render table by filter enable masking 1`
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.13:33061
+
+
+ |
@@ -1493,7 +1647,9 @@ exports[`page/DataSource/DataSourceList render table by filter enable masking 1`
|
|
+ >
+ -
+
10.186.62.13:33062
|
+
+
+ |
@@ -1598,11 +1772,7 @@ exports[`page/DataSource/DataSourceList render table by filter enable masking 1`
|
-
- -
-
+ -
|
| |
+ >
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 数据源连接状态
+
+
+ 请选择{{name}}
+
+
+
+
+
+
+
+
@@ -2265,6 +2509,12 @@ exports[`page/DataSource/DataSourceList render table filter option val 1`] = `
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.13:33061
+
+
+ |
@@ -2485,7 +2762,9 @@ exports[`page/DataSource/DataSourceList render table filter option val 1`] = `
|
|
+ >
+ -
+
10.186.62.13:33062
|
+
+
+ |
@@ -2590,11 +2887,7 @@ exports[`page/DataSource/DataSourceList render table filter option val 1`] = `
|
-
- -
-
+ -
|
| |
+ >
+ -
+
|
+
@@ -3012,6 +3311,7 @@ exports[`page/DataSource/DataSourceList render table for action btn render table
+
@@ -3032,6 +3332,12 @@ exports[`page/DataSource/DataSourceList render table for action btn render table
>
地址
+
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.13:33061
+
+
+ |
@@ -3252,7 +3585,9 @@ exports[`page/DataSource/DataSourceList render table for action btn render table
|
|
+ >
+ -
+
10.186.62.13:33062
|
+
+
+ |
@@ -3315,11 +3668,7 @@ exports[`page/DataSource/DataSourceList render table for action btn render table
|
-
- -
-
+ -
|
| |
+ >
+ -
+
+
+
+
+
@@ -3760,6 +4125,12 @@ exports[`page/DataSource/DataSourceList render table for action btn render table
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.13:33061
+
+
+ |
@@ -3980,7 +4378,9 @@ exports[`page/DataSource/DataSourceList render table for action btn render table
|
|
+ >
+ -
+
+
+
+
+
@@ -4590,6 +5004,12 @@ exports[`page/DataSource/DataSourceList render table for action btn render table
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.13:33061
+
+
+ |
@@ -4810,7 +5257,9 @@ exports[`page/DataSource/DataSourceList render table for action btn render table
|
|
+ >
+ -
+
+
+
+
+
@@ -5420,6 +5883,12 @@ exports[`page/DataSource/DataSourceList render table for api has data 1`] = `
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.13:33061
+
+
+ |
@@ -5640,7 +6136,9 @@ exports[`page/DataSource/DataSourceList render table for api has data 1`] = `
|
|
+ >
+ -
+
10.186.62.13:33062
|
+
+
+ |
@@ -5745,11 +6261,7 @@ exports[`page/DataSource/DataSourceList render table for api has data 1`] = `
|
-
- -
-
+ -
|
| |
+ >
+ -
+
+
+
+
+
@@ -6257,6 +6785,12 @@ exports[`page/DataSource/DataSourceList render table for api has data 2`] = `
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.13:33061
+
+
+ |
@@ -6477,7 +7038,9 @@ exports[`page/DataSource/DataSourceList render table for api has data 2`] = `
|
|
+ >
+ -
+
10.186.62.13:33062
|
+
+
+ |
@@ -6582,11 +7163,7 @@ exports[`page/DataSource/DataSourceList render table for api has data 2`] = `
|
-
- -
-
+ -
|
| |
+ >
+ -
+
+
+
+
+
@@ -7069,6 +7662,12 @@ exports[`page/DataSource/DataSourceList render table for api return no data 1`]
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
+
+
+
+
@@ -7490,6 +8112,12 @@ exports[`page/DataSource/DataSourceList render table for api return no data 2`]
>
地址
+
+ 上一次连接状态
+ |
| |
+
+
+
+
+ |
+
+
+
+
@@ -7911,6 +8562,12 @@ exports[`page/DataSource/DataSourceList render table for column val 1`] = `
>
地址
+
+ 上一次连接状态
+ |
| |
+
+
+
+
+ |
-
+
+ -
+ |
@@ -8168,11 +8839,7 @@ exports[`page/DataSource/DataSourceList render table for column val 1`] = `
|
-
- -
-
+ -
|
=> ({
+ projectID: string,
+ batchTestDatabaseConnection: () => void,
+ batchTestDatabaseConnectionPending: boolean
+): Record<
+ | 'batch-import-data-source'
+ | 'add-data-source'
+ | 'batch-test-data-source-connection',
+ ReactNode
+> => ({
+ 'batch-test-data-source-connection': (
+
+
+
+ ),
'batch-import-data-source': (
t('dmsDataSource.databaseList.lastTestConnectionStatus'),
+ filterCustomType: 'select',
+ filterKey: 'filter_last_connection_test_status',
+ filterLabel: t(
+ 'dmsDataSource.databaseList.testConnectionStatusFilterLabel'
+ ),
+ render: (status, record) => {
+ return (
+
+ );
+ }
+ },
{
dataIndex: 'source',
title: () => t('dmsDataSource.databaseList.source')
@@ -53,7 +69,7 @@ export const DataSourceColumns = (
dataIndex: 'desc',
title: () => t('dmsDataSource.databaseList.describe'),
className: 'ellipsis-column-width',
- render: (desc: string) => {
+ render: (desc) => {
return desc ? : '-';
}
},
@@ -62,7 +78,7 @@ export const DataSourceColumns = (
title: () => t('dmsDataSource.databaseList.type'),
filterCustomType: 'select',
filterKey: 'filter_by_db_type',
- render: (dbType: string) => {
+ render: (dbType) => {
if (!dbType) return '-';
return (
@@ -77,7 +93,10 @@ export const DataSourceColumns = (
{
dataIndex: 'audit_plan_types',
title: () => t('dmsDataSource.databaseList.enabledScanTypes'),
- render: (scanTypes: IAuditPlanTypes[], record) => {
+ render: (scanTypes, record) => {
+ if (!scanTypes || scanTypes.length === 0) {
+ return '-';
+ }
return (
t('dmsDataSource.databaseList.dataMask'),
filterCustomType: 'select',
filterKey: 'is_enable_masking',
- render: (value: boolean) => {
+ render: (value) => {
return value ? t('common.enabled') : t('common.notEnabled');
}
},
@@ -108,7 +127,10 @@ export const DataSourceColumns = (
{
dataIndex: 'maintenance_times',
title: () => t('dmsDataSource.databaseList.maintenanceTime'),
- render(value: IListDBService['maintenance_times']) {
+ render(value) {
+ if (!value || value.length === 0) {
+ return '-';
+ }
return value?.map((time, i) => (
{timeAddZero(time.maintenance_start_time?.hour ?? 0)}:
diff --git a/packages/base/src/page/DataSource/components/List/index.test.tsx b/packages/base/src/page/DataSource/components/List/index.test.tsx
index e7dba851f..8b336c421 100644
--- a/packages/base/src/page/DataSource/components/List/index.test.tsx
+++ b/packages/base/src/page/DataSource/components/List/index.test.tsx
@@ -25,6 +25,7 @@ describe('page/DataSource/DataSourceList', () => {
const projectID = mockProjectInfo.projectID;
const navigateSpy = jest.fn();
const useParamsMock: jest.Mock = useParams as jest.Mock;
+ let CheckProjectDBServicesConnectionsSpy: jest.SpyInstance;
const customRender = (params = {}) => {
return superRender(, undefined, {
@@ -67,6 +68,8 @@ describe('page/DataSource/DataSourceList', () => {
useParamsMock.mockReturnValue({ projectID });
dms.mockAllApi();
dbServices.ListDBServicesTips();
+ CheckProjectDBServicesConnectionsSpy =
+ dbServices.CheckProjectDBServicesConnections();
});
afterEach(() => {
@@ -197,7 +200,7 @@ describe('page/DataSource/DataSourceList', () => {
'.actiontech-table-filter-container-namespace .ant-space-item',
baseElement
);
- expect(filterItems.length).toBe(3);
+ expect(filterItems.length).toBe(4);
expect(baseElement).toMatchSnapshot();
});
@@ -270,9 +273,9 @@ describe('page/DataSource/DataSourceList', () => {
'.actiontech-table-filter-container-namespace .ant-space-item',
baseElement
);
- expect(filterItems.length).toBe(3);
+ expect(filterItems.length).toBe(4);
expect(baseElement).toMatchSnapshot();
- const enableFilterElement = getBySelector('input', filterItems[2]);
+ const enableFilterElement = getBySelector('input', filterItems[3]);
fireEvent.mouseDown(enableFilterElement);
const selectOptions = getAllBySelector('.ant-select-item-option');
await act(async () => {
@@ -288,6 +291,42 @@ describe('page/DataSource/DataSourceList', () => {
});
});
+ it('should display an error message and return if dataSourceList is empty or undefined', async () => {
+ const requestTableList = dms.getListDBServices();
+ requestTableList.mockImplementation(() =>
+ createSpySuccessResponse({ data: [] })
+ );
+ customRender();
+
+ await act(async () => jest.advanceTimersByTime(6300));
+
+ fireEvent.click(screen.getByText('批量测试数据源连通性'));
+ expect(CheckProjectDBServicesConnectionsSpy).toHaveBeenCalledTimes(0);
+ expect(screen.getByText('当前列表无数据!')).toBeInTheDocument();
+ });
+
+ it('should initiate the connection test and call DBService.CheckProjectDBServicesConnections when dataSourceList has valid data sources', async () => {
+ const requestTableList = dms.getListDBServices();
+ customRender();
+
+ await act(async () => jest.advanceTimersByTime(6300));
+
+ fireEvent.click(screen.getByText('批量测试数据源连通性'));
+ expect(CheckProjectDBServicesConnectionsSpy).toHaveBeenCalledTimes(1);
+ expect(CheckProjectDBServicesConnectionsSpy).toHaveBeenCalledWith({
+ project_uid: projectID,
+ db_services: DBServicesList.map((v) => ({
+ db_service_uid: v.uid!
+ }))
+ });
+
+ await act(async () => jest.advanceTimersByTime(3000));
+ expect(requestTableList).toHaveBeenCalledTimes(2);
+ expect(
+ screen.getByText('执行批量测试数据源连通性成功!')
+ ).toBeInTheDocument();
+ });
+
describe('render table for action btn', () => {
it('render table for edit action', async () => {
const requestTableList = dms.getListDBServices();
diff --git a/packages/base/src/page/DataSource/components/List/index.tsx b/packages/base/src/page/DataSource/components/List/index.tsx
index 2f89c0633..e7325f5a7 100644
--- a/packages/base/src/page/DataSource/components/List/index.tsx
+++ b/packages/base/src/page/DataSource/components/List/index.tsx
@@ -12,7 +12,7 @@ import {
useDbServiceDriver
} from '@actiontech/shared/lib/global';
import useDbService from '../../../../hooks/useDbService';
-import { useRequest } from 'ahooks';
+import { useBoolean, useRequest } from 'ahooks';
import DBService from '@actiontech/shared/lib/api/base/service/DBService';
import { ResponseCode } from '@actiontech/shared/lib/enum';
import {
@@ -34,6 +34,7 @@ import {
import usePermission from '@actiontech/shared/lib/global/usePermission/usePermission';
import { DataSourceListActions, DataSourcePageHeaderActions } from './actions';
import { ROUTE_PATHS } from '@actiontech/shared/lib/data/routePaths';
+import useStaticTips from '../../../../hooks/useStaticTips';
const DataSourceList = () => {
const { t } = useTranslation();
@@ -45,6 +46,11 @@ const DataSourceList = () => {
const { parse2TableActionPermissions } = usePermission();
const { projectID } = useCurrentProject();
+ const [
+ batchTestDatabaseConnectionPending,
+ { setFalse: finishTestConnection, setTrue: startTestConnection }
+ ] = useBoolean();
+
const {
dbDriverOptions,
getLogoUrlByDbType,
@@ -57,6 +63,8 @@ const DataSourceList = () => {
updateDbServiceList
} = useDbService();
+ const { generateDatabaseTestConnectionStatusSelectOptions } = useStaticTips();
+
const {
tableFilterInfo,
updateTableFilterInfo,
@@ -214,6 +222,34 @@ const DataSourceList = () => {
[messageApi, modalApi, projectID, t]
);
+ const batchTestDatabaseConnection = () => {
+ if (!dataSourceList?.list || dataSourceList.list.length === 0) {
+ messageApi.error(t('dmsDataSource.batchTestConnection.notFoundData'));
+ return;
+ }
+ startTestConnection();
+ DBService.CheckProjectDBServicesConnections({
+ project_uid: projectID,
+ db_services:
+ dataSourceList?.list?.map((v) => ({
+ db_service_uid: v.uid!
+ })) ?? []
+ })
+ .then((res) => {
+ if (res.data.code === ResponseCode.SUCCESS) {
+ refresh();
+ messageApi.success(
+ t(
+ 'dmsDataSource.batchTestConnection.batchTestConnectionSuccessTips'
+ )
+ );
+ }
+ })
+ .finally(() => {
+ finishTestConnection();
+ });
+ };
+
const columns = useMemo(
() => DataSourceColumns(getLogoUrlByDbType),
[getLogoUrlByDbType]
@@ -232,6 +268,10 @@ const DataSourceList = () => {
'db_type',
{ options: dbDriverOptions, loading: getDriveOptionsLoading }
],
+ [
+ 'last_connection_test_status',
+ { options: generateDatabaseTestConnectionStatusSelectOptions }
+ ],
// #if [dms]
['is_enable_masking', { options: filterDataMaskOptions }]
// #endif
@@ -239,6 +279,7 @@ const DataSourceList = () => {
}, [
dbDriverOptions,
dbServiceOptions,
+ generateDatabaseTestConnectionStatusSelectOptions,
getDbServiceOptionsLoading,
getDriveOptionsLoading
]);
@@ -259,7 +300,11 @@ const DataSourceList = () => {
testDatabaseConnection,
navigateToSqlManagementConf
]);
- const pageHeaderActions = DataSourcePageHeaderActions(projectID);
+ const pageHeaderActions = DataSourcePageHeaderActions(
+ projectID,
+ batchTestDatabaseConnection,
+ batchTestDatabaseConnectionPending
+ );
useEffect(() => {
if (projectID) {
@@ -277,6 +322,7 @@ const DataSourceList = () => {
title={t('dmsDataSource.databaseListTitle')}
extra={
+ {pageHeaderActions['batch-test-data-source-connection']}
{/* #if [ee] */}
{pageHeaderActions['batch-import-data-source']}
{/* #endif */}
diff --git a/packages/base/src/page/DataSourceManagement/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataSourceManagement/__tests__/__snapshots__/index.test.tsx.snap
index 3a5a43329..00677a35f 100644
--- a/packages/base/src/page/DataSourceManagement/__tests__/__snapshots__/index.test.tsx.snap
+++ b/packages/base/src/page/DataSourceManagement/__tests__/__snapshots__/index.test.tsx.snap
@@ -47,16 +47,106 @@ exports[`test DataSourceManagement should match snapshot 1`] = `
@@ -280,6 +370,12 @@ exports[`test DataSourceManagement should match snapshot 1`] = `
>
地址
+
+ 上一次连接状态
+ |
| |
+
+
+
+
+ |
diff --git a/packages/base/src/page/DataSourceManagement/__tests__/index.test.tsx b/packages/base/src/page/DataSourceManagement/__tests__/index.test.tsx
index 3dee1b50f..8641a5b22 100644
--- a/packages/base/src/page/DataSourceManagement/__tests__/index.test.tsx
+++ b/packages/base/src/page/DataSourceManagement/__tests__/index.test.tsx
@@ -26,7 +26,10 @@ describe('test DataSourceManagement', () => {
syncTaskList.mockAllApi();
(useNavigate as jest.Mock).mockImplementation(() => navigateSpy);
mockUsePermission(
- { checkPagePermission: jest.fn().mockReturnValue(true) },
+ {
+ checkPagePermission: jest.fn().mockReturnValue(true),
+ checkActionPermission: jest.fn().mockReturnValue(true)
+ },
{ useSpyOnMockHooks: true }
);
});
@@ -69,6 +72,26 @@ describe('test DataSourceManagement', () => {
);
});
+ it('should send emit event when click batch test connect button', () => {
+ const emitSpy = jest.spyOn(eventEmitter, 'emit');
+
+ const { getByText } = superRender();
+
+ fireEvent.click(getByText('批量测试数据源连通性'));
+
+ expect(emitSpy).toHaveBeenCalledTimes(1);
+ expect(emitSpy).toHaveBeenCalledWith(
+ EmitterKey.DMS_Batch_Test_Data_Source_Connection
+ );
+
+ fireEvent.click(getByText('外部数据源同步'));
+ fireEvent.click(getBySelector('.custom-icon-refresh'));
+ expect(emitSpy).toHaveBeenCalledTimes(2);
+ expect(emitSpy).toHaveBeenCalledWith(
+ EmitterKey.DMS_Refresh_Sync_Data_Source
+ );
+ });
+
it('should not render tabs item when use role is not admin or not project manager', () => {
mockUsePermission(
{
diff --git a/packages/base/src/page/DataSourceManagement/action.tsx b/packages/base/src/page/DataSourceManagement/action.tsx
index 637e66e9a..6ba9317dd 100644
--- a/packages/base/src/page/DataSourceManagement/action.tsx
+++ b/packages/base/src/page/DataSourceManagement/action.tsx
@@ -7,9 +7,13 @@ import { t } from '../../locale';
import { ROUTE_PATHS } from '@actiontech/shared/lib/data/routePaths';
export const DataSourceManagementPageHeaderActions = (
- activeKey: DataSourceManagerSegmentedKey
+ activeKey: DataSourceManagerSegmentedKey,
+ onBatchTestConnection: () => void
): Record<
- 'add_sync_task' | 'batch_import_db_service' | 'add_db_service',
+ | 'add_sync_task'
+ | 'batch_import_db_service'
+ | 'add_db_service'
+ | 'batch_test_data_source_connection',
ReactNode
> => {
return {
@@ -52,6 +56,19 @@ export const DataSourceManagementPageHeaderActions = (
link={{ to: ROUTE_PATHS.BASE.GLOBAL_DATA_SOURCE.create }}
/>
+ ),
+ batch_test_data_source_connection: (
+
+
+
)
};
};
diff --git a/packages/base/src/page/DataSourceManagement/index.tsx b/packages/base/src/page/DataSourceManagement/index.tsx
index b97d183fb..17ff2623b 100644
--- a/packages/base/src/page/DataSourceManagement/index.tsx
+++ b/packages/base/src/page/DataSourceManagement/index.tsx
@@ -65,12 +65,19 @@ const DataSourceManagement: React.FC = () => {
}, [checkPagePermission, t]);
// #if [ee]
+ const onBatchTestConnection = () => {
+ eventEmitter.emit(EmitterKey.DMS_Batch_Test_Data_Source_Connection);
+ };
const renderExtra = () => {
- const pageHeaderActions = DataSourceManagementPageHeaderActions(activeKey);
+ const pageHeaderActions = DataSourceManagementPageHeaderActions(
+ activeKey,
+ onBatchTestConnection
+ );
return (
<>
{pageHeaderActions['add_sync_task']}
+ {pageHeaderActions['batch_test_data_source_connection']}
{pageHeaderActions['batch_import_db_service']}
{pageHeaderActions['add_db_service']}
diff --git a/packages/base/src/page/GlobalDataSource/BatchImportDataSource/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/GlobalDataSource/BatchImportDataSource/__tests__/__snapshots__/index.test.tsx.snap
index 26ca108b7..86283df6e 100644
--- a/packages/base/src/page/GlobalDataSource/BatchImportDataSource/__tests__/__snapshots__/index.test.tsx.snap
+++ b/packages/base/src/page/GlobalDataSource/BatchImportDataSource/__tests__/__snapshots__/index.test.tsx.snap
@@ -284,61 +284,6 @@ exports[`base/GlobalDataSource/BatchImportDataSource render check api return csv
-
@@ -592,61 +537,6 @@ exports[`base/GlobalDataSource/BatchImportDataSource render delete file 1`] = `
-
@@ -828,478 +718,6 @@ exports[`base/GlobalDataSource/BatchImportDataSource render init snap 1`] = `
-
-
-
-
- |
-
-
-
diff --git a/packages/base/src/page/GlobalDataSource/BatchImportDataSource/__tests__/index.test.tsx b/packages/base/src/page/GlobalDataSource/BatchImportDataSource/__tests__/index.test.tsx
index e94e88630..e4e30b6d6 100644
--- a/packages/base/src/page/GlobalDataSource/BatchImportDataSource/__tests__/index.test.tsx
+++ b/packages/base/src/page/GlobalDataSource/BatchImportDataSource/__tests__/index.test.tsx
@@ -34,7 +34,6 @@ describe('base/GlobalDataSource/BatchImportDataSource', () => {
await act(async () => jest.advanceTimersByTime(300));
expect(baseElement).toMatchSnapshot();
expect(screen.getByText('批量导入数据源')).toBeInTheDocument();
- expect(screen.getByText('批量测试数据源连通性')).toBeInTheDocument();
fireEvent.click(screen.getByText('返回全局数据源列表'));
});
@@ -111,33 +110,6 @@ describe('base/GlobalDataSource/BatchImportDataSource', () => {
expect(baseElement).toMatchSnapshot();
});
- it('render test connection', async () => {
- const { baseElement } = superRender();
- await act(async () => jest.advanceTimersByTime(300));
- expect(
- screen.getByText('批量测试数据源连通性').closest('button')
- ).toBeDisabled();
- const file = new File([''], 'test.csv');
- fireEvent.change(getBySelector('#files', baseElement), {
- target: { files: [file] }
- });
- await act(async () => jest.advanceTimersByTime(100));
- expect(screen.getByText('test.csv')).toBeInTheDocument();
- await act(async () => jest.advanceTimersByTime(3000));
- expect(
- screen.getByText('批量测试数据源连通性').closest('button')
- ).not.toBeDisabled();
- fireEvent.click(screen.getByText('批量测试数据源连通性'));
- await act(async () => jest.advanceTimersByTime(100));
- expect(dbServicesConnectionSpy).toHaveBeenCalledTimes(1);
- await act(async () => jest.advanceTimersByTime(3000));
- expect(screen.getByText('测试连通性成功1个')).toBeInTheDocument();
- expect(
- screen.getByText('测试连通性失败1个,数据源为mysql_1')
- ).toBeInTheDocument();
- expect(baseElement).toMatchSnapshot();
- });
-
it('render upload file', async () => {
const { baseElement } = superRender();
await act(async () => jest.advanceTimersByTime(300));
diff --git a/packages/base/src/page/GlobalDataSource/BatchImportDataSource/index.tsx b/packages/base/src/page/GlobalDataSource/BatchImportDataSource/index.tsx
index 3c1837f78..8a978cdfa 100644
--- a/packages/base/src/page/GlobalDataSource/BatchImportDataSource/index.tsx
+++ b/packages/base/src/page/GlobalDataSource/BatchImportDataSource/index.tsx
@@ -111,7 +111,6 @@ const GlobalBatchImportDataSource = () => {
diff --git a/packages/base/src/page/GlobalDataSource/List/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/GlobalDataSource/List/__tests__/__snapshots__/index.test.tsx.snap
index b6a03bd6e..d3fb8c9ce 100644
--- a/packages/base/src/page/GlobalDataSource/List/__tests__/__snapshots__/index.test.tsx.snap
+++ b/packages/base/src/page/GlobalDataSource/List/__tests__/__snapshots__/index.test.tsx.snap
@@ -133,6 +133,7 @@ exports[`page/GlobalDataSource/List render list snap 1`] = `
+
@@ -165,6 +166,12 @@ exports[`page/GlobalDataSource/List render list snap 1`] = `
>
地址
+
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.41:3306
+
+
+ |
@@ -552,6 +586,24 @@ exports[`page/GlobalDataSource/List render list snap 1`] = `
>
-
|
+
+
+ |
@@ -675,6 +727,11 @@ exports[`page/GlobalDataSource/List render list snap 1`] = `
>
-
|
+
+ -
+ |
@@ -1069,6 +1126,7 @@ exports[`page/GlobalDataSource/List render list snap 2`] = `
+
@@ -1101,6 +1159,12 @@ exports[`page/GlobalDataSource/List render list snap 2`] = `
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.41:3306
+
+
+ |
@@ -1488,6 +1579,24 @@ exports[`page/GlobalDataSource/List render list snap 2`] = `
>
-
|
+
+
+ |
@@ -1611,6 +1720,11 @@ exports[`page/GlobalDataSource/List render list snap 2`] = `
>
-
|
+
+ -
+ |
@@ -2035,6 +2149,64 @@ exports[`page/GlobalDataSource/List render table filter option val 1`] = `
/>
+
+
+
+
+
+
+
+
+
+ 数据源连接状态
+
+
+ 请选择{{name}}
+
+
+
+
+
+
+
+
@@ -2159,6 +2332,12 @@ exports[`page/GlobalDataSource/List render table filter option val 1`] = `
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.41:3306
+
+
+ |
@@ -2546,6 +2752,24 @@ exports[`page/GlobalDataSource/List render table filter option val 1`] = `
>
-
|
+
+
+ |
@@ -2669,6 +2893,11 @@ exports[`page/GlobalDataSource/List render table filter option val 1`] = `
>
-
|
+
+ -
+ |
@@ -3063,6 +3292,7 @@ exports[`page/GlobalDataSource/List render table for action btn render table for
+
@@ -3095,6 +3325,12 @@ exports[`page/GlobalDataSource/List render table for action btn render table for
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.41:3306
+
+
+ |
@@ -3882,6 +4145,7 @@ exports[`page/GlobalDataSource/List render table for action btn render table for
+
@@ -3914,6 +4178,12 @@ exports[`page/GlobalDataSource/List render table for action btn render table for
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.41:3306
+
+
+ |
@@ -4701,6 +4998,7 @@ exports[`page/GlobalDataSource/List render table for action btn should not rende
+
@@ -4733,6 +5031,12 @@ exports[`page/GlobalDataSource/List render table for action btn should not rende
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
10.186.62.41:3306
+
+
+ |
@@ -5078,6 +5409,24 @@ exports[`page/GlobalDataSource/List render table for action btn should not rende
>
-
|
+
+
+ |
@@ -5159,6 +5508,11 @@ exports[`page/GlobalDataSource/List render table for action btn should not rende
>
-
|
+
+ -
+ |
@@ -5511,6 +5865,7 @@ exports[`page/GlobalDataSource/List render table for api return no data 1`] = `
+
@@ -5543,6 +5898,12 @@ exports[`page/GlobalDataSource/List render table for api return no data 1`] = `
>
地址
+ |
+ 上一次连接状态
+ |
+ |
+
+
+
+ |
{
return {
@@ -34,6 +36,7 @@ describe('page/GlobalDataSource/List', () => {
let listGlobalDBServicesSpy: jest.SpyInstance;
let getProjectListSpy: jest.SpyInstance;
let listGlobalDBServicesTipsSpy: jest.SpyInstance;
+ let CheckGlobalDBServicesConnectionsSpy: jest.SpyInstance;
const customRender = () => {
return superRender();
@@ -46,6 +49,9 @@ describe('page/GlobalDataSource/List', () => {
listGlobalDBServicesSpy = dbServices.listGlobalDBServices();
listGlobalDBServicesTipsSpy = dbServices.listGlobalDBServicesTips();
getProjectListSpy = project.getProjectList();
+ CheckGlobalDBServicesConnectionsSpy =
+ project.CheckGlobalDBServicesConnections();
+
(useNavigate as jest.Mock).mockImplementation(() => navigateSpy);
jest.useFakeTimers();
dms.mockAllApi();
@@ -124,10 +130,47 @@ describe('page/GlobalDataSource/List', () => {
'.actiontech-table-filter-container-namespace .ant-space-item',
baseElement
);
- expect(filterItems.length).toBe(2);
+ expect(filterItems.length).toBe(3);
expect(baseElement).toMatchSnapshot();
});
+ it('should display an error message and return if dataSourceList is empty or undefined', async () => {
+ listGlobalDBServicesSpy.mockImplementation(() =>
+ createSpySuccessResponse({ data: [] })
+ );
+ customRender();
+
+ await act(async () => jest.advanceTimersByTime(3000));
+
+ act(() => {
+ eventEmitter.emit(EmitterKey.DMS_Batch_Test_Data_Source_Connection);
+ });
+
+ expect(CheckGlobalDBServicesConnectionsSpy).toHaveBeenCalledTimes(0);
+
+ await screen.findByText('当前列表无数据!');
+ });
+
+ it('should initiate the connection test and call DBService.CheckProjectDBServicesConnections when dataSourceList has valid data sources', async () => {
+ customRender();
+
+ await act(async () => jest.advanceTimersByTime(3000));
+ act(() => {
+ eventEmitter.emit(EmitterKey.DMS_Batch_Test_Data_Source_Connection);
+ });
+
+ expect(CheckGlobalDBServicesConnectionsSpy).toHaveBeenCalledTimes(1);
+ expect(CheckGlobalDBServicesConnectionsSpy).toHaveBeenCalledWith({
+ db_services: globalDataSourceMockData.map((v) => ({
+ db_service_uid: v.uid!
+ }))
+ });
+
+ await act(async () => jest.advanceTimersByTime(3000));
+ expect(listGlobalDBServicesSpy).toHaveBeenCalledTimes(2);
+ await screen.findByText('执行批量测试数据源连通性成功!');
+ });
+
describe('render table for action btn', () => {
it('render table for edit action', async () => {
listGlobalDBServicesSpy.mockImplementationOnce(() =>
diff --git a/packages/base/src/page/GlobalDataSource/List/columns.tsx b/packages/base/src/page/GlobalDataSource/List/columns.tsx
index c60a0e37d..3815ed6a6 100644
--- a/packages/base/src/page/GlobalDataSource/List/columns.tsx
+++ b/packages/base/src/page/GlobalDataSource/List/columns.tsx
@@ -9,6 +9,8 @@ import {
import BasicTypographyEllipsis from '@actiontech/shared/lib/components/BasicTypographyEllipsis';
import { IListGlobalDBServicesParams } from '@actiontech/shared/lib/api/base/service/DBService/index.d';
import { DatabaseTypeLogo } from '@actiontech/shared';
+import ConnectionResultColumn from '../../DataSource/components/List/ConnectionResultColumn';
+import { ListDBServiceLastConnectionTestStatusEnum } from '@actiontech/shared/lib/api/base/service/common.enum';
export type GLobalDataSourceListParamType = PageInfoWithoutIndexAndSize<
IListGlobalDBServicesParams & { page_index: number }
@@ -46,6 +48,26 @@ export const GlobalDataSourceColumns = (
return `${record.host}:${record.port}`;
}
},
+ {
+ dataIndex: 'last_connection_test_status',
+ title: () => t('dmsGlobalDataSource.list.lastTestConnectionStatus'),
+ filterCustomType: 'select',
+ filterKey: 'filter_last_connection_test_status',
+ filterLabel: t(
+ 'dmsGlobalDataSource.list.testConnectionStatusFilterLabel'
+ ),
+ render: (status, record) => {
+ return (
+
+ );
+ }
+ },
{
dataIndex: 'source',
title: t('dmsGlobalDataSource.list.source')
@@ -54,7 +76,7 @@ export const GlobalDataSourceColumns = (
dataIndex: 'desc',
title: t('dmsGlobalDataSource.list.describe'),
className: 'ellipsis-column-width',
- render: (desc: string) => {
+ render: (desc) => {
return desc ? : '-';
}
},
@@ -63,7 +85,7 @@ export const GlobalDataSourceColumns = (
title: t('dmsGlobalDataSource.list.type'),
filterCustomType: 'select',
filterKey: 'filter_by_db_type',
- render: (dbType: string) => {
+ render: (dbType) => {
if (!dbType) return '-';
return (
diff --git a/packages/base/src/page/GlobalDataSource/List/index.tsx b/packages/base/src/page/GlobalDataSource/List/index.tsx
index dfb5f0bcc..1e4e2f528 100644
--- a/packages/base/src/page/GlobalDataSource/List/index.tsx
+++ b/packages/base/src/page/GlobalDataSource/List/index.tsx
@@ -1,10 +1,11 @@
-import { useEffect, useMemo } from 'react';
+import { useCallback, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { message, Modal } from 'antd';
import { TestConnectDisableReasonStyleWrapper } from '@actiontech/shared/lib/components/TestDatabaseConnectButton/style';
import { useDbServiceDriver } from '@actiontech/shared/lib/global';
import { useRequest } from 'ahooks';
import DBService from '@actiontech/shared/lib/api/base/service/DBService';
+import ProjectService from '@actiontech/shared/lib/api/base/service/Project';
import { ResponseCode } from '@actiontech/shared/lib/enum';
import {
ActiontechTable,
@@ -28,6 +29,7 @@ import usePermission from '@actiontech/shared/lib/global/usePermission/usePermis
import { GlobalDataSourceListActions } from './action';
import { useTypedNavigate } from '@actiontech/shared';
import { ROUTE_PATHS } from '@actiontech/shared/lib/data/routePaths';
+import useStaticTips from '../../../hooks/useStaticTips';
const GlobalDataSourceList = () => {
const { t } = useTranslation();
@@ -42,6 +44,8 @@ const GlobalDataSourceList = () => {
const { getLogoUrlByDbType, updateDriverList } = useDbServiceDriver();
+ const { generateDatabaseTestConnectionStatusSelectOptions } = useStaticTips();
+
const {
updateDbTypeList,
dbTypeOptions,
@@ -104,13 +108,18 @@ const GlobalDataSourceList = () => {
[
'project_name',
{ options: projectIDOptions, loading: getProjectsLoading }
+ ],
+ [
+ 'last_connection_test_status',
+ { options: generateDatabaseTestConnectionStatusSelectOptions }
]
]);
}, [
dbTypeOptions,
getDbTypeListLoading,
projectIDOptions,
- getProjectsLoading
+ getProjectsLoading,
+ generateDatabaseTestConnectionStatusSelectOptions
]);
const actions = useMemo(() => {
@@ -219,6 +228,30 @@ const GlobalDataSourceList = () => {
modalApi
]);
+ const batchTestDatabaseConnection = useCallback(() => {
+ if (!dataSourceList?.list || dataSourceList.list.length === 0) {
+ messageApi.error(
+ t('dmsGlobalDataSource.batchTestConnection.notFoundData')
+ );
+ return;
+ }
+ ProjectService.CheckGlobalDBServicesConnections({
+ db_services:
+ dataSourceList?.list?.map((v) => ({
+ db_service_uid: v.uid!
+ })) ?? []
+ }).then((res) => {
+ if (res.data.code === ResponseCode.SUCCESS) {
+ refresh();
+ messageApi.success(
+ t(
+ 'dmsGlobalDataSource.batchTestConnection.batchTestConnectionSuccessTips'
+ )
+ );
+ }
+ });
+ }, [dataSourceList?.list, messageApi, refresh, t]);
+
useEffect(() => {
updateDriverList();
updateProjects();
@@ -226,15 +259,21 @@ const GlobalDataSourceList = () => {
}, [updateDbTypeList, updateDriverList, updateProjects]);
useEffect(() => {
- const { unsubscribe } = eventEmitter.subscribe(
+ const { unsubscribe: unsubscribeRefresh } = eventEmitter.subscribe(
EmitterKey.DMS_Refresh_Global_Data_Source,
refresh
);
+ const { unsubscribe: unsubscribeBatchTest } = eventEmitter.subscribe(
+ EmitterKey.DMS_Batch_Test_Data_Source_Connection,
+ batchTestDatabaseConnection
+ );
+
return () => {
- unsubscribe();
+ unsubscribeRefresh();
+ unsubscribeBatchTest();
};
- }, [refresh]);
+ }, [refresh, batchTestDatabaseConnection]);
return (
<>
diff --git a/packages/base/src/page/GlobalDataSource/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/GlobalDataSource/__tests__/__snapshots__/index.test.tsx.snap
index 64dda3c71..eed24328c 100644
--- a/packages/base/src/page/GlobalDataSource/__tests__/__snapshots__/index.test.tsx.snap
+++ b/packages/base/src/page/GlobalDataSource/__tests__/__snapshots__/index.test.tsx.snap
@@ -157,6 +157,7 @@ exports[`test base/GlobalDataSource should match snapshot 1`] = `
+
@@ -189,6 +190,12 @@ exports[`test base/GlobalDataSource should match snapshot 1`] = `
>
地址
+ |
+ 上一次连接状态
+ |
|
+
+
+
+
+ |
-
diff --git a/packages/base/src/page/Project/BatchImportDataSource/UploadForm/index.test.tsx b/packages/base/src/page/Project/BatchImportDataSource/UploadForm/index.test.tsx
index 4dc0aa681..07d25e7f8 100644
--- a/packages/base/src/page/Project/BatchImportDataSource/UploadForm/index.test.tsx
+++ b/packages/base/src/page/Project/BatchImportDataSource/UploadForm/index.test.tsx
@@ -34,7 +34,6 @@ describe('base/Project/BatchImportDataSourceForm', () => {
@@ -46,10 +45,6 @@ describe('base/Project/BatchImportDataSourceForm', () => {
expect(baseElement).toMatchSnapshot();
expect(screen.getByText('请选择导入文件')).toBeInTheDocument();
expect(screen.getByText('下载导入模板')).toBeInTheDocument();
- expect(screen.getByText('批量测试数据源连通性')).toBeInTheDocument();
- expect(
- screen.getByText('批量测试数据源连通性').closest('button')
- ).toBeDisabled();
});
test('render init snap', async () => {
@@ -59,14 +54,6 @@ describe('base/Project/BatchImportDataSourceForm', () => {
expect(getImportDBServicesTemplateSpy).toHaveBeenCalledTimes(1);
});
- test('render test connection', async () => {
- customRender(mockBatchImportDBCheckData);
- await act(async () => jest.advanceTimersByTime(300));
- expect(
- screen.getByText('批量测试数据源连通性').closest('button')
- ).not.toBeDisabled();
- });
-
test('render upload file error', async () => {
customRender([], { success: false, errorMessage: 'test error' });
});
diff --git a/packages/base/src/page/Project/BatchImportDataSource/UploadForm/index.tsx b/packages/base/src/page/Project/BatchImportDataSource/UploadForm/index.tsx
index 1d76414c3..18cab6de2 100644
--- a/packages/base/src/page/Project/BatchImportDataSource/UploadForm/index.tsx
+++ b/packages/base/src/page/Project/BatchImportDataSource/UploadForm/index.tsx
@@ -1,4 +1,3 @@
-import { BasicButton, ReminderInformation, EmptyBox } from '@actiontech/shared';
import { useTranslation } from 'react-i18next';
import {
FormAreaBlockStyleWrapper,
@@ -16,71 +15,17 @@ import {
FileUploadCheckStatusType
} from '../index.type';
import FileUpload from './FileUpload';
-import { UploadProps, Space } from 'antd';
-import Project from '@actiontech/shared/lib/api/base/service/Project';
-import { useBoolean } from 'ahooks';
-import { useState } from 'react';
-import { IDBServicesConnectionItem } from '@actiontech/shared/lib/api/base/service/common';
-import { ResponseCode } from '@actiontech/shared/lib/enum';
-import { IDBService } from '@actiontech/shared/lib/api/base/service/common';
-import { useEffect } from 'react';
+import { UploadProps } from 'antd';
import { OverviewOutlined } from '@actiontech/icons';
const BatchImportDataSourceForm: React.FC<{
form: BatchImportDataSourceFormType;
customRequest: UploadProps['customRequest'];
- dbServices?: IDBService[];
uploadCheckStatus: FileUploadCheckStatusType;
clearUploadCheckStatus: () => void;
-}> = ({
- form,
- customRequest,
- dbServices,
- uploadCheckStatus,
- clearUploadCheckStatus
-}) => {
+}> = ({ form, customRequest, uploadCheckStatus, clearUploadCheckStatus }) => {
const { t } = useTranslation();
- const [
- connectionTesting,
- { setTrue: setConnectionTesting, setFalse: setConnectionTestingDone }
- ] = useBoolean();
-
- const [connectionTestResult, setConnectionTestResult] =
- useState();
-
- const onBatchTestConnection = async () => {
- await form.validateFields();
- setConnectionTesting();
- Project.DBServicesConnection({
- db_services: dbServices?.map((i) => {
- return {
- additional_params: i.additional_params,
- db_type: i.db_type ?? '',
- host: i.host,
- name: i.name,
- password: i.password,
- port: i.port,
- user: i.user
- };
- })
- })
- .then((res) => {
- if (res.data.code === ResponseCode.SUCCESS) {
- setConnectionTestResult(res.data.data);
- }
- })
- .finally(() => {
- setConnectionTestingDone();
- });
- };
-
- useEffect(() => {
- if (!dbServices?.length) {
- setConnectionTestResult(undefined);
- }
- }, [dbServices]);
-
return (
{
clearUploadCheckStatus();
- setConnectionTestResult(undefined);
}}
accept=".csv"
customRequest={customRequest}
uploadCheckStatus={uploadCheckStatus}
/>
-
-
-
- {t('dmsProject.batchImportDataSource.testConnect')}
-
-
-
-
-
-
-
-
-
);
diff --git a/packages/base/src/page/Project/BatchImportDataSource/__snapshots__/index.test.tsx.snap b/packages/base/src/page/Project/BatchImportDataSource/__snapshots__/index.test.tsx.snap
index 2e6794bf3..9612cae8d 100644
--- a/packages/base/src/page/Project/BatchImportDataSource/__snapshots__/index.test.tsx.snap
+++ b/packages/base/src/page/Project/BatchImportDataSource/__snapshots__/index.test.tsx.snap
@@ -288,61 +288,6 @@ exports[`base/Project/BatchImportDataSource render check api return csv file 1`]
-
@@ -600,61 +545,6 @@ exports[`base/Project/BatchImportDataSource render delete file 1`] = `
-
@@ -840,482 +730,6 @@ exports[`base/Project/BatchImportDataSource render init snap 1`] = `
-
-
-
-
- |
-
-
-
diff --git a/packages/base/src/page/Project/BatchImportDataSource/index.test.tsx b/packages/base/src/page/Project/BatchImportDataSource/index.test.tsx
index 826d5a999..119789c2b 100644
--- a/packages/base/src/page/Project/BatchImportDataSource/index.test.tsx
+++ b/packages/base/src/page/Project/BatchImportDataSource/index.test.tsx
@@ -34,7 +34,6 @@ describe('base/Project/BatchImportDataSource', () => {
await act(async () => jest.advanceTimersByTime(300));
expect(baseElement).toMatchSnapshot();
expect(screen.getByText('批量导入数据源')).toBeInTheDocument();
- expect(screen.getByText('批量测试数据源连通性')).toBeInTheDocument();
fireEvent.click(screen.getByText('返回项目列表'));
});
@@ -111,33 +110,6 @@ describe('base/Project/BatchImportDataSource', () => {
expect(baseElement).toMatchSnapshot();
});
- it('render test connection', async () => {
- const { baseElement } = superRender();
- await act(async () => jest.advanceTimersByTime(300));
- expect(
- screen.getByText('批量测试数据源连通性').closest('button')
- ).toBeDisabled();
- const file = new File([''], 'test.csv');
- fireEvent.change(getBySelector('#files', baseElement), {
- target: { files: [file] }
- });
- await act(async () => jest.advanceTimersByTime(100));
- expect(screen.getByText('test.csv')).toBeInTheDocument();
- await act(async () => jest.advanceTimersByTime(3000));
- expect(
- screen.getByText('批量测试数据源连通性').closest('button')
- ).not.toBeDisabled();
- fireEvent.click(screen.getByText('批量测试数据源连通性'));
- await act(async () => jest.advanceTimersByTime(100));
- expect(dbServicesConnectionSpy).toHaveBeenCalledTimes(1);
- await act(async () => jest.advanceTimersByTime(3000));
- expect(screen.getByText('测试连通性成功1个')).toBeInTheDocument();
- expect(
- screen.getByText('测试连通性失败1个,数据源为mysql_1')
- ).toBeInTheDocument();
- expect(baseElement).toMatchSnapshot();
- });
-
it('render upload file', async () => {
const { baseElement } = superRender();
await act(async () => jest.advanceTimersByTime(300));
diff --git a/packages/base/src/page/Project/BatchImportDataSource/index.tsx b/packages/base/src/page/Project/BatchImportDataSource/index.tsx
index 841a934b8..bf72236ff 100644
--- a/packages/base/src/page/Project/BatchImportDataSource/index.tsx
+++ b/packages/base/src/page/Project/BatchImportDataSource/index.tsx
@@ -114,7 +114,6 @@ const BatchImportDataSource = () => {
diff --git a/packages/base/src/testUtils/mockApi/dbServices/data.ts b/packages/base/src/testUtils/mockApi/dbServices/data.ts
index 1d1a54728..226a4e70c 100644
--- a/packages/base/src/testUtils/mockApi/dbServices/data.ts
+++ b/packages/base/src/testUtils/mockApi/dbServices/data.ts
@@ -4,7 +4,10 @@ import {
IListDBServiceTipItem,
IListGlobalDBService
} from '@actiontech/shared/lib/api/base/service/common';
-import { SQLQueryConfigAllowQueryWhenLessThanAuditLevelEnum } from '@actiontech/shared/lib/api/base/service/common.enum';
+import {
+ ListGlobalDBServiceLastConnectionTestStatusEnum,
+ SQLQueryConfigAllowQueryWhenLessThanAuditLevelEnum
+} from '@actiontech/shared/lib/api/base/service/common.enum';
export const dbServices: IListDBService[] = [
{
@@ -99,7 +102,11 @@ export const globalDataSourceMockData: IListGlobalDBService[] = [
is_enable_masking: false,
project_name: 'default',
unfinished_workflow_num: 1,
- is_enable_audit: true
+ is_enable_audit: true,
+ last_connection_test_error_message: 'error message',
+ last_connection_test_status:
+ ListGlobalDBServiceLastConnectionTestStatusEnum.connect_failed,
+ last_connection_test_time: '2024-11-15T15:28:13.315+08:00'
},
{
uid: '123457',
@@ -115,7 +122,11 @@ export const globalDataSourceMockData: IListGlobalDBService[] = [
is_enable_masking: false,
project_name: 'project1',
unfinished_workflow_num: 0,
- is_enable_audit: false
+ is_enable_audit: false,
+ last_connection_test_error_message: '',
+ last_connection_test_status:
+ ListGlobalDBServiceLastConnectionTestStatusEnum.connect_success,
+ last_connection_test_time: '2024-11-15T15:28:13.315+08:00'
},
{
uid: '123458',
diff --git a/packages/base/src/testUtils/mockApi/dbServices/index.ts b/packages/base/src/testUtils/mockApi/dbServices/index.ts
index 860209b78..8e7cc8506 100644
--- a/packages/base/src/testUtils/mockApi/dbServices/index.ts
+++ b/packages/base/src/testUtils/mockApi/dbServices/index.ts
@@ -23,6 +23,7 @@ class MockDbServicesApi implements MockSpyApy {
this.checkDBServiceIsConnectableById();
this.listGlobalDBServices();
this.listGlobalDBServicesTips();
+ this.CheckProjectDBServicesConnections();
}
public ListDBServices() {
@@ -117,6 +118,16 @@ class MockDbServicesApi implements MockSpyApy {
);
return spy;
}
+
+ public CheckProjectDBServicesConnections() {
+ const spy = jest.spyOn(DBService, 'CheckProjectDBServicesConnections');
+ spy.mockImplementation(() =>
+ createSpySuccessResponse({
+ data: globalDBServicesTipsMockData
+ })
+ );
+ return spy;
+ }
}
export default new MockDbServicesApi();
diff --git a/packages/base/src/testUtils/mockApi/global/data.ts b/packages/base/src/testUtils/mockApi/global/data.ts
index 373e4b977..6dfa76cf2 100644
--- a/packages/base/src/testUtils/mockApi/global/data.ts
+++ b/packages/base/src/testUtils/mockApi/global/data.ts
@@ -5,7 +5,10 @@ import {
ICompanyNotice,
IListDBService
} from '@actiontech/shared/lib/api/base/service/common';
-import { GetUserAuthenticationTypeEnum } from '@actiontech/shared/lib/api/base/service/common.enum';
+import {
+ GetUserAuthenticationTypeEnum,
+ ListDBServiceLastConnectionTestStatusEnum
+} from '@actiontech/shared/lib/api/base/service/common.enum';
import { SupportLanguage } from '@actiontech/shared/lib/enum';
export const UserInfo = {
@@ -73,7 +76,11 @@ export const DBServicesList: IListDBService[] = [
instance_audit_plan_id: 1232,
audit_plan_types: [
{ type: 'mysql_slow_log', desc: '慢日志', audit_plan_id: 1 }
- ]
+ ],
+ last_connection_test_error_message: '',
+ last_connection_test_status:
+ ListDBServiceLastConnectionTestStatusEnum.connect_success,
+ last_connection_test_time: '2024-11-15T15:05:10.175+08:00'
},
{
uid: '1739531942258282496',
@@ -97,6 +104,10 @@ export const DBServicesList: IListDBService[] = [
audit_enabled: false
}
},
- is_enable_masking: false
+ is_enable_masking: false,
+ last_connection_test_error_message: 'error message',
+ last_connection_test_status:
+ ListDBServiceLastConnectionTestStatusEnum.connect_failed,
+ last_connection_test_time: '2024-11-15T15:05:10.175+08:00'
}
];
diff --git a/packages/base/src/testUtils/mockApi/project/index.ts b/packages/base/src/testUtils/mockApi/project/index.ts
index 946748ad4..2ecb290df 100644
--- a/packages/base/src/testUtils/mockApi/project/index.ts
+++ b/packages/base/src/testUtils/mockApi/project/index.ts
@@ -33,6 +33,7 @@ class MockProjectApi implements MockSpyApy {
this.importDBServicesOfProjectsCheck();
this.importDBServicesOfOneProjectCheck();
this.dbServicesConnection();
+ this.CheckGlobalDBServicesConnections();
}
public getProjectList() {
@@ -211,6 +212,12 @@ class MockProjectApi implements MockSpyApy {
);
return spy;
}
+
+ public CheckGlobalDBServicesConnections() {
+ const spy = jest.spyOn(Project, 'CheckGlobalDBServicesConnections');
+ spy.mockImplementation(() => createSpySuccessResponse({}));
+ return spy;
+ }
}
export default new MockProjectApi();
diff --git a/packages/shared/lib/api/base/service/DBService/index.d.ts b/packages/shared/lib/api/base/service/DBService/index.d.ts
index 9dea570ac..b9d8f7cd2 100644
--- a/packages/shared/lib/api/base/service/DBService/index.d.ts
+++ b/packages/shared/lib/api/base/service/DBService/index.d.ts
@@ -1,6 +1,8 @@
import {
ListGlobalDBServicesOrderByEnum,
+ ListGlobalDBServicesFilterLastConnectionTestStatusEnum,
ListDBServicesOrderByEnum,
+ ListDBServicesFilterLastConnectionTestStatusEnum,
ListDBServiceTipsFunctionalModuleEnum
} from './index.enum';
@@ -13,6 +15,8 @@ import {
IAddDBServiceReply,
ICheckDBServiceIsConnectableReq,
ICheckDBServiceIsConnectableReply,
+ ICheckDBServicesIsConnectableReq,
+ ICheckDBServicesIsConnectableReply,
IImportDBServicesOfOneProjectReq,
IGenericResp,
IListDBServiceTipsReply,
@@ -26,6 +30,8 @@ export interface IListGlobalDBServicesParams {
order_by?: ListGlobalDBServicesOrderByEnum;
+ filter_last_connection_test_status?: ListGlobalDBServicesFilterLastConnectionTestStatusEnum;
+
filter_by_business?: string;
filter_by_host?: string;
@@ -63,6 +69,8 @@ export interface IListDBServicesParams {
filter_by_business?: string;
+ filter_last_connection_test_status?: ListDBServicesFilterLastConnectionTestStatusEnum;
+
filter_by_host?: string;
filter_by_uid?: string;
@@ -75,6 +83,8 @@ export interface IListDBServicesParams {
project_uid: string;
+ filter_by_db_service_ids?: string[];
+
fuzzy_keyword?: string;
is_enable_masking?: boolean;
@@ -96,6 +106,14 @@ export interface ICheckDBServiceIsConnectableParams
export interface ICheckDBServiceIsConnectableReturn
extends ICheckDBServiceIsConnectableReply {}
+export interface ICheckProjectDBServicesConnectionsParams
+ extends ICheckDBServicesIsConnectableReq {
+ project_uid: string;
+}
+
+export interface ICheckProjectDBServicesConnectionsReturn
+ extends ICheckDBServicesIsConnectableReply {}
+
export interface IImportDBServicesOfOneProjectParams
extends IImportDBServicesOfOneProjectReq {
project_uid: string;
diff --git a/packages/shared/lib/api/base/service/DBService/index.enum.ts b/packages/shared/lib/api/base/service/DBService/index.enum.ts
index 015335988..431605f95 100644
--- a/packages/shared/lib/api/base/service/DBService/index.enum.ts
+++ b/packages/shared/lib/api/base/service/DBService/index.enum.ts
@@ -4,10 +4,22 @@ export enum ListGlobalDBServicesOrderByEnum {
'name' = 'name'
}
+export enum ListGlobalDBServicesFilterLastConnectionTestStatusEnum {
+ 'connect_success' = 'connect_success',
+
+ 'connect_failed' = 'connect_failed'
+}
+
export enum ListDBServicesOrderByEnum {
'name' = 'name'
}
+export enum ListDBServicesFilterLastConnectionTestStatusEnum {
+ 'connect_success' = 'connect_success',
+
+ 'connect_failed' = 'connect_failed'
+}
+
export enum ListDBServiceTipsFunctionalModuleEnum {
'save_audit_plan' = 'save_audit_plan',
diff --git a/packages/shared/lib/api/base/service/DBService/index.ts b/packages/shared/lib/api/base/service/DBService/index.ts
index ae7c6f96b..b757455dd 100644
--- a/packages/shared/lib/api/base/service/DBService/index.ts
+++ b/packages/shared/lib/api/base/service/DBService/index.ts
@@ -17,6 +17,8 @@ import {
IAddDBServiceReturn,
ICheckDBServiceIsConnectableParams,
ICheckDBServiceIsConnectableReturn,
+ ICheckProjectDBServicesConnectionsParams,
+ ICheckProjectDBServicesConnectionsReturn,
IImportDBServicesOfOneProjectParams,
IImportDBServicesOfOneProjectReturn,
IImportDBServicesOfOneProjectCheckParams,
@@ -104,6 +106,21 @@ class DBServiceService extends ServiceBase {
);
}
+ public CheckProjectDBServicesConnections(
+ params: ICheckProjectDBServicesConnectionsParams,
+ options?: AxiosRequestConfig
+ ) {
+ const paramsData = this.cloneDeep(params);
+ const project_uid = paramsData.project_uid;
+ delete paramsData.project_uid;
+
+ return this.post(
+ `/v1/dms/projects/${project_uid}/db_services/connections`,
+ paramsData,
+ options
+ );
+ }
+
public ImportDBServicesOfOneProject(
params: IImportDBServicesOfOneProjectParams,
options?: AxiosRequestConfig
diff --git a/packages/shared/lib/api/base/service/Project/index.d.ts b/packages/shared/lib/api/base/service/Project/index.d.ts
index 95815ca48..d74e00ffc 100644
--- a/packages/shared/lib/api/base/service/Project/index.d.ts
+++ b/packages/shared/lib/api/base/service/Project/index.d.ts
@@ -1,5 +1,6 @@
import {
ListProjectsOrderByEnum,
+ ListProjectsFilterByProjectPriorityEnum,
ExportProjectsOrderByEnum
} from './index.enum';
@@ -9,6 +10,8 @@ import {
IAddProjectReply,
IDBServiceConnectionReq,
IDBServicesConnectionReply,
+ IDBServicesConnectionReq,
+ IDBServicesConnectionReqReply,
IImportProjectsReq,
IGenericResp,
IImportDBServicesOfProjectsReq,
@@ -27,6 +30,10 @@ export interface IListProjectsParams {
filter_by_name?: string;
filter_by_uid?: string;
+
+ filter_by_project_uids?: string[];
+
+ filter_by_project_priority?: ListProjectsFilterByProjectPriorityEnum;
}
export interface IListProjectsReturn extends IListProjectReply {}
@@ -40,6 +47,12 @@ export interface IDBServicesConnectionParams extends IDBServiceConnectionReq {}
export interface IDBServicesConnectionReturn
extends IDBServicesConnectionReply {}
+export interface ICheckGlobalDBServicesConnectionsParams
+ extends IDBServicesConnectionReq {}
+
+export interface ICheckGlobalDBServicesConnectionsReturn
+ extends IDBServicesConnectionReqReply {}
+
export interface IExportProjectsParams {
order_by?: ExportProjectsOrderByEnum;
diff --git a/packages/shared/lib/api/base/service/Project/index.enum.ts b/packages/shared/lib/api/base/service/Project/index.enum.ts
index 68863110e..3b3db98a4 100644
--- a/packages/shared/lib/api/base/service/Project/index.enum.ts
+++ b/packages/shared/lib/api/base/service/Project/index.enum.ts
@@ -4,6 +4,16 @@ export enum ListProjectsOrderByEnum {
'name' = 'name'
}
+export enum ListProjectsFilterByProjectPriorityEnum {
+ 'high' = 'high',
+
+ 'medium' = 'medium',
+
+ 'low' = 'low',
+
+ 'unknown' = 'unknown'
+}
+
export enum ExportProjectsOrderByEnum {
'name' = 'name'
}
diff --git a/packages/shared/lib/api/base/service/Project/index.ts b/packages/shared/lib/api/base/service/Project/index.ts
index fdde68c00..e183666f4 100644
--- a/packages/shared/lib/api/base/service/Project/index.ts
+++ b/packages/shared/lib/api/base/service/Project/index.ts
@@ -13,6 +13,8 @@ import {
IAddProjectReturn,
IDBServicesConnectionParams,
IDBServicesConnectionReturn,
+ ICheckGlobalDBServicesConnectionsParams,
+ ICheckGlobalDBServicesConnectionsReturn,
IExportProjectsParams,
IImportProjectsParams,
IImportProjectsReturn,
@@ -67,6 +69,18 @@ class ProjectService extends ServiceBase {
);
}
+ public CheckGlobalDBServicesConnections(
+ params: ICheckGlobalDBServicesConnectionsParams,
+ options?: AxiosRequestConfig
+ ) {
+ const paramsData = this.cloneDeep(params);
+ return this.post(
+ '/v1/dms/projects/db_services_connections',
+ paramsData,
+ options
+ );
+ }
+
public ExportProjects(
params: IExportProjectsParams,
options?: AxiosRequestConfig
diff --git a/packages/shared/lib/api/base/service/common.d.ts b/packages/shared/lib/api/base/service/common.d.ts
index 3e94bcbc6..bf853e4de 100644
--- a/packages/shared/lib/api/base/service/common.d.ts
+++ b/packages/shared/lib/api/base/service/common.d.ts
@@ -1,9 +1,12 @@
import {
+ DBServiceIsConnectableReplyConnectionStatusEnum,
DMSProxyTargetScenarioEnum,
GetDataExportTaskStatusEnum,
GetUserAuthenticationTypeEnum,
GetUserStatEnum,
+ ListDBServiceLastConnectionTestStatusEnum,
ListDataExportWorkflowStatusEnum,
+ ListGlobalDBServiceLastConnectionTestStatusEnum,
ListMemberRoleWithOpRangeOpRangeTypeEnum,
ListOpPermissionRangeTypeEnum,
ListProjectProjectPriorityEnum,
@@ -345,6 +348,18 @@ export interface ICheckDBServiceIsConnectableReq {
db_service?: ICheckDbConnectable;
}
+export interface ICheckDBServicesIsConnectableReply {
+ code?: number;
+
+ data?: IDBServiceIsConnectableReply[];
+
+ message?: string;
+}
+
+export interface ICheckDBServicesIsConnectableReq {
+ db_services?: IDbServiceConnections[];
+}
+
export interface ICheckDbConnectable {
additional_params?: IAdditionalParam[];
@@ -406,6 +421,8 @@ export interface IDBService {
desc?: string;
+ enable_backup?: boolean;
+
host: string;
is_enable_masking?: boolean;
@@ -427,6 +444,16 @@ export interface IDBServiceConnectionReq {
db_services?: ICheckDbsConnectable[];
}
+export interface IDBServiceIsConnectableReply {
+ connect_error_message?: string;
+
+ connection_status?: DBServiceIsConnectableReplyConnectionStatusEnum;
+
+ db_service_uid?: string;
+
+ test_connection_time?: string;
+}
+
export interface IDBServiceSyncTask {
additional_params?: IParams;
@@ -469,6 +496,18 @@ export interface IDBServicesConnectionReply {
message?: string;
}
+export interface IDBServicesConnectionReq {
+ db_services?: IDbServiceConnections[];
+}
+
+export interface IDBServicesConnectionReqReply {
+ code?: number;
+
+ data?: IDBServiceIsConnectableReply[];
+
+ message?: string;
+}
+
export interface IDMSProxyTarget {
addr: string;
@@ -515,6 +554,10 @@ export interface IDatabaseDriverOption {
params?: IDatabaseDriverAdditionalParam[];
}
+export interface IDbServiceConnections {
+ db_service_uid?: string;
+}
+
export interface IDelDBServicePreCheckReply {
code?: number;
@@ -1056,12 +1099,20 @@ export interface IListDBService {
desc?: string;
+ enable_backup?: boolean;
+
host?: string;
instance_audit_plan_id?: number;
is_enable_masking?: boolean;
+ last_connection_test_error_message?: string;
+
+ last_connection_test_status?: ListDBServiceLastConnectionTestStatusEnum;
+
+ last_connection_test_time?: string;
+
maintenance_times?: IMaintenanceTime[];
name?: string;
@@ -1220,12 +1271,20 @@ export interface IListGlobalDBService {
desc?: string;
+ enable_backup?: boolean;
+
host?: string;
is_enable_audit?: boolean;
is_enable_masking?: boolean;
+ last_connection_test_error_message?: string;
+
+ last_connection_test_status?: ListGlobalDBServiceLastConnectionTestStatusEnum;
+
+ last_connection_test_time?: string;
+
maintenance_times?: IMaintenanceTime[];
name?: string;
@@ -1880,6 +1939,8 @@ export interface IUpdateDBService {
desc?: string;
+ enable_backup?: boolean;
+
host: string;
is_enable_masking?: boolean;
diff --git a/packages/shared/lib/api/base/service/common.enum.ts b/packages/shared/lib/api/base/service/common.enum.ts
index 3e0d35164..0dbd3519f 100644
--- a/packages/shared/lib/api/base/service/common.enum.ts
+++ b/packages/shared/lib/api/base/service/common.enum.ts
@@ -1,3 +1,9 @@
+export enum DBServiceIsConnectableReplyConnectionStatusEnum {
+ 'connect_success' = 'connect_success',
+
+ 'connect_failed' = 'connect_failed'
+}
+
export enum DMSProxyTargetScenarioEnum {
'internal_service' = 'internal_service',
@@ -40,6 +46,12 @@ export enum GetUserStatEnum {
'Unknown' = 'Unknown'
}
+export enum ListDBServiceLastConnectionTestStatusEnum {
+ 'connect_success' = 'connect_success',
+
+ 'connect_failed' = 'connect_failed'
+}
+
export enum ListDataExportWorkflowStatusEnum {
'wait_for_approve' = 'wait_for_approve',
@@ -56,6 +68,12 @@ export enum ListDataExportWorkflowStatusEnum {
'finish' = 'finish'
}
+export enum ListGlobalDBServiceLastConnectionTestStatusEnum {
+ 'connect_success' = 'connect_success',
+
+ 'connect_failed' = 'connect_failed'
+}
+
export enum ListMemberRoleWithOpRangeOpRangeTypeEnum {
'unknown' = 'unknown',
@@ -81,7 +99,9 @@ export enum ListProjectProjectPriorityEnum {
'medium' = 'medium',
- 'low' = 'low'
+ 'low' = 'low',
+
+ 'unknown' = 'unknown'
}
export enum ListRoleStatEnum {
@@ -203,7 +223,9 @@ export enum ProjectProjectPriorityEnum {
'medium' = 'medium',
- 'low' = 'low'
+ 'low' = 'low',
+
+ 'unknown' = 'unknown'
}
export enum SQLQueryConfigAllowQueryWhenLessThanAuditLevelEnum {
@@ -227,7 +249,9 @@ export enum UpdateProjectProjectPriorityEnum {
'medium' = 'medium',
- 'low' = 'low'
+ 'low' = 'low',
+
+ 'unknown' = 'unknown'
}
export enum WorkflowRecordStatusEnum {
diff --git a/packages/shared/lib/components/ActiontechTable/Table.tsx b/packages/shared/lib/components/ActiontechTable/Table.tsx
index 5341c81ca..ad43b3af8 100644
--- a/packages/shared/lib/components/ActiontechTable/Table.tsx
+++ b/packages/shared/lib/components/ActiontechTable/Table.tsx
@@ -1,12 +1,10 @@
import { Result, ConfigProvider } from 'antd';
-import { ActiontechTableProps } from './index.type';
+import { ActiontechTableColumn, ActiontechTableProps } from './index.type';
import ToolBar from './components/Toolbar';
import FilterContainer from './components/FilterContainer';
import { useTranslation } from 'react-i18next';
import { ActiontechTableStyleWrapper, tableToken } from './style';
-import useTableAction, {
- ACTIONTECH_TABLE_OPERATOR_COLUMN_DATA_INDEX
-} from './hooks/useTableAction';
+import useTableAction from './hooks/useTableAction';
import classnames from 'classnames';
import { useEffect, useMemo } from 'react';
import useTableSettings from './hooks/useTableSettings';
@@ -14,7 +12,7 @@ import useTableSettings from './hooks/useTableSettings';
const ActiontechTable = <
T extends Record,
F extends Record,
- OtherColumnKeys extends string = ''
+ OtherColumnKeys extends string = never
>({
className,
toolbar,
@@ -33,13 +31,15 @@ const ActiontechTable = <
const { catchDefaultColumnsInfo, localColumns } = useTableSettings<
T,
F,
- OtherColumnKeys | typeof ACTIONTECH_TABLE_OPERATOR_COLUMN_DATA_INDEX
+ OtherColumnKeys
>(tableName, username);
const mergerColumns = useMemo(() => {
const operatorColumn = renderActionInTable(props.actions);
- return operatorColumn ? [...columns, operatorColumn] : columns;
+ return (
+ operatorColumn ? [...columns, operatorColumn] : columns
+ ) as ActiontechTableColumn;
}, [columns, props.actions, renderActionInTable]);
const innerColumns = useMemo(() => {
diff --git a/packages/shared/lib/components/ActiontechTable/hooks/useTableAction.tsx b/packages/shared/lib/components/ActiontechTable/hooks/useTableAction.tsx
index 4ceb1f75f..d0eb29df1 100644
--- a/packages/shared/lib/components/ActiontechTable/hooks/useTableAction.tsx
+++ b/packages/shared/lib/components/ActiontechTable/hooks/useTableAction.tsx
@@ -205,7 +205,7 @@ const useTableAction = () => {
: actions.title ?? (() => t('common.operate')),
fixed: Array.isArray(actions) ? 'right' : actions.fixed ?? 'right',
width: Array.isArray(actions) ? maxWidth : actions.width ?? maxWidth,
- render: (_, record: T) => renderContent(record)
+ render: (_: unknown, record: T) => renderContent(record)
};
},
[renderAction, t]
diff --git a/packages/shared/lib/components/ActiontechTable/hooks/useTableFilterContainer.tsx b/packages/shared/lib/components/ActiontechTable/hooks/useTableFilterContainer.tsx
index 417f93587..0edad64c4 100644
--- a/packages/shared/lib/components/ActiontechTable/hooks/useTableFilterContainer.tsx
+++ b/packages/shared/lib/components/ActiontechTable/hooks/useTableFilterContainer.tsx
@@ -23,7 +23,7 @@ export const mergeFilterButtonMeta = <
if (cur.filterCustomType) {
result.set(cur.dataIndex, {
checked: false,
- filterLabel: getColumnsLabel(cur.title),
+ filterLabel: cur.filterLabel ?? getColumnsLabel(cur.title),
filterCustomType: cur.filterCustomType
});
}
diff --git a/packages/shared/lib/components/ActiontechTable/hooks/useTableSettings.tsx b/packages/shared/lib/components/ActiontechTable/hooks/useTableSettings.tsx
index ff1a4045b..f058e9794 100644
--- a/packages/shared/lib/components/ActiontechTable/hooks/useTableSettings.tsx
+++ b/packages/shared/lib/components/ActiontechTable/hooks/useTableSettings.tsx
@@ -13,7 +13,7 @@ import { isEqual } from 'lodash';
const useTableSettings = <
T extends Record,
F = Record,
- OtherColumnKeys extends string = ''
+ OtherColumnKeys extends string = never
>(
tableName: string,
username: string
diff --git a/packages/shared/lib/components/ActiontechTable/index.type.ts b/packages/shared/lib/components/ActiontechTable/index.type.ts
index 1985ac4d2..451dbe838 100644
--- a/packages/shared/lib/components/ActiontechTable/index.type.ts
+++ b/packages/shared/lib/components/ActiontechTable/index.type.ts
@@ -6,6 +6,7 @@ import { CustomSelectProps } from '../CustomSelect';
import { IBasicButton } from '../BasicButton';
import { ICustomInputProps } from '../CustomInput';
import { TypedLinkProps } from '../TypedRouter';
+import { ExcludeSymbol } from '../../types/common.type';
//======================================= utils
@@ -19,7 +20,7 @@ type ComponentBaseType = {
*/
export type PageInfoWithoutIndexAndSize<
T extends TablePagination & Record,
- Other extends keyof T = ''
+ Other extends keyof T = never
> = Omit;
//=======================================
@@ -201,7 +202,7 @@ export type TableRefreshButtonProps = {
*/
export type CatchTableColumnValueType<
T = Record,
- OtherColumnKeys extends string = ''
+ OtherColumnKeys extends string = never
> = {
/**
* key 为用户名
@@ -348,29 +349,39 @@ export type ActiontechTableActionsConfig<
* 表格 columns props, 当配置 filterCustomType 和 filterKey 启用该列的筛选功能, 通过 useTableFilterContainer 来生成 筛选项的元数据
* 当需要添加表格列以外的筛选列时, 可以使用 useTableFilterContainer 的第三个参数: extraFilterMeta
*/
-type ExcludeSymbol = T extends symbol ? never : T;
+type ColumnValueType = K extends keyof T
+ ? T[K]
+ : never;
+
+type BaseColumnType> = {
+ show?: boolean;
+ dataIndex: ExcludeSymbol;
+ render?: (
+ value: ColumnValueType,
+ record: T,
+ index: number
+ ) => ColumnType['render'] extends (...args: any) => infer R
+ ? R
+ : React.ReactNode;
+} & Pick<
+ ActiontechTableFilterMetaValue,
+ 'filterCustomType' | 'filterKey' | 'filterLabel'
+>;
+
export type ActiontechTableColumn<
T = Record,
F = Record,
OtherColumnKeys extends string = never
> = Array<
- Omit | ColumnType, 'render' | 'dataIndex'> &
- {
- [K in keyof Required]: {
- show?: boolean;
- dataIndex: ExcludeSymbol;
- render?: (
- value: K | OtherColumnKeys extends keyof T ? T[K] : never,
- record: T,
- index: number
- ) => ColumnType['render'] extends (...args: any) => infer R
- ? R
- : React.ReactNode;
- } & Pick<
- ActiontechTableFilterMetaValue,
- 'filterCustomType' | 'filterKey'
- >;
- }[keyof Required]
+ Omit | ColumnType, 'dataIndex' | 'render'> &
+ (
+ | {
+ [K in keyof Required]: BaseColumnType;
+ }[keyof Required]
+ | {
+ [K in OtherColumnKeys]: BaseColumnType;
+ }[OtherColumnKeys]
+ )
>;
export interface ActiontechTableProps<
diff --git a/packages/shared/lib/global/usePermission/__tests__/__snapshots__/index.test.ts.snap b/packages/shared/lib/global/usePermission/__tests__/__snapshots__/index.test.ts.snap
index 7272a85f5..df7521e72 100644
--- a/packages/shared/lib/global/usePermission/__tests__/__snapshots__/index.test.ts.snap
+++ b/packages/shared/lib/global/usePermission/__tests__/__snapshots__/index.test.ts.snap
@@ -20,6 +20,7 @@ exports[`usePermission should match snapshot 1`] = `
"DB_SERVICE": {
"ADD": "action:add_db_service",
"BATCH_IMPORT": "action:batch_import_db_service",
+ "BATCH_TEST_CONNECT": "action:batch_test_project_db_service",
"CREATE_AUDIT_PLAN": "action:db_service_create_audit_plan",
"DELETE": "action:delete_db_service",
"EDIT": "action:edit_db_service",
@@ -29,6 +30,7 @@ exports[`usePermission should match snapshot 1`] = `
"GLOBAL_DATA_SOURCE": {
"ADD": "action:add_global_db_service",
"BATCH_IMPORT": "action:batch_import_global_db_service",
+ "BATCH_TEST_CONNECT": "action:batch_test_global_db_service",
"DELETE": "action:delete_global_db_service",
"EDIT": "action:edit_global_db_service",
"TEST_IN_MORE_BUTTON": "action:test_global_db_service_in_more_button",
@@ -285,7 +287,7 @@ exports[`usePermission should match snapshot 2`] = `
"type": "action",
},
"action:add_task": {
- "id": "action:add_global_db_service",
+ "id": "action:add_task",
"role": [
"admin",
"globalManager",
@@ -377,6 +379,24 @@ exports[`usePermission should match snapshot 2`] = `
],
"type": "action",
},
+ "action:batch_test_global_db_service": {
+ "id": "action:batch_test_global_db_service",
+ "role": [
+ "admin",
+ "globalManager",
+ ],
+ "type": "action",
+ },
+ "action:batch_test_project_db_service": {
+ "id": "action:batch_test_project_db_service",
+ "projectArchived": false,
+ "projectManager": true,
+ "role": [
+ "admin",
+ "globalManager",
+ ],
+ "type": "action",
+ },
"action:cancel_schedule_time_exec_task": {
"id": "action:cancel_schedule_time_exec_task",
"projectArchived": false,
diff --git a/packages/shared/lib/global/usePermission/permissionManifest.ts b/packages/shared/lib/global/usePermission/permissionManifest.ts
index 8ab57718c..d7811df62 100644
--- a/packages/shared/lib/global/usePermission/permissionManifest.ts
+++ b/packages/shared/lib/global/usePermission/permissionManifest.ts
@@ -140,6 +140,13 @@ export const PERMISSION_MANIFEST: Record<
type: 'action',
projectArchived: false
},
+ [PERMISSIONS.ACTIONS.BASE.DB_SERVICE.BATCH_TEST_CONNECT]: {
+ id: PERMISSIONS.ACTIONS.BASE.DB_SERVICE.BATCH_TEST_CONNECT,
+ type: 'action',
+ projectArchived: false,
+ role: [SystemRole.admin, SystemRole.globalManager],
+ projectManager: true
+ },
//用户中心
[PERMISSIONS.ACTIONS.BASE.USER_CENTER.USER.ADD]: {
@@ -214,10 +221,15 @@ export const PERMISSION_MANIFEST: Record<
id: PERMISSIONS.ACTIONS.BASE.GLOBAL_DATA_SOURCE.TEST_IN_MORE_BUTTON,
type: 'action'
},
+ [PERMISSIONS.ACTIONS.BASE.GLOBAL_DATA_SOURCE.BATCH_TEST_CONNECT]: {
+ id: PERMISSIONS.ACTIONS.BASE.GLOBAL_DATA_SOURCE.BATCH_TEST_CONNECT,
+ type: 'action',
+ role: [SystemRole.admin, SystemRole.globalManager]
+ },
// 同步外部数据源
[PERMISSIONS.ACTIONS.BASE.SYNC_DATA_SOURCE.ADD]: {
- id: PERMISSIONS.ACTIONS.BASE.GLOBAL_DATA_SOURCE.ADD,
+ id: PERMISSIONS.ACTIONS.BASE.SYNC_DATA_SOURCE.ADD,
type: 'action',
role: [SystemRole.admin, SystemRole.globalManager]
},
diff --git a/packages/shared/lib/global/usePermission/permissions.ts b/packages/shared/lib/global/usePermission/permissions.ts
index 8d102b44d..0bb86ccd1 100644
--- a/packages/shared/lib/global/usePermission/permissions.ts
+++ b/packages/shared/lib/global/usePermission/permissions.ts
@@ -33,7 +33,8 @@ export const PERMISSIONS = {
DELETE: 'action:delete_global_db_service',
TEST_IN_MORE_BUTTON: 'action:test_global_db_service_in_more_button',
ADD: 'action:add_global_db_service',
- BATCH_IMPORT: 'action:batch_import_global_db_service'
+ BATCH_IMPORT: 'action:batch_import_global_db_service',
+ BATCH_TEST_CONNECT: 'action:batch_test_global_db_service'
},
SYNC_DATA_SOURCE: {
ADD: 'action:add_task',
@@ -48,7 +49,8 @@ export const PERMISSIONS = {
DELETE: 'action:delete_db_service',
TEST: 'action:test_db_service',
TEST_IN_MORE_BUTTON: 'action:test_db_service_in_more_button',
- CREATE_AUDIT_PLAN: 'action:db_service_create_audit_plan'
+ CREATE_AUDIT_PLAN: 'action:db_service_create_audit_plan',
+ BATCH_TEST_CONNECT: 'action:batch_test_project_db_service'
},
SYSTEM: {
PUSH_NOTIFICATION: {
diff --git a/packages/shared/lib/types/common.type.ts b/packages/shared/lib/types/common.type.ts
index 679bc0eab..ff85de117 100644
--- a/packages/shared/lib/types/common.type.ts
+++ b/packages/shared/lib/types/common.type.ts
@@ -49,3 +49,5 @@ export type RouterConfigItem =
BaseRouterConfigItem & {
children?: RouterConfigItem[];
});
+
+export type ExcludeSymbol = T extends symbol ? never : T;
diff --git a/packages/sqle/src/hooks/useBackendTable/useBackendTable.tsx b/packages/sqle/src/hooks/useBackendTable/useBackendTable.tsx
index 4b7231d8c..e4d0f6bea 100644
--- a/packages/sqle/src/hooks/useBackendTable/useBackendTable.tsx
+++ b/packages/sqle/src/hooks/useBackendTable/useBackendTable.tsx
@@ -9,6 +9,7 @@ import {
TableFilterContainerProps,
TypeFilterElement
} from '@actiontech/shared/lib/components/ActiontechTable/index.type';
+import { ExcludeSymbol } from '@actiontech/shared/lib/types/common.type';
import { Tooltip, Typography } from 'antd';
import { ColumnType } from 'antd/es/table';
import { groupBy } from 'lodash';
@@ -108,7 +109,8 @@ const useBackendTable = () => {
? options.columnClassName(cell.type)
: options?.columnClassName;
return {
- dataIndex: cell.field_name ?? '',
+ dataIndex: cell.field_name as ExcludeSymbol &
+ string,
title: (cell.desc || cell.field_name) ?? '',
render: renderMethod,
className: cls,
diff --git a/packages/sqle/src/page/GlobalDashboard/index.data.ts b/packages/sqle/src/page/GlobalDashboard/index.data.ts
index c791f24d9..c0cbd064d 100644
--- a/packages/sqle/src/page/GlobalDashboard/index.data.ts
+++ b/packages/sqle/src/page/GlobalDashboard/index.data.ts
@@ -6,7 +6,8 @@ export const ProjectPriorityDictionary: {
} = {
[ProjectProjectPriorityEnum.high]: t('globalDashboard.high'),
[ProjectProjectPriorityEnum.medium]: t('globalDashboard.medium'),
- [ProjectProjectPriorityEnum.low]: t('globalDashboard.low')
+ [ProjectProjectPriorityEnum.low]: t('globalDashboard.low'),
+ [ProjectProjectPriorityEnum.unknown]: t('common.unknown')
};
export const ProjectPriorityOptions: Array<{
diff --git a/packages/sqle/src/page/SqlAudit/List/column.tsx b/packages/sqle/src/page/SqlAudit/List/column.tsx
index 90ad5a829..e7c515a5c 100644
--- a/packages/sqle/src/page/SqlAudit/List/column.tsx
+++ b/packages/sqle/src/page/SqlAudit/List/column.tsx
@@ -68,7 +68,7 @@ const SqlAuditListColumn: (
{
dataIndex: 'sql_audit_record_id',
title: () => t('sqlAudit.list.columns.auditID'),
- render: (id: string) => {
+ render: (id) => {
if (!id) {
return '-';
}
@@ -106,15 +106,17 @@ const SqlAuditListColumn: (
{
dataIndex: 'sql_audit_status',
title: () => t('sqlAudit.list.columns.auditStatus'),
- render: (
- sql_audit_status: getSQLAuditRecordsV1FilterSqlAuditStatusEnum
- ) => {
+ render: (sql_audit_status) => {
if (!sql_audit_status) {
return '-';
}
return (
-
+
);
}
@@ -122,7 +124,7 @@ const SqlAuditListColumn: (
{
dataIndex: 'tags',
title: () => t('sqlAudit.list.columns.businessTag'),
- render: (tags: string[], record) => {
+ render: (tags, record) => {
return (
t('sqlAudit.list.columns.auditTime'),
- render(time: string) {
+ render(time) {
return formatTime(time, '-');
},
width: 200
diff --git a/packages/sqle/src/page/SqlExecWorkflow/List/column.tsx b/packages/sqle/src/page/SqlExecWorkflow/List/column.tsx
index 70914849d..67c5d4840 100644
--- a/packages/sqle/src/page/SqlExecWorkflow/List/column.tsx
+++ b/packages/sqle/src/page/SqlExecWorkflow/List/column.tsx
@@ -63,14 +63,13 @@ export const SqlExecWorkflowListColumn: (
projectID: string
) => ActiontechTableColumn<
IWorkflowDetailResV1,
- SqlExecWorkflowListTableFilterParam,
- 'address'
+ SqlExecWorkflowListTableFilterParam
> = (projectID) => {
return [
{
dataIndex: 'workflow_id',
title: () => t('execWorkflow.list.id'),
- render: (id: string) => {
+ render: (id) => {
return (
@@ -84,7 +83,7 @@ export const SqlExecWorkflowListColumn: (
dataIndex: 'workflow_name',
className: 'workflow-list-table-workflow-name-column',
title: () => t('execWorkflow.list.name'),
- render: (name: string) => (
+ render: (name) => (
{name}
@@ -95,7 +94,7 @@ export const SqlExecWorkflowListColumn: (
dataIndex: 'desc',
title: () => t('execWorkflow.list.desc'),
className: 'workflow-list-table-desc-column',
- render: (desc: string, record: IWorkflowDetailResV1) =>
+ render: (desc, record) =>
desc ? (
t('execWorkflow.list.version'),
filterCustomType: 'select',
filterKey: 'filter_sql_version_id',
- render: (versionNames: string[]) => {
+ render: (versionNames) => {
if (!versionNames || versionNames.length === 0) {
return '-';
}
@@ -149,7 +148,10 @@ export const SqlExecWorkflowListColumn: (
{
dataIndex: 'status',
title: () => t('execWorkflow.list.status'),
- render: (status: IWorkflowDetailResV1['status']) => {
+ render: (status) => {
+ if (!status) {
+ return '-';
+ }
return ;
}
},
@@ -158,7 +160,10 @@ export const SqlExecWorkflowListColumn: (
title: () => t('execWorkflow.list.assignee'),
filterCustomType: 'select',
filterKey: 'filter_current_step_assignee_user_id',
- render: (list: string[]) => {
+ render: (list) => {
+ if (!list) {
+ return '-';
+ }
return list?.map((v) => {
return ;
});