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 127453e5d8..47e4da1ef4 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 { exportSqlManageV2FilterStatusEnum, exportSqlManageV2SortFieldEnum, exportSqlManageV2SortOrderEnum, + exportSqlManageV2ExportFormatEnum, GetSqlManageListV3FilterSourceEnum, GetSqlManageListV3FilterAuditLevelEnum, GetSqlManageListV3FilterStatusEnum, @@ -280,6 +281,8 @@ export interface IExportSqlManageV2Params { sort_field?: exportSqlManageV2SortFieldEnum; sort_order?: exportSqlManageV2SortOrderEnum; + + export_format?: exportSqlManageV2ExportFormatEnum; } export interface IGetSqlManageListV3Params { diff --git a/packages/shared/lib/api/sqle/service/SqlManage/index.enum.ts b/packages/shared/lib/api/sqle/service/SqlManage/index.enum.ts index fc2401c3cd..0d04710fc9 100644 --- a/packages/shared/lib/api/sqle/service/SqlManage/index.enum.ts +++ b/packages/shared/lib/api/sqle/service/SqlManage/index.enum.ts @@ -196,6 +196,12 @@ export enum exportSqlManageV2SortOrderEnum { 'desc' = 'desc' } +export enum exportSqlManageV2ExportFormatEnum { + 'csv' = 'csv', + + 'excel' = 'excel' +} + export enum GetSqlManageListV3FilterSourceEnum { 'audit_plan' = 'audit_plan', diff --git a/packages/shared/lib/api/sqle/service/common.d.ts b/packages/shared/lib/api/sqle/service/common.d.ts index c014105753..ce9d9d419d 100644 --- a/packages/shared/lib/api/sqle/service/common.d.ts +++ b/packages/shared/lib/api/sqle/service/common.d.ts @@ -29,6 +29,7 @@ import { DirectAuditReqV1SqlTypeEnum, FilterMetaFilterInputTypeEnum, FilterMetaFilterOpTypeEnum, + GetAuditPlanSQLExportReqV1ExportFormatEnum, GetWorkflowTasksItemV1StatusEnum, GlobalSqlManageProjectPriorityEnum, GlobalSqlManageStatusEnum, @@ -1352,6 +1353,8 @@ export interface IGetAuditPlanSQLDataResV1 { } export interface IGetAuditPlanSQLExportReqV1 { + export_format?: GetAuditPlanSQLExportReqV1ExportFormatEnum; + filter_list?: IFilter[]; is_asc?: boolean; diff --git a/packages/shared/lib/api/sqle/service/common.enum.ts b/packages/shared/lib/api/sqle/service/common.enum.ts index d99d7ac479..22673aec8c 100644 --- a/packages/shared/lib/api/sqle/service/common.enum.ts +++ b/packages/shared/lib/api/sqle/service/common.enum.ts @@ -294,6 +294,12 @@ export enum FilterMetaFilterOpTypeEnum { 'between' = 'between' } +export enum GetAuditPlanSQLExportReqV1ExportFormatEnum { + 'csv' = 'csv', + + 'excel' = 'excel' +} + export enum GetWorkflowTasksItemV1StatusEnum { 'wait_for_audit' = 'wait_for_audit', diff --git a/packages/shared/lib/api/sqle/service/workflow/index.d.ts b/packages/shared/lib/api/sqle/service/workflow/index.d.ts index bdbcc3252f..c899fa201c 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.d.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.d.ts @@ -45,6 +45,7 @@ import { getWorkflowsV1FilterStatusEnum, autoCreateAndExecuteWorkflowV1ExecModeEnum, exportWorkflowV1FilterStatusEnum, + exportWorkflowV1ExportFormatEnum, GetBackupSqlListV1FilterExecStatusEnum } from './index.enum'; @@ -245,6 +246,8 @@ export interface IExportWorkflowV1Params { project_name: string; fuzzy_keyword?: string; + + export_format?: exportWorkflowV1ExportFormatEnum; } export interface IGetBackupSqlListV1Params { diff --git a/packages/shared/lib/api/sqle/service/workflow/index.enum.ts b/packages/shared/lib/api/sqle/service/workflow/index.enum.ts index 560febbc55..6dd919cb8f 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.enum.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.enum.ts @@ -134,6 +134,12 @@ export enum exportWorkflowV1FilterStatusEnum { 'finished' = 'finished' } +export enum exportWorkflowV1ExportFormatEnum { + 'csv' = 'csv', + + 'excel' = 'excel' +} + export enum GetBackupSqlListV1FilterExecStatusEnum { 'initialized' = 'initialized', diff --git a/packages/sqle/src/components/ExportFormatModal/__tests__/__snapshots__/index.test.tsx.snap b/packages/sqle/src/components/ExportFormatModal/__tests__/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000..6e1ed4e657 --- /dev/null +++ b/packages/sqle/src/components/ExportFormatModal/__tests__/__snapshots__/index.test.tsx.snap @@ -0,0 +1,167 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ExportFormatModal should render modal with correct title and options 1`] = ` + +
+
+
+
+
+ +
+ +`; diff --git a/packages/sqle/src/components/ExportFormatModal/__tests__/index.test.tsx b/packages/sqle/src/components/ExportFormatModal/__tests__/index.test.tsx new file mode 100644 index 0000000000..65372a7e61 --- /dev/null +++ b/packages/sqle/src/components/ExportFormatModal/__tests__/index.test.tsx @@ -0,0 +1,66 @@ +import { fireEvent, screen } from '@testing-library/react'; +import ExportFormatModal from '../index'; +import { sqleSuperRender } from '../../../testUtils/superRender'; +import { GetAuditPlanSQLExportReqV1ExportFormatEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; + +describe('ExportFormatModal', () => { + const mockOnFormatChange = jest.fn(); + const mockOnConfirm = jest.fn(); + const mockOnCancel = jest.fn(); + + const defaultProps = { + open: true, + selectedFormat: GetAuditPlanSQLExportReqV1ExportFormatEnum.csv, + onFormatChange: mockOnFormatChange, + onConfirm: mockOnConfirm, + onCancel: mockOnCancel + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should render modal with correct title and options', () => { + const { baseElement } = sqleSuperRender( + + ); + + expect(screen.getByText('选择导出文件格式')).toBeInTheDocument(); + expect(screen.getByText('CSV')).toBeInTheDocument(); + expect(screen.getByText('Excel')).toBeInTheDocument(); + expect(baseElement).toMatchSnapshot(); + }); + + it('should not render modal when open is false', () => { + sqleSuperRender(); + + expect(screen.queryByText('选择导出文件格式')).not.toBeInTheDocument(); + }); + + it('should call onFormatChange when format is changed', () => { + sqleSuperRender(); + + const excelRadio = screen.getByText('Excel'); + fireEvent.click(excelRadio); + + expect(mockOnFormatChange).toHaveBeenCalledWith('excel'); + }); + + it('should call onConfirm when confirm button is clicked', () => { + sqleSuperRender(); + + const confirmButton = screen.getByText('确 认'); + fireEvent.click(confirmButton); + + expect(mockOnConfirm).toHaveBeenCalledTimes(1); + }); + + it('should call onCancel when cancel button is clicked', () => { + sqleSuperRender(); + + const cancelButton = screen.getByText('取 消'); + fireEvent.click(cancelButton); + + expect(mockOnCancel).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/sqle/src/components/ExportFormatModal/index.tsx b/packages/sqle/src/components/ExportFormatModal/index.tsx new file mode 100644 index 0000000000..b4f42527e8 --- /dev/null +++ b/packages/sqle/src/components/ExportFormatModal/index.tsx @@ -0,0 +1,55 @@ +import { BasicButton, BasicModal } from '@actiontech/dms-kit'; +import { Radio, Space } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { GetAuditPlanSQLExportReqV1ExportFormatEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; + +export interface ExportFormatModalProps { + open: boolean; + selectedFormat: GetAuditPlanSQLExportReqV1ExportFormatEnum; + onFormatChange: (format: GetAuditPlanSQLExportReqV1ExportFormatEnum) => void; + onConfirm: () => void; + onCancel: () => void; +} + +const ExportFormatModal = ({ + open, + selectedFormat, + onFormatChange, + onConfirm, + onCancel +}: ExportFormatModalProps) => { + const { t } = useTranslation(); + + return ( + + {t('common.cancel')} + + {t('common.ok')} + + + } + > + onFormatChange(e.target.value)} + > + + + CSV + + + Excel + + + + + ); +}; + +export default ExportFormatModal; diff --git a/packages/sqle/src/hooks/useExportFormatModal/__tests__/index.test.tsx b/packages/sqle/src/hooks/useExportFormatModal/__tests__/index.test.tsx new file mode 100644 index 0000000000..a1aa2817c4 --- /dev/null +++ b/packages/sqle/src/hooks/useExportFormatModal/__tests__/index.test.tsx @@ -0,0 +1,69 @@ +import { renderHook, act } from '@testing-library/react'; +import { useExportFormatModal } from '../index'; +import { GetAuditPlanSQLExportReqV1ExportFormatEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; + +describe('useExportFormatModal', () => { + it('should initialize with default format', () => { + const { result } = renderHook(() => + useExportFormatModal(GetAuditPlanSQLExportReqV1ExportFormatEnum.csv) + ); + + expect(result.current.exportFormatModalVisible).toBe(false); + expect(result.current.selectedExportFormat).toBe( + GetAuditPlanSQLExportReqV1ExportFormatEnum.csv + ); + }); + + it('should show and hide modal', () => { + const { result } = renderHook(() => + useExportFormatModal(GetAuditPlanSQLExportReqV1ExportFormatEnum.csv) + ); + + act(() => { + result.current.showExportFormatModal(); + }); + expect(result.current.exportFormatModalVisible).toBe(true); + + act(() => { + result.current.hideExportFormatModal(); + }); + expect(result.current.exportFormatModalVisible).toBe(false); + }); + + it('should change selected format', () => { + const { result } = renderHook(() => + useExportFormatModal(GetAuditPlanSQLExportReqV1ExportFormatEnum.csv) + ); + + act(() => { + result.current.setSelectedExportFormat( + GetAuditPlanSQLExportReqV1ExportFormatEnum.excel + ); + }); + expect(result.current.selectedExportFormat).toBe( + GetAuditPlanSQLExportReqV1ExportFormatEnum.excel + ); + }); + + it('should reset format to default', () => { + const { result } = renderHook(() => + useExportFormatModal(GetAuditPlanSQLExportReqV1ExportFormatEnum.csv) + ); + + act(() => { + result.current.setSelectedExportFormat( + GetAuditPlanSQLExportReqV1ExportFormatEnum.excel + ); + }); + expect(result.current.selectedExportFormat).toBe( + GetAuditPlanSQLExportReqV1ExportFormatEnum.excel + ); + + act(() => { + result.current.resetFormat(); + }); + expect(result.current.selectedExportFormat).toBe( + GetAuditPlanSQLExportReqV1ExportFormatEnum.csv + ); + }); +}); diff --git a/packages/sqle/src/hooks/useExportFormatModal/index.tsx b/packages/sqle/src/hooks/useExportFormatModal/index.tsx new file mode 100644 index 0000000000..99f9f28a12 --- /dev/null +++ b/packages/sqle/src/hooks/useExportFormatModal/index.tsx @@ -0,0 +1,27 @@ +import { useState } from 'react'; +import { useBoolean } from 'ahooks'; +import { GetAuditPlanSQLExportReqV1ExportFormatEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; + +export const useExportFormatModal = ( + defaultFormat: GetAuditPlanSQLExportReqV1ExportFormatEnum +) => { + const [ + exportFormatModalVisible, + { setTrue: showExportFormatModal, setFalse: hideExportFormatModal } + ] = useBoolean(false); + const [selectedExportFormat, setSelectedExportFormat] = + useState(defaultFormat); + + const resetFormat = () => { + setSelectedExportFormat(defaultFormat); + }; + + return { + exportFormatModalVisible, + showExportFormatModal, + hideExportFormatModal, + selectedExportFormat, + setSelectedExportFormat, + resetFormat + }; +}; diff --git a/packages/sqle/src/locale/en-US/sqlManagement.ts b/packages/sqle/src/locale/en-US/sqlManagement.ts index f984bb7e7f..a52c99dd8c 100644 --- a/packages/sqle/src/locale/en-US/sqlManagement.ts +++ b/packages/sqle/src/locale/en-US/sqlManagement.ts @@ -5,7 +5,10 @@ export default { action: { export: 'Export', exporting: 'Exporting file', - exportSuccessTips: 'Export file successfully' + exportSuccessTips: 'Export file successfully', + exportFormatModal: { + title: 'Select export file format' + } } }, statistics: { diff --git a/packages/sqle/src/locale/zh-CN/sqlManagement.ts b/packages/sqle/src/locale/zh-CN/sqlManagement.ts index 17e2b2b014..9d1f95c2e4 100644 --- a/packages/sqle/src/locale/zh-CN/sqlManagement.ts +++ b/packages/sqle/src/locale/zh-CN/sqlManagement.ts @@ -5,7 +5,10 @@ export default { action: { export: '导出', exporting: '正在导出文件', - exportSuccessTips: '导出文件成功' + exportSuccessTips: '导出文件成功', + exportFormatModal: { + title: '选择导出文件格式' + } } }, statistics: { diff --git a/packages/sqle/src/page/SqlExecWorkflow/List/__tests__/index.test.tsx b/packages/sqle/src/page/SqlExecWorkflow/List/__tests__/index.test.tsx index cfec8034df..127656dc9f 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/List/__tests__/index.test.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/List/__tests__/index.test.tsx @@ -259,6 +259,15 @@ describe('sqle/Workflow/List', () => { expect(screen.getByText('导出工单')).toBeInTheDocument(); fireEvent.click(screen.getByText('导出工单')); + + await act(async () => jest.advanceTimersByTime(0)); + expect(screen.getByText('选择导出文件格式')).toBeInTheDocument(); + expect(screen.getByText('CSV')).toBeInTheDocument(); + expect(screen.getByText('Excel')).toBeInTheDocument(); + + fireEvent.click(screen.getByText('确 认')); + + await act(async () => jest.advanceTimersByTime(0)); expect(RequestExportWorkflowList).toHaveBeenCalled(); expect(RequestExportWorkflowList).toHaveBeenCalledWith( { @@ -272,7 +281,8 @@ describe('sqle/Workflow/List', () => { filter_task_execute_start_time_to: undefined, filter_task_instance_name: undefined, fuzzy_keyword: '', - project_name: projectName + project_name: projectName, + export_format: 'csv' }, { responseType: 'blob' } ); diff --git a/packages/sqle/src/page/SqlExecWorkflow/List/components/ExportWorkflowButton/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/List/components/ExportWorkflowButton/index.tsx index dddf42decf..36ab58753f 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/List/components/ExportWorkflowButton/index.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/List/components/ExportWorkflowButton/index.tsx @@ -7,6 +7,10 @@ import { message } from 'antd'; import { useTranslation } from 'react-i18next'; import { ExportWorkflowButtonProps } from './index.type'; import { SqlExecWorkflowExportAction } from '../../action'; +import { exportWorkflowV1ExportFormatEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; +import { useExportFormatModal } from '../../../../../hooks/useExportFormatModal'; +import ExportFormatModal from '../../../../../components/ExportFormatModal'; +import { GetAuditPlanSQLExportReqV1ExportFormatEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; const ExportWorkflowButton: React.FC = ({ tableFilterInfo, @@ -21,7 +25,16 @@ const ExportWorkflowButton: React.FC = ({ exportButtonDisabled, { setFalse: finishExport, setTrue: startExport } ] = useBoolean(false); + const { + exportFormatModalVisible, + showExportFormatModal, + hideExportFormatModal, + selectedExportFormat, + setSelectedExportFormat + } = useExportFormatModal(GetAuditPlanSQLExportReqV1ExportFormatEnum.csv); + const exportWorkflow = () => { + hideExportFormatModal(); startExport(); const hideLoading = messageApi.loading( t('execWorkflow.list.exportWorkflow.exporting') @@ -50,7 +63,9 @@ const ExportWorkflowButton: React.FC = ({ filter_create_time_to, filter_task_execute_start_time_from, filter_task_execute_start_time_to, - fuzzy_keyword: searchKeyword + fuzzy_keyword: searchKeyword, + export_format: + selectedExportFormat as unknown as exportWorkflowV1ExportFormatEnum }; workflow @@ -71,7 +86,14 @@ const ExportWorkflowButton: React.FC = ({ return ( <> {messageContextHolder} - {SqlExecWorkflowExportAction(exportWorkflow, exportButtonDisabled)} + {SqlExecWorkflowExportAction(showExportFormatModal, exportButtonDisabled)} + ); }; diff --git a/packages/sqle/src/page/SqlExecWorkflow/List/components/__tests__/ExportWorkflowButton.test.tsx b/packages/sqle/src/page/SqlExecWorkflow/List/components/__tests__/ExportWorkflowButton.test.tsx index aafeff52f7..6facddf0dc 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/List/components/__tests__/ExportWorkflowButton.test.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/List/components/__tests__/ExportWorkflowButton.test.tsx @@ -1,7 +1,10 @@ -import { exportWorkflowV1FilterStatusEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; +import { + exportWorkflowV1FilterStatusEnum, + exportWorkflowV1ExportFormatEnum +} from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; import { sqleSuperRender } from '../../../../../testUtils/superRender'; import ExportWorkflowButton from '../ExportWorkflowButton'; -import { fireEvent } from '@testing-library/dom'; +import { fireEvent, screen } from '@testing-library/dom'; import execWorkflow from '@actiontech/shared/lib/testUtil/mockApi/sqle/execWorkflow'; import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; import { mockProjectInfo } from '@actiontech/shared/lib/testUtil/mockHook/data'; @@ -31,8 +34,8 @@ describe('test ExportWorkflowButton', () => { jest.clearAllMocks(); jest.clearAllTimers(); }); - it('should be called request with params when the button is clicked', async () => { - const { getByText } = sqleSuperRender( + it('should export with CSV format by default when clicking OK', async () => { + const { getByText, baseElement } = sqleSuperRender( { ); fireEvent.click(getByText('导出工单')); + + await act(async () => jest.advanceTimersByTime(0)); + expect(screen.getByText('选择导出文件格式')).toBeInTheDocument(); + + expect(baseElement).toMatchSnapshot(); + + fireEvent.click(screen.getByText('确 认')); + + await act(async () => jest.advanceTimersByTime(0)); expect(RequestExportWorkflowList).toHaveBeenCalledTimes(1); expect(RequestExportWorkflowList).toHaveBeenCalledWith( { @@ -61,7 +73,8 @@ describe('test ExportWorkflowButton', () => { filter_task_instance_id: '1739531942258282496', filter_status: exportWorkflowV1FilterStatusEnum.exec_failed, fuzzy_keyword: 'filter value', - project_name: mockProjectInfo.projectName + project_name: mockProjectInfo.projectName, + export_format: exportWorkflowV1ExportFormatEnum.csv }, { responseType: 'blob' } ); diff --git a/packages/sqle/src/page/SqlExecWorkflow/List/components/__tests__/__snapshots__/ExportWorkflowButton.test.tsx.snap b/packages/sqle/src/page/SqlExecWorkflow/List/components/__tests__/__snapshots__/ExportWorkflowButton.test.tsx.snap new file mode 100644 index 0000000000..1127b1b961 --- /dev/null +++ b/packages/sqle/src/page/SqlExecWorkflow/List/components/__tests__/__snapshots__/ExportWorkflowButton.test.tsx.snap @@ -0,0 +1,191 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`test ExportWorkflowButton should export with CSV format by default when clicking OK 1`] = ` + +
+ +
+
+
+
+
+ +
+ +`; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.test.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.test.tsx index fdd889ae54..08481b8af0 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.test.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.test.tsx @@ -23,7 +23,8 @@ import { ModalName } from '../../../../data/ModalName'; import { mockUseAuditPlanTypes } from '../../../../testUtils/mockRequest'; import { GetSqlManageListV2FilterPriorityEnum, - exportSqlManageV1FilterPriorityEnum + exportSqlManageV1FilterPriorityEnum, + exportSqlManageV2ExportFormatEnum } from '@actiontech/shared/lib/api/sqle/service/SqlManage/index.enum'; import { SupportLanguage } from '@actiontech/dms-kit'; import { SystemRole } from '@actiontech/dms-kit'; @@ -285,11 +286,20 @@ describe('page/SqlManagement/SQLEEIndex', () => { expect(screen.getByText('导出')).toBeInTheDocument(); fireEvent.click(screen.getByText('导出')); + + await act(async () => jest.advanceTimersByTime(300)); + expect(screen.getByText('选择导出文件格式')).toBeInTheDocument(); + expect(screen.getByText('CSV')).toBeInTheDocument(); + expect(screen.getByText('Excel')).toBeInTheDocument(); + + fireEvent.click(screen.getByText('确 认')); + expect(exportRequest).toHaveBeenCalledWith( { ...exportParams, filter_assignee: mockCurrentUserReturn.userId, - filter_priority: exportSqlManageV1FilterPriorityEnum.high + filter_priority: exportSqlManageV1FilterPriorityEnum.high, + export_format: exportSqlManageV2ExportFormatEnum.csv }, { responseType: 'blob' diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx index 51ef5c6371..946cc4c881 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx @@ -3,6 +3,9 @@ import { useBoolean, useRequest } from 'ahooks'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { BasicButton, PageHeader } from '@actiontech/dms-kit'; import { useTypedQuery } from '@actiontech/shared'; +import { useExportFormatModal } from '../../../../hooks/useExportFormatModal'; +import ExportFormatModal from '../../../../components/ExportFormatModal'; +import { GetAuditPlanSQLExportReqV1ExportFormatEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; import SQLStatistics, { ISQLStatisticsProps } from '../SQLStatistics'; import { useTableFilterContainer, @@ -30,7 +33,8 @@ import { GetSqlManageListV3SortFieldEnum, GetSqlManageListV3SortOrderEnum, exportSqlManageV2FilterPriorityEnum, - exportSqlManageV2FilterStatusEnum + exportSqlManageV2FilterStatusEnum, + exportSqlManageV2ExportFormatEnum } from '@actiontech/shared/lib/api/sqle/service/SqlManage/index.enum'; import SqlManagementColumn, { ExtraFilterMeta, @@ -363,7 +367,15 @@ const SQLEEIndex = () => { exportButtonDisabled, { setFalse: finishExport, setTrue: startExport } ] = useBoolean(false); + const { + exportFormatModalVisible, + showExportFormatModal, + hideExportFormatModal, + selectedExportFormat, + setSelectedExportFormat + } = useExportFormatModal(GetAuditPlanSQLExportReqV1ExportFormatEnum.csv); const handleExport = () => { + hideExportFormatModal(); startExport(); const hideLoading = messageApi.loading( t('sqlManagement.pageHeader.action.exporting') @@ -384,7 +396,9 @@ const SQLEEIndex = () => { filter_db_type: filter_rule_name?.split(DB_TYPE_RULE_NAME_SEPARATOR)?.[0], filter_rule_name: filter_rule_name?.split( DB_TYPE_RULE_NAME_SEPARATOR - )?.[1] + )?.[1], + export_format: + selectedExportFormat as unknown as exportSqlManageV2ExportFormatEnum } as IExportSqlManageV2Params; SqleApi.SqlManageService.exportSqlManageV2(params, { responseType: 'blob' @@ -481,7 +495,7 @@ const SQLEEIndex = () => { title={t('sqlManagement.pageTitle')} extra={ } disabled={exportButtonDisabled} > @@ -489,6 +503,13 @@ const SQLEEIndex = () => { } /> + {/* page */} {/* page - total */} = ({ }; }, [refreshFilterMetaList, refreshTableRows]); useEffect(() => { - const exportScanTypeSqlDetail = () => { + const exportScanTypeSqlDetail = ( + exportFormat?: GetAuditPlanSQLExportReqV1ExportFormatEnum + ) => { exportPending(); const hideLoading = messageApi.loading( t('managementConf.detail.exportTips'), @@ -230,7 +233,8 @@ const ScanTypeSqlCollection: React.FC = ({ project_name: projectName, instance_audit_plan_id: instanceAuditPlanId ?? '', audit_plan_id: auditPlanId, - filter_list: getFilterListByTableFilterInfo() + filter_list: getFilterListByTableFilterInfo(), + export_format: exportFormat }; createSortParams(params); instance_audit_plan 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 0b7db6d7cd..e7fce974a1 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 @@ -1304,3 +1304,1067 @@ exports[`test SqlManagementConf/Detail/index.tsx should match snapshot 2`] = `
`; + +exports[`test SqlManagementConf/Detail/index.tsx should render extra action buttons in the page header and export with CSV format 1`] = ` + +
+
+
+ mysql-1 智能扫描详情 +
+ +
+
+
+
+
+ + + + +
+
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 智能扫描类型 + + 审核规则模板 + + 任务状态 + + 连接信息 + + 采集到的SQL数 + + 审核有问题的SQL数 + + 最近一次采集时间 +
+ + 库表元数据 + + + + default_MySQL + + +
+ + + + + 运行中 + +
+
+ - + + 0 + + 0 + + 2024-08-06 11:30:43 +
+ + 慢日志 + + + + mysql_rule_template + + +
+ + + + + + 停用 + +
+
+ +
+
+ + + + + +
+
+ +
+ + + +
+
+
+
+ 0 + + 0 + + - +
+ + processlist 列表 + + + + default_MySQL + + +
+ + + + + 运行中 + +
+
+ - + + 0 + + 0 + + - +
+ + 自定义 + + + + default_MySQL + + +
+ + + + + 运行中 + +
+
+ - + + 0 + + 0 + + - +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+ + + + + + +
+
+
+
+ + + + + + + + + + +
+
+
+ + + + + + + + + +
+
+ 暂无数据 +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +`; diff --git a/packages/sqle/src/page/SqlManagementConf/Detail/__tests__/index.test.tsx b/packages/sqle/src/page/SqlManagementConf/Detail/__tests__/index.test.tsx index 4202b64a8d..a3b1354f2e 100644 --- a/packages/sqle/src/page/SqlManagementConf/Detail/__tests__/index.test.tsx +++ b/packages/sqle/src/page/SqlManagementConf/Detail/__tests__/index.test.tsx @@ -85,16 +85,15 @@ describe('test SqlManagementConf/Detail/index.tsx', () => { expect(container).toMatchSnapshot(); }); - it('should render extra action buttons in the page header', async () => { + it('should render extra action buttons in the page header and export with CSV format', async () => { mockUsePermission( { checkActionPermission: jest.fn(() => true) }, { useSpyOnMockHooks: true } ); const getInstanceAuditPlanSQLExportSpy = instanceAuditPlan.getInstanceAuditPlanSQLExport(); - const { getByText, queryByText, getAllByText } = sqleSuperRender( - - ); + const { getByText, queryByText, getAllByText, baseElement } = + sqleSuperRender(); await act(async () => jest.advanceTimersByTime(3000)); expect(queryByText('导出')).not.toBeInTheDocument(); @@ -106,6 +105,15 @@ describe('test SqlManagementConf/Detail/index.tsx', () => { fireEvent.click(getByText('导 出')); await act(async () => jest.advanceTimersByTime(0)); + + expect(getByText('选择导出文件格式')).toBeInTheDocument(); + expect(getByText('CSV')).toBeInTheDocument(); + expect(getByText('Excel')).toBeInTheDocument(); + expect(baseElement).toMatchSnapshot(); + + fireEvent.click(getByText('确 认')); + await act(async () => jest.advanceTimersByTime(0)); + expect(getInstanceAuditPlanSQLExportSpy).toHaveBeenCalledTimes(1); expect(getInstanceAuditPlanSQLExportSpy).toHaveBeenNthCalledWith( 1, @@ -114,7 +122,8 @@ describe('test SqlManagementConf/Detail/index.tsx', () => { instance_audit_plan_id: instanceAuditPlanId, audit_plan_id: mockAuditPlanDetailData?.audit_plans?.[0]?.audit_plan_type?.audit_plan_id?.toString(), - filter_list: [] + filter_list: [], + export_format: 'csv' }, { responseType: 'blob' } ); diff --git a/packages/sqle/src/page/SqlManagementConf/Detail/index.tsx b/packages/sqle/src/page/SqlManagementConf/Detail/index.tsx index 5387f2c3b1..83899a6b97 100644 --- a/packages/sqle/src/page/SqlManagementConf/Detail/index.tsx +++ b/packages/sqle/src/page/SqlManagementConf/Detail/index.tsx @@ -29,6 +29,9 @@ import { ResponseCode } from '@actiontech/dms-kit'; import { SqlManagementConfDetailPageHeaderActions } from './action'; import { ROUTE_PATHS } from '@actiontech/dms-kit'; import useScanTypeVerify from '../Common/ConfForm/useScanTypeVerify'; +import { GetAuditPlanSQLExportReqV1ExportFormatEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { useExportFormatModal } from '../../../hooks/useExportFormatModal'; +import ExportFormatModal from '../../../components/ExportFormatModal'; const ConfDetail: React.FC = () => { const { t } = useTranslation(); const { projectID } = useCurrentProject(); @@ -50,6 +53,13 @@ const ConfDetail: React.FC = () => { useBoolean(); const [messageApi, contextMessageHolder] = message.useMessage(); const { isPerformanceCollectScanType } = useScanTypeVerify(); + const { + exportFormatModalVisible, + showExportFormatModal, + hideExportFormatModal, + selectedExportFormat, + setSelectedExportFormat + } = useExportFormatModal(GetAuditPlanSQLExportReqV1ExportFormatEnum.csv); const { data, error, @@ -135,8 +145,12 @@ const ConfDetail: React.FC = () => { eventEmitter.emit(EmitterKey.Refresh_Sql_Management_Conf_Detail_Sql_List); } }; - const exportScanTypeSqlDetail = () => { - eventEmitter.emit(EmitterKey.Export_Sql_Management_Conf_Detail_Sql_List); + const handleExportFormatConfirm = () => { + hideExportFormatModal(); + eventEmitter.emit( + EmitterKey.Export_Sql_Management_Conf_Detail_Sql_List, + selectedExportFormat + ); }; const onAuditImmediately = () => { auditPending(); @@ -162,7 +176,7 @@ const ConfDetail: React.FC = () => { const pageHeaderActions = SqlManagementConfDetailPageHeaderActions({ onAuditImmediately, auditPending: auditing, - onExport: exportScanTypeSqlDetail, + onExport: showExportFormatModal, exportPending: exporting }); return ( @@ -200,6 +214,13 @@ const ConfDetail: React.FC = () => { } /> )} + ); };