diff --git a/packages/shared/lib/api/sqle/service/SqlManage/index.d.ts b/packages/shared/lib/api/sqle/service/SqlManage/index.d.ts index 75858a868..4d539fe0c 100644 --- a/packages/shared/lib/api/sqle/service/SqlManage/index.d.ts +++ b/packages/shared/lib/api/sqle/service/SqlManage/index.d.ts @@ -24,6 +24,7 @@ import { IGetGlobalSqlManageListResp, IGetGlobalSqlManageStatisticsResp, IGetSqlManageListResp, + IGetAbnormalAuditPlanInstancesResp, IBatchUpdateSqlManageReq, IBaseRes, IGetSqlManageRuleTipsResp, @@ -97,6 +98,13 @@ export interface IGetSqlManageListParams { export interface IGetSqlManageListReturn extends IGetSqlManageListResp {} +export interface IGetAbnormalInstanceAuditPlansV1Params { + project_name: string; +} + +export interface IGetAbnormalInstanceAuditPlansV1Return + extends IGetAbnormalAuditPlanInstancesResp {} + export interface IBatchUpdateSqlManageParams extends IBatchUpdateSqlManageReq { project_name: string; } diff --git a/packages/shared/lib/api/sqle/service/SqlManage/index.ts b/packages/shared/lib/api/sqle/service/SqlManage/index.ts index d96a057cd..bc64fec6e 100644 --- a/packages/shared/lib/api/sqle/service/SqlManage/index.ts +++ b/packages/shared/lib/api/sqle/service/SqlManage/index.ts @@ -13,6 +13,8 @@ import { IGetGlobalSqlManageStatisticsReturn, IGetSqlManageListParams, IGetSqlManageListReturn, + IGetAbnormalInstanceAuditPlansV1Params, + IGetAbnormalInstanceAuditPlansV1Return, IBatchUpdateSqlManageParams, IBatchUpdateSqlManageReturn, IExportSqlManageV1Params, @@ -68,6 +70,21 @@ class SqlManageService extends ServiceBase { ); } + public getAbnormalInstanceAuditPlansV1( + params: IGetAbnormalInstanceAuditPlansV1Params, + options?: AxiosRequestConfig + ) { + const paramsData = this.cloneDeep(params); + const project_name = paramsData.project_name; + delete paramsData.project_name; + + return this.get( + `/v1/projects/${project_name}/sql_manages/abnormal_audit_plan_instance`, + paramsData, + options + ); + } + public BatchUpdateSqlManage( params: IBatchUpdateSqlManageParams, options?: AxiosRequestConfig diff --git a/packages/shared/lib/api/sqle/service/common.d.ts b/packages/shared/lib/api/sqle/service/common.d.ts index a6e1aa73b..e924fece5 100644 --- a/packages/shared/lib/api/sqle/service/common.d.ts +++ b/packages/shared/lib/api/sqle/service/common.d.ts @@ -4,6 +4,8 @@ import { AuditPlanParamResV1TypeEnum, AuditPlanReportResV1AuditLevelEnum, AuditPlanSQLHeadV1TypeEnum, + AuditPlanTypeResBaseActiveStatusEnum, + AuditPlanTypeResBaseLastCollectionStatusEnum, AuditPlanTypesV1InstanceTypeEnum, AuditResDataV1AuditLevelEnum, AuditTaskResV1AuditLevelEnum, @@ -32,6 +34,7 @@ import { HighPriorityConditionReqOperatorEnum, HighPriorityConditionResV1TypeEnum, InstanceAuditPlanInfoActiveStatusEnum, + InstanceAuditPlanInfoLastCollectionStatusEnum, InstanceAuditPlanResV1ActiveStatusEnum, InstanceTipResV1SupportedBackupStrategyEnum, ModuleRedDotModuleNameEnum, @@ -122,6 +125,12 @@ export interface IRuleCategoryStatistic { tag?: string; } +export interface IAbnormalAuditPlanInstance { + instance_audit_plan_id?: number; + + instance_name?: string; +} + export interface IAffectRows { count?: number; @@ -301,10 +310,14 @@ export interface IAuditPlanSQLResV1 { } export interface IAuditPlanTypeResBase { + active_status?: AuditPlanTypeResBaseActiveStatusEnum; + audit_plan_id?: number; desc?: string; + last_collection_status?: AuditPlanTypeResBaseLastCollectionStatusEnum; + token?: string; type?: string; @@ -1072,6 +1085,14 @@ export interface IGenModifylSQLReqV1 { database_schema_objects?: IDatabaseSchemaObject[]; } +export interface IGetAbnormalAuditPlanInstancesResp { + code?: number; + + data?: IAbnormalAuditPlanInstance[]; + + message?: string; +} + export interface IGetAuditPlanAnalysisDataResV1 { code?: number; @@ -2119,6 +2140,8 @@ export interface IInstanceAuditPlanInfo { id?: number; + last_collection_status?: InstanceAuditPlanInfoLastCollectionStatusEnum; + last_collection_time?: string; total_sql_nums?: number; @@ -3994,6 +4017,8 @@ export interface IExecResultCount { export interface IFullSyncAuditPlanSQLsReqV2 { audit_plan_sql_list?: IAuditPlanSQLReqV2[]; + + error_message?: string; } export interface IGetAuditFileExecStatisticRes { @@ -4182,6 +4207,8 @@ export interface IUpdateWorkflowScheduleReqV2 { export interface IUploadInstanceAuditPlanSQLsReqV2 { audit_plan_sql_list?: IAuditPlanSQLReqV2[]; + + error_message?: string; } export interface IWorkflowRecordResV2 { diff --git a/packages/shared/lib/api/sqle/service/common.enum.ts b/packages/shared/lib/api/sqle/service/common.enum.ts index 0534ef9f6..7951af768 100644 --- a/packages/shared/lib/api/sqle/service/common.enum.ts +++ b/packages/shared/lib/api/sqle/service/common.enum.ts @@ -50,6 +50,18 @@ export enum AuditPlanSQLHeadV1TypeEnum { 'sql' = 'sql' } +export enum AuditPlanTypeResBaseActiveStatusEnum { + 'normal' = 'normal', + + 'disabled' = 'disabled' +} + +export enum AuditPlanTypeResBaseLastCollectionStatusEnum { + 'normal' = 'normal', + + 'abnormal' = 'abnormal' +} + export enum AuditPlanTypesV1InstanceTypeEnum { 'MySQL' = 'MySQL', @@ -332,6 +344,12 @@ export enum InstanceAuditPlanInfoActiveStatusEnum { 'disabled' = 'disabled' } +export enum InstanceAuditPlanInfoLastCollectionStatusEnum { + 'normal' = 'normal', + + 'abnormal' = 'abnormal' +} + export enum InstanceAuditPlanResV1ActiveStatusEnum { 'normal' = 'normal', diff --git a/packages/sqle/src/locale/zh-CN/managementConf.ts b/packages/sqle/src/locale/zh-CN/managementConf.ts index bd6cdb184..23cbeef9f 100644 --- a/packages/sqle/src/locale/zh-CN/managementConf.ts +++ b/packages/sqle/src/locale/zh-CN/managementConf.ts @@ -34,7 +34,8 @@ export default { scanStatus: '采集状态', notificationMethod: '推送方式', createdAt: '创建时间', - creator: '创建人' + creator: '创建人', + abnormalTips: 'SQL采集存在异常' }, action: { disabled: { @@ -117,7 +118,14 @@ export default { connectionInfo: '连接信息', collectedSqlCount: '采集到的SQL数', problematicSqlCount: '审核有问题的SQL数', - lastCollectionTime: '最近一次采集时间' + lastCollectionTime: '最近一次采集时间', + taskStatus: { + disabled: '停用', + normal: '运行中', + abnormal: '运行异常' + }, + abnormalTips: + '请根据"execute extract sql failed"关键字到sqled.log日志中检索相关信息' }, actions: { enabled: '启用', diff --git a/packages/sqle/src/locale/zh-CN/sqlManagement.ts b/packages/sqle/src/locale/zh-CN/sqlManagement.ts index 91f3d927e..f313d559c 100644 --- a/packages/sqle/src/locale/zh-CN/sqlManagement.ts +++ b/packages/sqle/src/locale/zh-CN/sqlManagement.ts @@ -13,6 +13,8 @@ export default { problemSQlNum: '问题SQL数', optimizedSQLNum: '已优化SQL数' }, + abnormalAuditPlanTips: + '上的SQL采集存在问题,为保障SQL管控功能正常运行,请及时进行诊断排查', ceTips: 'SQL管控为用户提供SQL全生命周期监控,面板将整合所有的业务SQL,用户可以在该面板中查看项目中采集并审核的所有SQL,暴露其中的问题SQL,同时支持用户解决问题SQL。', table: { diff --git a/packages/sqle/src/page/SqlManagement/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagement/__snapshots__/index.test.tsx.snap index 26245b634..61b08c1dc 100644 --- a/packages/sqle/src/page/SqlManagement/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlManagement/__snapshots__/index.test.tsx.snap @@ -467,7 +467,7 @@ exports[`page/SqlManagement render sql management page 1`] = `
{ payload: [sqlManageListData.data[0]] }); }); + + it('render abnormal status audit plan tips when request return data', async () => { + const request = sqlManage.getAbnormalInstanceAuditPlans(); + request.mockImplementation(() => + createSpySuccessResponse({ data: mockAbnormalInstanceAuditPlansData }) + ); + superRender(); + expect(request).toHaveBeenCalled(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(getBySelector('.ant-alert-warning')).toBeInTheDocument(); + }); }); diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx index b7a14b389..4e5c76955 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx @@ -1,7 +1,13 @@ import { useTranslation } from 'react-i18next'; import { useBoolean, useRequest } from 'ahooks'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { BasicButton, PageHeader, useTypedQuery } from '@actiontech/shared'; +import { + BasicButton, + PageHeader, + useTypedQuery, + TypedLink, + EmptyBox +} from '@actiontech/shared'; import SQLStatistics, { ISQLStatisticsProps } from '../SQLStatistics'; import { useTableFilterContainer, @@ -11,7 +17,7 @@ import { ColumnsSettingProps, useTableRequestParams } from '@actiontech/shared/lib/components/ActiontechTable'; -import SqlManage from '@actiontech/shared/lib/api/sqle/service/SqlManage'; +import { SqlManageService } from '@actiontech/shared/lib/api'; import { IExportSqlManageV1Params, IGetSqlManageListV2Params @@ -42,7 +48,7 @@ import { import { ModalName } from '../../../../data/ModalName'; import { SorterResult, TableRowSelection } from 'antd/es/table/interface'; import { ISqlManage } from '@actiontech/shared/lib/api/sqle/service/common'; -import { Spin, message } from 'antd'; +import { Spin, message, Alert, Space } from 'antd'; import SqlManagementModal from './Modal'; import EmitterKey from '../../../../data/EmitterKey'; import EventEmitter from '../../../../utils/EventEmitter'; @@ -53,7 +59,10 @@ import useGetTableFilterInfo from './hooks/useGetTableFilterInfo'; import { DownArrowLineOutlined } from '@actiontech/icons'; import useSqlManagementExceptionRedux from '../../../SqlManagementException/hooks/useSqlManagementExceptionRedux'; import useWhitelistRedux from '../../../Whitelist/hooks/useWhitelistRedux'; -import { SqlManagementTableStyleWrapper } from './style'; +import { + SqlManagementTableStyleWrapper, + AbnormalAuditPlanTipsStyleWrapper +} from './style'; import { SqlManageAuditStatusEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; import { GetSqlManageListV2FilterSourceEnum } from '@actiontech/shared/lib/api/sqle/service/SqlManage/index.enum'; import { ROUTE_PATHS } from '@actiontech/shared/lib/data/routePaths'; @@ -162,7 +171,9 @@ const SQLEEIndex = () => { ? GetSqlManageListV2FilterPriorityEnum.high : undefined }; - return handleTableRequestError(SqlManage.GetSqlManageListV2(params)); + return handleTableRequestError( + SqlManageService.GetSqlManageListV2(params) + ); }, { refreshDeps: [ @@ -198,6 +209,17 @@ const SQLEEIndex = () => { } ); + const { data: abnormalInstances, loading: getAbnormalInstancesLoading } = + useRequest(() => + SqlManageService.getAbnormalInstanceAuditPlansV1({ + project_name: projectName + }).then((res) => { + if (res.data.code === ResponseCode.SUCCESS) { + return res.data.data; + } + }) + ); + const openModal = useCallback((name: ModalName, row?: ISqlManage) => { if (row) { setSelectData(row); @@ -279,7 +301,7 @@ const SQLEEIndex = () => { return; } updateRemarkProtect.current = true; - SqlManage.BatchUpdateSqlManage({ + SqlManageService.BatchUpdateSqlManage({ project_name: projectName, sql_manage_id_list: [id], remark @@ -368,7 +390,7 @@ const SQLEEIndex = () => { DB_TYPE_RULE_NAME_SEPARATOR )?.[1] } as IExportSqlManageV1Params; - SqlManage.exportSqlManageV1(params, { responseType: 'blob' }) + SqlManageService.exportSqlManageV1(params, { responseType: 'blob' }) .then((res) => { if (res.data.code === ResponseCode.SUCCESS) { messageApi.success( @@ -445,7 +467,7 @@ const SQLEEIndex = () => { }, []); return ( - + {messageContextHolder} { errorMessage={getListError} loading={loading} /> + + + + + {abnormalInstances?.map((instance, index) => { + return ( + + {instance.instance_name} + + ); + })} + + {t('sqlManagement.abnormalAuditPlanTips')} + + } + type="warning" + showIcon + /> + + {/* table */} { filterCustomProps={filterCustomProps} /> ` .ant-table-body { - max-height: calc(100vh - 338px) !important; + max-height: ${(hasAbnormalAuditPlan) => + `calc(100vh - ${hasAbnormalAuditPlan ? '388px' : '338px'}) !important`}; } .audit-status .ant-tag { width: fit-content; } `; + +export const AbnormalAuditPlanTipsStyleWrapper = styled('div')` + padding: 10px 40px 0; +`; diff --git a/packages/sqle/src/page/SqlManagementConf/Common/ConfForm/DataSourceSelection/index.tsx b/packages/sqle/src/page/SqlManagementConf/Common/ConfForm/DataSourceSelection/index.tsx index b95c184b7..db68116c2 100644 --- a/packages/sqle/src/page/SqlManagementConf/Common/ConfForm/DataSourceSelection/index.tsx +++ b/packages/sqle/src/page/SqlManagementConf/Common/ConfForm/DataSourceSelection/index.tsx @@ -11,7 +11,7 @@ import { } from '@actiontech/shared/lib/global'; import { Form } from 'antd'; import useInstance from '../../../../../hooks/useInstance'; -import { useContext, useEffect, useMemo, useCallback } from 'react'; +import { useContext, useEffect, useMemo } from 'react'; import useDatabaseType from '../../../../../hooks/useDatabaseType'; import { ConfFormContext } from '../context'; import { SqlManagementConfFormFields } from '../index.type'; @@ -103,8 +103,8 @@ const DataSourceSelection: React.FC = () => { updateDriverNameList(); }, [updateDriverNameList]); - const updateInstanceListByProjectName = useCallback( - (id: string) => { + useEffect(() => { + if (!!instanceIdByUrlSearchParams && !!businessByUrlSearchParams) { updateInstanceList( { project_name: projectName, @@ -113,34 +113,32 @@ const DataSourceSelection: React.FC = () => { }, { onSuccess: (list) => { - const instance = list.find((v) => v.instance_id === id); + const instance = list.find( + (v) => v.instance_id === instanceIdByUrlSearchParams + ); form.setFieldsValue({ + businessScope: businessByUrlSearchParams, + instanceId: instanceIdByUrlSearchParams, instanceName: instance?.instance_name ?? '', instanceType: instance?.instance_type ?? '' }); } } ); - }, - [form, projectName, updateInstanceList] - ); - - useEffect(() => { - if (!!instanceIdByUrlSearchParams && !!businessByUrlSearchParams) { - form.setFieldsValue({ - businessScope: businessByUrlSearchParams, - instanceId: instanceIdByUrlSearchParams - }); - updateInstanceListByProjectName(instanceIdByUrlSearchParams); } else if (!!defaultValue) { - updateInstanceListByProjectName(defaultValue.instanceId as string); + updateInstanceList({ + project_name: projectName, + functional_module: + getInstanceTipListV1FunctionalModuleEnum.create_audit_plan + }); } }, [ businessByUrlSearchParams, instanceIdByUrlSearchParams, defaultValue, - updateInstanceListByProjectName, - form + updateInstanceList, + form, + projectName ]); useEffect(() => { diff --git a/packages/sqle/src/page/SqlManagementConf/Detail/Overview/__tests__/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagementConf/Detail/Overview/__tests__/__snapshots__/index.test.tsx.snap index 8a4a71092..35f5f081b 100644 --- a/packages/sqle/src/page/SqlManagementConf/Detail/Overview/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlManagementConf/Detail/Overview/__tests__/__snapshots__/index.test.tsx.snap @@ -1,5 +1,500 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`test Overview render abnormal status audit plan 1`] = ` +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 智能扫描类型 + + 审核规则模板 + + 任务状态 + + 连接信息 + + 采集到的SQL数 + + 审核有问题的SQL数 + + 最近一次采集时间 + + 操作 +
+ + 库表元数据 + + + + default_MySQL + + +
+
+
+ + + +
+
+ + 运行异常 + +
+
+ - + + 0 + + 0 + + 2024-08-06 11:30:43 + +
+
+
+ +
+
+ +
+
+ +
+
+
+
+ + 慢日志 + + + + mysql_rule_template + + +
+ + + + + 未知状态... + +
+
+ +
+
+ + + + + +
+
+ +
+ + + +
+
+
+
+ 0 + + 0 + + - + +
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+`; + exports[`test Overview should match snapshot when hasOpPermission is equal false 1`] = `
{ return { @@ -175,4 +177,27 @@ describe('test Overview', () => { const { container } = customRender(); expect(container).toMatchSnapshot(); }); + + it('render abnormal status audit plan', async () => { + getInstanceAuditPlanOverviewSpy.mockImplementation(() => + createSpySuccessResponse({ + data: [ + { + ...mockInstanceAuditPlanInfo[0], + active_status: InstanceAuditPlanInfoActiveStatusEnum.normal, + last_collection_status: + InstanceAuditPlanInfoLastCollectionStatusEnum.abnormal + }, + { + ...mockInstanceAuditPlanInfo[1], + active_status: undefined + } + ] + }) + ); + const { container } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(container).toMatchSnapshot(); + expect(screen.getByText('运行异常')).toBeInTheDocument(); + }); }); diff --git a/packages/sqle/src/page/SqlManagementConf/Detail/Overview/column.tsx b/packages/sqle/src/page/SqlManagementConf/Detail/Overview/column.tsx index b59e85e78..7e93325bb 100644 --- a/packages/sqle/src/page/SqlManagementConf/Detail/Overview/column.tsx +++ b/packages/sqle/src/page/SqlManagementConf/Detail/Overview/column.tsx @@ -2,13 +2,17 @@ import { ActiontechTableColumn } from '@actiontech/shared/lib/components/Actiont import { t } from '../../../../locale'; import { formatTime } from '@actiontech/shared/lib/utils/Common'; import { IInstanceAuditPlanInfo } from '@actiontech/shared/lib/api/sqle/service/common'; -import { SensitiveDisplay, TypedLink } from '@actiontech/shared'; -import { InstanceAuditPlanInfoActiveStatusEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { SensitiveDisplay, TypedLink, BasicToolTip } from '@actiontech/shared'; +import { + InstanceAuditPlanInfoLastCollectionStatusEnum, + InstanceAuditPlanInfoActiveStatusEnum +} from '@actiontech/shared/lib/api/sqle/service/common.enum'; import { TableColumnWithIconStyleWrapper } from '@actiontech/shared/lib/styleWrapper/element'; import { CheckCircleOutlined, CloseHexagonOutlined, - InfoHexagonOutlined + InfoHexagonOutlined, + InfoCircleOutlined } from '@actiontech/icons'; import { Typography } from 'antd'; import { ROUTE_PATHS } from '@actiontech/shared/lib/data/routePaths'; @@ -62,13 +66,30 @@ export const ConfDetailOverviewColumns: ( { dataIndex: 'active_status', title: () => t('managementConf.detail.overview.column.status'), - render: (status) => { + render: (status, record) => { if (status === InstanceAuditPlanInfoActiveStatusEnum.disabled) { return ( - {t('managementConf.list.table.column.taskStatus.disabled')} + {t('managementConf.detail.overview.column.taskStatus.disabled')} + + + ); + } + if ( + status === InstanceAuditPlanInfoActiveStatusEnum.normal && + record.last_collection_status === + InstanceAuditPlanInfoLastCollectionStatusEnum.abnormal + ) { + return ( + + } + title={t('managementConf.detail.overview.column.abnormalTips')} + /> + + {t('managementConf.detail.overview.column.taskStatus.abnormal')} ); @@ -78,7 +99,7 @@ export const ConfDetailOverviewColumns: ( - {t('managementConf.list.table.column.taskStatus.normal')} + {t('managementConf.detail.overview.column.taskStatus.normal')} ); diff --git a/packages/sqle/src/page/SqlManagementConf/Detail/__tests__/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagementConf/Detail/__tests__/__snapshots__/index.test.tsx.snap index 29080a8e1..7a5275369 100644 --- a/packages/sqle/src/page/SqlManagementConf/Detail/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlManagementConf/Detail/__tests__/__snapshots__/index.test.tsx.snap @@ -759,7 +759,7 @@ exports[`test SqlManagementConf/Detail/index.tsx should match snapshot 2`] = ` /> - 启用 + 运行中
@@ -1060,7 +1060,7 @@ exports[`test SqlManagementConf/Detail/index.tsx should match snapshot 2`] = ` /> - 启用 + 运行中
@@ -1178,7 +1178,7 @@ exports[`test SqlManagementConf/Detail/index.tsx should match snapshot 2`] = ` /> - 启用 + 运行中
diff --git a/packages/sqle/src/page/SqlManagementConf/List/__tests__/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagementConf/List/__tests__/__snapshots__/index.test.tsx.snap index 203e5b050..56df12818 100644 --- a/packages/sqle/src/page/SqlManagementConf/List/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlManagementConf/List/__tests__/__snapshots__/index.test.tsx.snap @@ -575,11 +575,23 @@ exports[`test sqle/SqlManagementConf/List render close task type filter field 1` - - 静态扫描 - + +
+
- - test instance name - + +
+
- - 静态扫描 - + +
+
- - 静态扫描 - + +
+
- - test instance name - + +
+
- - 静态扫描 - + +
+
`; + +exports[`test sqle/SqlManagementConf/List render sql management conf list with audit plan active status 1`] = ` + +
+
+
+
+ SQL管控配置 +
+ +
+
+
+
+
+
+
+
+
+ + + + + + + + +
+
+ +
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+ + 全部数据源 + + + + + +
+
+ + 全部任务类型 + + + + + + + + + + +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 数据源名称 + + 数据源类型 + + 所属业务 + + 启用的扫描类型 + + 数据源任务状态 + + 创建时间 + + 创建人 + + 操作 +
+
+ +
+
+
+ + + +
+
+
+
+
+
+ + + MySQL + +
+
+ test + + + +
+ + + + + 启用 + +
+
+ 2024-07-29 16:12:35 + + admin + +
+ + +
+
+
+
+
+
    +
  • + + 共 1 条数据 + +
  • +
  • + +
  • +
  • + + 1 + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+
+
+
+
+
+ +`; diff --git a/packages/sqle/src/page/SqlManagementConf/List/__tests__/index.test.tsx b/packages/sqle/src/page/SqlManagementConf/List/__tests__/index.test.tsx index a3a467c05..c9127466f 100644 --- a/packages/sqle/src/page/SqlManagementConf/List/__tests__/index.test.tsx +++ b/packages/sqle/src/page/SqlManagementConf/List/__tests__/index.test.tsx @@ -23,6 +23,10 @@ import { import instance from '../../../../testUtils/mockApi/instance'; import { InstanceAuditPlanStatusEnum } from '../index.enum'; import { mockUsePermission } from '@actiontech/shared/lib/testUtil/mockHook/mockUsePermission'; +import { + AuditPlanTypeResBaseActiveStatusEnum, + AuditPlanTypeResBaseLastCollectionStatusEnum +} from '@actiontech/shared/lib/api/sqle/service/common.enum'; jest.mock('react-redux', () => { return { @@ -77,6 +81,32 @@ describe('test sqle/SqlManagementConf/List', () => { expect(getInstanceTipListSpy).toHaveBeenCalled(); }); + it('render sql management conf list with audit plan active status', async () => { + getInstanceAuditPlansSpy.mockClear(); + getInstanceAuditPlansSpy.mockImplementation(() => + createSpySuccessResponse({ + data: [ + { + ...mockInstanceAuditPlanListData[0], + audit_plan_types: [ + { + audit_plan_id: 1, + type: 'sql_file', + desc: 'SQL文件', + active_status: AuditPlanTypeResBaseActiveStatusEnum.normal, + last_collection_status: + AuditPlanTypeResBaseLastCollectionStatusEnum.abnormal + } + ] + } + ] + }) + ); + const { baseElement } = superRender(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(baseElement).toMatchSnapshot(); + }); + it('render create button when project is archived', async () => { mockUseCurrentUser({ bindProjects: [ diff --git a/packages/sqle/src/page/SqlManagementConf/List/column.tsx b/packages/sqle/src/page/SqlManagementConf/List/column.tsx index a6111a820..5e22fca42 100644 --- a/packages/sqle/src/page/SqlManagementConf/List/column.tsx +++ b/packages/sqle/src/page/SqlManagementConf/List/column.tsx @@ -4,7 +4,12 @@ import { ActiontechTableFilterMetaValue } from '@actiontech/shared/lib/components/ActiontechTable'; import { t } from '../../../locale'; -import { DatabaseTypeLogo, TypedLink } from '@actiontech/shared'; +import { + DatabaseTypeLogo, + TypedLink, + BasicToolTip, + EmptyBox +} from '@actiontech/shared'; import { IInstanceAuditPlanResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import { InstanceAuditPlanTableFilterParamType } from './index.type'; import { formatTime } from '@actiontech/shared/lib/utils/Common'; @@ -13,10 +18,16 @@ import { CloseHexagonOutlined, InfoHexagonOutlined } from '@actiontech/icons'; -import { InstanceAuditPlanResV1ActiveStatusEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { + InstanceAuditPlanResV1ActiveStatusEnum, + AuditPlanTypeResBaseLastCollectionStatusEnum, + AuditPlanTypeResBaseActiveStatusEnum +} from '@actiontech/shared/lib/api/sqle/service/common.enum'; import ScanTypeTagsCell from './ScanTypeTagsCell'; import { TableColumnWithIconStyleWrapper } from '@actiontech/shared/lib/styleWrapper/element'; import { ROUTE_PATHS } from '@actiontech/shared/lib/data/routePaths'; +import { InfoCircleOutlined } from '@actiontech/icons/'; +import { PlanListTaskTypeButtonStyleWrapper } from './style'; export const ExtraFilterMeta: () => ActiontechTableFilterMeta< IInstanceAuditPlanResV1, @@ -49,17 +60,32 @@ export const SqlManagementConfColumns: ( dataIndex: 'instance_name', title: () => t('managementConf.list.table.column.dbName'), render: (instanceName, record) => { + const hasAbnormalPlan = record.audit_plan_types?.some( + (plan) => + plan.active_status === + AuditPlanTypeResBaseActiveStatusEnum.normal && + plan.last_collection_status === + AuditPlanTypeResBaseLastCollectionStatusEnum.abnormal + ); return ( - - {instanceName || - t('managementConf.list.table.column.staticScanType')} - + + + {instanceName || + t('managementConf.list.table.column.staticScanType')} + + + } + title={t('managementConf.list.table.column.abnormalTips')} + /> + + ); }, filterCustomType: 'select', diff --git a/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts b/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts index 42aa67d85..720cf64b9 100644 --- a/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts +++ b/packages/sqle/src/testUtils/mockApi/sqlManage/data.ts @@ -1,4 +1,5 @@ import { SqlManageAuditStatusEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { IAbnormalAuditPlanInstance } from '@actiontech/shared/lib/api/sqle/service/common.d'; export const ruleTipsData = [ { @@ -319,3 +320,15 @@ export const mockSqlManageSqlAnalysisChartData = { } ] }; + +export const mockAbnormalInstanceAuditPlansData: IAbnormalAuditPlanInstance[] = + [ + { + instance_audit_plan_id: 1, + instance_name: 'mysql-1' + }, + { + instance_audit_plan_id: 2, + instance_name: 'mysql-2' + } + ]; diff --git a/packages/sqle/src/testUtils/mockApi/sqlManage/index.ts b/packages/sqle/src/testUtils/mockApi/sqlManage/index.ts index 1ae260cff..14033e648 100644 --- a/packages/sqle/src/testUtils/mockApi/sqlManage/index.ts +++ b/packages/sqle/src/testUtils/mockApi/sqlManage/index.ts @@ -20,6 +20,7 @@ class MockSqlManageApi implements MockSpyApy { this.getGlobalSqlManageStatistics(); this.sendSqlManage(); this.getSqlManageSqlAnalysisChart(); + this.getAbnormalInstanceAuditPlans(); } public getSqlManageRuleTips() { @@ -93,6 +94,12 @@ class MockSqlManageApi implements MockSpyApy { ); return spy; } + + public getAbnormalInstanceAuditPlans() { + const spy = jest.spyOn(SqlManage, 'getAbnormalInstanceAuditPlansV1'); + spy.mockImplementation(() => createSpySuccessResponse({})); + return spy; + } } export default new MockSqlManageApi();