diff --git a/packages/base/src/hooks/useSqlReviewTemplateToggle/index.test.tsx b/packages/base/src/hooks/useSqlReviewTemplateToggle/index.test.tsx
deleted file mode 100644
index 5e5da7424..000000000
--- a/packages/base/src/hooks/useSqlReviewTemplateToggle/index.test.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import { act, renderHook } from '@testing-library/react-hooks';
-import useSqlReviewTemplateToggle from '.';
-import { Form } from 'antd';
-
-jest.mock('antd', () => {
- const actualAntd = jest.requireActual('antd');
- return {
- ...actualAntd,
- Form: {
- ...actualAntd.Form,
- useForm: jest.fn(),
- useWatch: jest.fn()
- }
- };
-});
-
-describe('test base/hooks/useSqlReviewTemplateToggle', () => {
- const mockSetFieldsForm = jest.fn();
-
- const customRenderHook = () => {
- const mockedForm = {
- setFieldsValue: mockSetFieldsForm
- };
- (Form.useForm as jest.Mock).mockReturnValue([mockedForm]);
- (Form.useWatch as jest.Mock).mockReturnValue(false);
-
- return renderHook(() => useSqlReviewTemplateToggle(mockedForm as any));
- };
-
- afterEach(() => {
- jest.clearAllMocks();
- jest.clearAllTimers();
- });
-
- it('match default value', async () => {
- const { result } = customRenderHook();
- expect(result.current.auditRequired).toBeFalsy();
- expect(result.current.auditRequiredPopupVisible).toBeFalsy();
- });
-
- it('execute changeAuditRequired', async () => {
- const { result } = customRenderHook();
-
- await act(() => {
- result.current.changeAuditRequired(false);
- });
- expect(mockSetFieldsForm).not.toHaveBeenCalled();
-
- await act(() => {
- result.current.changeAuditRequired(true);
- });
-
- expect(mockSetFieldsForm).toHaveBeenCalledTimes(1);
- expect(mockSetFieldsForm).toHaveBeenCalledWith({
- needSqlAuditService: true
- });
- });
-
- it('execute clearRuleTemplate', async () => {
- const { result } = customRenderHook();
-
- await act(() => {
- result.current.clearRuleTemplate();
- });
- expect(mockSetFieldsForm).toHaveBeenCalledTimes(1);
-
- expect(mockSetFieldsForm).toHaveBeenCalledWith({
- needSqlAuditService: false,
- ruleTemplateId: undefined,
- ruleTemplateName: undefined
- });
- });
-
- it('execute onAuditRequiredPopupOpenChange', async () => {
- const { result, rerender } = customRenderHook();
-
- await act(() => {
- result.current.onAuditRequiredPopupOpenChange(true);
- });
- expect(result.current.auditRequiredPopupVisible).toBeFalsy();
-
- (Form.useWatch as jest.Mock).mockReturnValue(true);
-
- rerender();
-
- await act(() => {
- result.current.onAuditRequiredPopupOpenChange(true);
- });
- expect(result.current.auditRequiredPopupVisible).toBeTruthy();
- });
-});
diff --git a/packages/base/src/hooks/useSqlReviewTemplateToggle/index.tsx b/packages/base/src/hooks/useSqlReviewTemplateToggle/index.tsx
deleted file mode 100644
index d0245fc0b..000000000
--- a/packages/base/src/hooks/useSqlReviewTemplateToggle/index.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import { Form, FormInstance } from 'antd';
-import { useState } from 'react';
-
-const useSqlReviewTemplateToggle = <
- T extends FormInstance<{
- needSqlAuditService?: boolean;
- ruleTemplateId?: string;
- ruleTemplateName?: string;
- }>
->(
- form: T
-) => {
- const auditRequired = Form.useWatch('needSqlAuditService', form);
- const [auditRequiredPopupVisible, setAuditRequiredPopupVisible] =
- useState(false);
-
- const onAuditRequiredPopupOpenChange = (open: boolean) => {
- if (!auditRequired) {
- return;
- }
- setAuditRequiredPopupVisible(open);
- };
- const clearRuleTemplate = () => {
- form.setFieldsValue({
- needSqlAuditService: false,
- ruleTemplateId: undefined,
- ruleTemplateName: undefined
- });
- };
-
- const changeAuditRequired = (check: boolean) => {
- if (check) {
- form.setFieldsValue({
- needSqlAuditService: check
- });
- }
- };
-
- return {
- auditRequired,
- auditRequiredPopupVisible,
- onAuditRequiredPopupOpenChange,
- clearRuleTemplate,
- changeAuditRequired
- };
-};
-
-export default useSqlReviewTemplateToggle;
diff --git a/packages/base/src/locale/zh-CN/dmsDataSource.ts b/packages/base/src/locale/zh-CN/dmsDataSource.ts
index d57451c16..da8133ce4 100644
--- a/packages/base/src/locale/zh-CN/dmsDataSource.ts
+++ b/packages/base/src/locale/zh-CN/dmsDataSource.ts
@@ -45,6 +45,8 @@ export default {
dataSourceForm: {
baseConfig: '基础配置',
sqlConfig: 'SQL审核配置',
+ sqlConfigTips:
+ '管理不同业务场景下SQL执行所需遵循的审核规则,实现精细化管控',
name: '数据源名称',
describe: '数据源描述',
type: '数据源类型',
@@ -62,17 +64,26 @@ export default {
deleteEnvironmentAttributeSuccess: '环境属性删除成功',
addEnvironmentAttributeSuccess: '环境属性添加成功',
deleteEnvironmentAttributeError: '当前环境已绑定:{{name}},暂无法删除',
- ruleTemplate: '审核规则模板',
+ ruleTemplate: 'SQL上线审核规则模板',
+ ruleTemplateTips: '此功能强制开启审核,请为上线流程选择规则模板',
workflow: '应用的工作流',
maxPreQueryRows: 'SQL查询返回条数',
queryTimeoutSecond: 'SQL超时限制(s)',
maintenanceTime: '运维时间',
maintenanceTimeTips: '设置运维时间后,仅能在此运维时间段内上线工单',
needAuditSqlService: '是否开启SQL审核业务',
+ needAuditSqlServiceTips: '关闭后将禁用所用场景的SQL审核',
closeAuditSqlServiceTips:
'如果不启用SQL审核业务,则在SQL审核相关业务中无法使用该数据源,是否确认关闭?',
- needAuditForSqlQuery: 'SQL工作台查询是否需要审核',
+ needAuditForSqlQuery: '工作台查询审核',
+ needAuditForSqlQueryTips: '用于SQL工作台实时查询,可按需启用',
+ workbenchAuditRuleTemplate: '工作台查询审核规则模板',
allowQueryWhenLessThanAuditLevel: '自动放行的最高审核等级',
+ allowQueryWhenLessThanAuditLevelTips:
+ '低于或等于此等级的审核结果将自动放行',
+ dataExportAuditRuleTemplate: '数据导出审核规则模板',
+ dataExportAuditRuleTemplateTips:
+ '此功能强制开启审核,请为数据导出选择规则模板',
passwordTips:
'这里不会显示您已经配置的当前数据源密码,提交时如果您没有填写密码,那么将不会对数据源密码进行变更。',
needUpdatePassword: '是否更新密码',
diff --git a/packages/base/src/page/DataSource/components/AddDataSource/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataSource/components/AddDataSource/__snapshots__/index.test.tsx.snap
index 22e815c13..55f8d070e 100644
--- a/packages/base/src/page/DataSource/components/AddDataSource/__snapshots__/index.test.tsx.snap
+++ b/packages/base/src/page/DataSource/components/AddDataSource/__snapshots__/index.test.tsx.snap
@@ -740,13 +740,31 @@ exports[`page/DataSource/AddDataSource render add database snap 1`] = `
-
- SQL审核配置
-
+
+
+ SQL审核配置
+
+
+
+
+ 管理不同业务场景下SQL执行所需遵循的审核规则,实现精细化管控
+
+
+
+
@@ -1995,91 +2063,31 @@ exports[`page/DataSource/AddDataSource render conenctable modal when current ser
-
-
-
- default_MySQL1
-
-
- custom_template_b
-
-
+
+
-
+
-
+ aria-label="exclamation-circle"
+ class="anticon anticon-exclamation-circle"
+ role="img"
+ >
+
+
+
- custom_template_b
+ 如果不启用SQL审核业务,则在SQL审核相关业务中无法使用该数据源,是否确认关闭?
-
+
+
+
+
diff --git a/packages/base/src/page/DataSource/components/AddDataSource/index.test.tsx b/packages/base/src/page/DataSource/components/AddDataSource/index.test.tsx
index 849cbdba4..ab4896830 100644
--- a/packages/base/src/page/DataSource/components/AddDataSource/index.test.tsx
+++ b/packages/base/src/page/DataSource/components/AddDataSource/index.test.tsx
@@ -8,7 +8,8 @@ import {
mockUseCurrentProject,
mockProjectInfo,
getAllBySelector,
- getBySelector
+ getBySelector,
+ selectOptionByIndex
} from '@actiontech/shared/lib/testUtil';
import EmitterKey from '../../../../data/EmitterKey';
import EventEmitter from '../../../../utils/EventEmitter';
@@ -136,6 +137,30 @@ describe('page/DataSource/AddDataSource', () => {
getBySelector('div[title="custom_template_b"]', baseElement)
);
await act(async () => jest.advanceTimersByTime(300));
+ // dataExportRuleTemplateName
+ fireEvent.mouseDown(
+ getBySelector('#dataExportRuleTemplateName', baseElement)
+ );
+ await act(async () => jest.advanceTimersByTime(300));
+ fireEvent.click(getAllBySelector('div[title="default_MySQL1"]')[1]);
+ await act(async () => jest.advanceTimersByTime(300));
+ // needAuditForSqlQuery
+ fireEvent.click(getBySelector('#needAuditForSqlQuery', baseElement));
+ await act(async () => jest.advanceTimersByTime(0));
+
+ // workbenchTemplateName
+ fireEvent.mouseDown(getBySelector('#workbenchTemplateName', baseElement));
+ await act(async () => jest.advanceTimersByTime(0));
+ fireEvent.click(getAllBySelector('div[title="default_MySQL1"]')[2]);
+ await act(async () => jest.advanceTimersByTime(0));
+ // allowQueryWhenLessThanAuditLevel
+ fireEvent.mouseDown(
+ getBySelector('#allowQueryWhenLessThanAuditLevel', baseElement)
+ );
+ await act(async () => jest.advanceTimersByTime(0));
+ fireEvent.click(getBySelector('div[title="warn"]', baseElement));
+ await act(async () => jest.advanceTimersByTime(0));
+
// submit
await act(async () => {
fireEvent.click(screen.getByText('提 交'));
@@ -162,11 +187,16 @@ describe('page/DataSource/AddDataSource', () => {
password: 'root',
port: '3306',
sqle_config: {
+ audit_enabled: true,
rule_template_id: '2',
rule_template_name: 'custom_template_b',
+ data_export_rule_template_id: '3',
+ data_export_rule_template_name: 'default_MySQL1',
sql_query_config: {
- allow_query_when_less_than_audit_level: undefined,
- audit_enabled: undefined
+ allow_query_when_less_than_audit_level: 'warn',
+ audit_enabled: true,
+ rule_template_id: '3',
+ rule_template_name: 'default_MySQL1'
}
},
user: 'root'
@@ -246,13 +276,16 @@ describe('page/DataSource/AddDataSource', () => {
fireEvent.click(firstOption);
await act(async () => jest.advanceTimersByTime(0));
- // ruleTemplateName
- fireEvent.mouseDown(getBySelector('#ruleTemplateName', baseElement));
- await act(async () => jest.advanceTimersByTime(300));
- fireEvent.click(
- getBySelector('div[title="custom_template_b"]', baseElement)
- );
- await act(async () => jest.advanceTimersByTime(300));
+ fireEvent.click(getBySelector('.audit-confirm-switch'));
+ await act(async () => jest.advanceTimersByTime(0));
+ expect(
+ screen.getByText(
+ '如果不启用SQL审核业务,则在SQL审核相关业务中无法使用该数据源,是否确认关闭?'
+ )
+ ).toBeInTheDocument();
+ fireEvent.click(screen.getByText('确 定'));
+ await act(async () => jest.advanceTimersByTime(0));
+ expect(getBySelector('.audit-confirm-switch')).not.toBeChecked();
// submit
await act(async () => {
fireEvent.click(screen.getByText('提 交'));
@@ -332,6 +365,13 @@ describe('page/DataSource/AddDataSource', () => {
getBySelector('div[title="custom_template_b"]', baseElement)
);
await act(async () => jest.advanceTimersByTime(300));
+ // dataExportRuleTemplateName
+ fireEvent.mouseDown(
+ getBySelector('#dataExportRuleTemplateName', baseElement)
+ );
+ await act(async () => jest.advanceTimersByTime(300));
+ fireEvent.click(getAllBySelector('div[title="default_MySQL1"]')[1]);
+ await act(async () => jest.advanceTimersByTime(0));
fireEvent.click(getBySelector('#enableBackup'));
await act(async () => jest.advanceTimersByTime(300));
@@ -372,8 +412,11 @@ describe('page/DataSource/AddDataSource', () => {
password: 'root',
port: '3306',
sqle_config: {
+ audit_enabled: true,
rule_template_id: '2',
rule_template_name: 'custom_template_b',
+ data_export_rule_template_id: '3',
+ data_export_rule_template_name: 'default_MySQL1',
sql_query_config: {
allow_query_when_less_than_audit_level: undefined,
audit_enabled: undefined
diff --git a/packages/base/src/page/DataSource/components/AddDataSource/index.tsx b/packages/base/src/page/DataSource/components/AddDataSource/index.tsx
index d77c168dc..f56c6b477 100644
--- a/packages/base/src/page/DataSource/components/AddDataSource/index.tsx
+++ b/packages/base/src/page/DataSource/components/AddDataSource/index.tsx
@@ -55,24 +55,33 @@ const AddDataSource = () => {
})) ?? [],
// #if [sqle]
sqle_config: {
+ audit_enabled: values.needSqlAuditService,
rule_template_id: values.ruleTemplateId,
rule_template_name: values.ruleTemplateName,
sql_query_config: {
allow_query_when_less_than_audit_level:
values.allowQueryWhenLessThanAuditLevel,
- audit_enabled: values.needAuditForSqlQuery
+ audit_enabled: values.needAuditForSqlQuery,
+ rule_template_id: values.workbenchTemplateId,
+ rule_template_name: values.workbenchTemplateName
}
},
// #endif
additional_params: values.asyncParams,
// #if [dms]
- is_enable_masking: values.is_enable_masking,
- // #endif
- // #if [sqle && ee]
- enable_backup: values.enableBackup,
- backup_max_rows: values.backupMaxRows
+ is_enable_masking: values.is_enable_masking
// #endif
};
+ // #if [sqle && ee]
+ if (dbService.sqle_config) {
+ dbService.sqle_config.data_export_rule_template_id =
+ values.dataExportRuleTemplateId;
+ dbService.sqle_config.data_export_rule_template_name =
+ values.dataExportRuleTemplateName;
+ }
+ dbService.enable_backup = values.enableBackup;
+ dbService.backup_max_rows = values.backupMaxRows;
+ // #endif
return DmsApi.DBServiceService.AddDBServiceV2({
db_service: dbService,
project_uid: values.project
diff --git a/packages/base/src/page/DataSource/components/Form/SqlAuditFields/ConfirmSwitch.tsx b/packages/base/src/page/DataSource/components/Form/SqlAuditFields/ConfirmSwitch.tsx
new file mode 100644
index 000000000..5be69f79e
--- /dev/null
+++ b/packages/base/src/page/DataSource/components/Form/SqlAuditFields/ConfirmSwitch.tsx
@@ -0,0 +1,57 @@
+import { BasicSwitch } from '@actiontech/shared';
+import { Popconfirm } from 'antd';
+import { useTranslation } from 'react-i18next';
+import { useState } from 'react';
+
+type ConfirmSwitchProps = {
+ checked?: boolean;
+ onChange?: (value: boolean) => void;
+ onConfirm?: () => void;
+};
+
+const ConfirmSwitch: React.FC
= ({
+ checked,
+ onChange,
+ onConfirm
+}) => {
+ const { t } = useTranslation();
+
+ const [auditRequiredPopupVisible, setAuditRequiredPopupVisible] =
+ useState(false);
+
+ const onOpenChange = (open: boolean) => {
+ if (!checked) {
+ return;
+ }
+ setAuditRequiredPopupVisible(open);
+ };
+
+ const onSwitchChange = (value: boolean) => {
+ if (value) {
+ onChange?.(value);
+ }
+ };
+
+ const onInnerConfirm = () => {
+ onChange?.(false);
+ onConfirm?.();
+ };
+
+ return (
+
+
+
+ );
+};
+
+export default ConfirmSwitch;
diff --git a/packages/base/src/page/DataSource/components/Form/SqlAuditFields/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataSource/components/Form/SqlAuditFields/__tests__/__snapshots__/index.test.tsx.snap
new file mode 100644
index 000000000..8c5c1a9ef
--- /dev/null
+++ b/packages/base/src/page/DataSource/components/Form/SqlAuditFields/__tests__/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,1174 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`SqlAuditFields should match snapshot when needSqlAuditService and needAuditForSqlQuery are both true 1`] = `
+
+`;
+
+exports[`SqlAuditFields should match snapshot when needSqlAuditService is false 1`] = `
+
+`;
+
+exports[`SqlAuditFields should match snapshot when needSqlAuditService is true 1`] = `
+
+`;
diff --git a/packages/base/src/page/DataSource/components/Form/SqlAuditFields/__tests__/index.test.tsx b/packages/base/src/page/DataSource/components/Form/SqlAuditFields/__tests__/index.test.tsx
new file mode 100644
index 000000000..2f628ad3b
--- /dev/null
+++ b/packages/base/src/page/DataSource/components/Form/SqlAuditFields/__tests__/index.test.tsx
@@ -0,0 +1,68 @@
+import { cleanup } from '@testing-library/react';
+import { Form } from 'antd';
+import { superRenderHook } from '@actiontech/shared/lib/testUtil/superRender';
+import { baseSuperRender } from '../../../../../../testUtils/superRender';
+import SqlAuditFields from '..';
+
+describe('SqlAuditFields', () => {
+ const mockOnNeedAuditForSqlQueryChange = jest.fn();
+ const mockRuleTemplateOptions = [
+ {
+ label: 'MySQL规则模板',
+ value: 'mysql_template',
+ key: '1'
+ },
+ {
+ label: 'PostgreSQL规则模板',
+ value: 'postgres_template',
+ key: '2'
+ }
+ ];
+
+ const customRender = (initialValues = {}) => {
+ const { result } = superRenderHook(() => Form.useForm());
+ const [form] = result.current;
+
+ return baseSuperRender(
+
+ );
+ };
+
+ beforeEach(() => {
+ jest.useFakeTimers();
+ });
+
+ afterEach(() => {
+ jest.useRealTimers();
+ jest.clearAllMocks();
+ cleanup();
+ });
+
+ it('should match snapshot when needSqlAuditService is false', () => {
+ const { container } = customRender({
+ needSqlAuditService: false
+ });
+ expect(container).toMatchSnapshot();
+ });
+
+ it('should match snapshot when needSqlAuditService is true', () => {
+ const { container } = customRender({
+ needSqlAuditService: true
+ });
+ expect(container).toMatchSnapshot();
+ });
+
+ it('should match snapshot when needSqlAuditService and needAuditForSqlQuery are both true', () => {
+ const { container } = customRender({
+ needSqlAuditService: true,
+ needAuditForSqlQuery: true
+ });
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/packages/base/src/page/DataSource/components/Form/SqlAuditFields/index.tsx b/packages/base/src/page/DataSource/components/Form/SqlAuditFields/index.tsx
new file mode 100644
index 000000000..f5dd27604
--- /dev/null
+++ b/packages/base/src/page/DataSource/components/Form/SqlAuditFields/index.tsx
@@ -0,0 +1,248 @@
+import { useTranslation } from 'react-i18next';
+import { Form, Typography } from 'antd';
+import {
+ BasicInput,
+ BasicSelect,
+ BasicSwitch,
+ EmptyBox
+} from '@actiontech/shared';
+import { FormAreaBlockStyleWrapper } from '@actiontech/shared/lib/components/CustomForm/style';
+import {
+ FormItemLabel,
+ FormItemSubTitle,
+ CustomLabelContent
+} from '@actiontech/shared/lib/components/CustomForm';
+import Select, { SelectProps, BaseOptionType } from 'antd/es/select';
+import { SQLQueryConfigAllowQueryWhenLessThanAuditLevelEnum } from '@actiontech/shared/lib/api/base/service/common.enum';
+import { FaLessThanEqualOutlined } from '@actiontech/icons';
+import ConfirmSwitch from './ConfirmSwitch';
+import { SqlAuditFieldsSubTitleWrapper } from '../style';
+
+type SqlAuditFieldsValue = {
+ needSqlAuditService: boolean;
+ ruleTemplateId: string;
+ ruleTemplateName: string;
+ dataExportRuleTemplateId: string;
+ dataExportRuleTemplateName: string;
+ needAuditForSqlQuery: boolean;
+ workbenchTemplateId: string;
+ workbenchTemplateName: string;
+ allowQueryWhenLessThanAuditLevel: string;
+};
+
+type SqlAuditFieldsProps = {
+ getTemplateOptionsLoading: boolean;
+ ruleTemplateOptions: SelectProps['options'];
+ onNeedAuditForSqlQueryChange: (value: boolean) => void;
+};
+
+const SqlAuditFields: React.FC = ({
+ getTemplateOptionsLoading,
+ ruleTemplateOptions,
+ onNeedAuditForSqlQueryChange
+}) => {
+ const { t } = useTranslation();
+
+ const form = Form.useFormInstance();
+
+ const needSqlAuditService = Form.useWatch('needSqlAuditService');
+
+ const needAuditForSqlQuery = Form.useWatch('needAuditForSqlQuery');
+
+ const changeRuleTemplate = (
+ value: string,
+ option: BaseOptionType,
+ key: keyof SqlAuditFieldsValue
+ ) => {
+ form.setFieldsValue({
+ [key]: option.key
+ });
+ };
+
+ return (
+
+
+
+ {t('dmsDataSource.dataSourceForm.sqlConfig')}
+
+
+ {t('dmsDataSource.dataSourceForm.sqlConfigTips')}
+
+
+
+ }
+ name="needSqlAuditService"
+ valuePropName="checked"
+ >
+
+
+
+
+
+
+
+ }
+ name="ruleTemplateName"
+ className="has-required-style has-label-tip"
+ rules={[
+ {
+ required: true,
+ message: t('common.form.placeholder.select', {
+ name: t('dmsDataSource.dataSourceForm.ruleTemplate')
+ })
+ }
+ ]}
+ >
+
+ changeRuleTemplate(value, option, 'ruleTemplateId')
+ }
+ options={ruleTemplateOptions}
+ />
+
+ {/* #if [ee] */}
+
+
+
+
+ }
+ name="dataExportRuleTemplateName"
+ className="has-required-style has-label-tip"
+ rules={[
+ {
+ required: true,
+ message: t('common.form.placeholder.select', {
+ name: t(
+ 'dmsDataSource.dataSourceForm.dataExportAuditRuleTemplate'
+ )
+ })
+ }
+ ]}
+ >
+
+ changeRuleTemplate(value, option, 'dataExportRuleTemplateId')
+ }
+ options={ruleTemplateOptions}
+ />
+
+ {/* #endif */}
+
+ }
+ name="needAuditForSqlQuery"
+ valuePropName="checked"
+ className="has-label-tip"
+ >
+
+
+
+
+
+
+
+
+ changeRuleTemplate(value, option, 'workbenchTemplateId')
+ }
+ options={ruleTemplateOptions}
+ />
+
+
+ }
+ name="allowQueryWhenLessThanAuditLevel"
+ rules={[
+ {
+ required: true,
+ message: t('common.form.placeholder.select', {
+ name: t(
+ 'dmsDataSource.dataSourceForm.allowQueryWhenLessThanAuditLevel'
+ )
+ })
+ }
+ ]}
+ className="has-required-style has-label-tip"
+ >
+ }>
+ {Object.values(
+ SQLQueryConfigAllowQueryWhenLessThanAuditLevelEnum
+ ).map((v) => {
+ return (
+
+ {v}
+
+ );
+ })}
+
+
+
+
+
+ );
+};
+
+export default SqlAuditFields;
diff --git a/packages/base/src/page/DataSource/components/Form/__snapshots__/index.ce.test.tsx.snap b/packages/base/src/page/DataSource/components/Form/__snapshots__/index.ce.test.tsx.snap
index 3282283c9..38a7eb41c 100644
--- a/packages/base/src/page/DataSource/components/Form/__snapshots__/index.ce.test.tsx.snap
+++ b/packages/base/src/page/DataSource/components/Form/__snapshots__/index.ce.test.tsx.snap
@@ -343,7 +343,7 @@ exports[`page/DataSource/DataSourceForm CE render business field when getProject
@@ -538,7 +538,7 @@ exports[`page/DataSource/DataSourceForm CE render business field when getProject
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SQL审核配置
-
@@ -6203,7 +4018,7 @@ exports[`page/DataSource/DataSourceForm render change switch when page is update
@@ -6312,7 +4108,7 @@ exports[`page/DataSource/DataSourceForm render change switch when page is update
-
-
-
@@ -7036,7 +4822,7 @@ exports[`page/DataSource/DataSourceForm render database type 1`] = `
@@ -7182,6 +4968,54 @@ exports[`page/DataSource/DataSourceForm render database type 1`] = `
+
@@ -7231,7 +5065,7 @@ exports[`page/DataSource/DataSourceForm render database type 1`] = `
@@ -7789,7 +5693,7 @@ exports[`page/DataSource/DataSourceForm render database type 1`] = `
数据脱敏配置
@@ -8977,7 +6951,7 @@ exports[`page/DataSource/DataSourceForm render name rule 1`] = `
数据脱敏配置
@@ -10098,7 +8142,7 @@ exports[`page/DataSource/DataSourceForm render name rule 2`] = `
数据脱敏配置
@@ -11260,7 +9374,7 @@ exports[`page/DataSource/DataSourceForm render update form snap 1`] = `
数据脱敏配置
@@ -2306,13 +2374,31 @@ exports[`page/DataSource/UpdateDataSource render prepare api 1`] = `
-
- SQL审核配置
-
+
+
+ SQL审核配置
+
+
+
+
+ 管理不同业务场景下SQL执行所需遵循的审核规则,实现精细化管控
+
+
+
+
+
+
+
+
+
diff --git a/packages/base/src/page/DataSource/components/UpdateDataSource/index.test.tsx b/packages/base/src/page/DataSource/components/UpdateDataSource/index.test.tsx
index 672144164..2c5650c1f 100644
--- a/packages/base/src/page/DataSource/components/UpdateDataSource/index.test.tsx
+++ b/packages/base/src/page/DataSource/components/UpdateDataSource/index.test.tsx
@@ -96,12 +96,18 @@ describe('page/DataSource/UpdateDataSource', () => {
source: 'SQLE',
project_uid: '700300',
sqle_config: {
+ audit_enabled: true,
rule_template_name: 'default_MySQL',
rule_template_id: '1',
+ data_export_rule_template_id: '3',
+ data_export_rule_template_name: 'default_MySQL1',
sql_query_config: {
max_pre_query_rows: 0,
query_timeout_second: 0,
- audit_enabled: false
+ audit_enabled: true,
+ rule_template_name: 'default_MySQL',
+ rule_template_id: '1',
+ allow_query_when_less_than_audit_level: 'warn'
}
},
additional_params: [
@@ -178,6 +184,12 @@ describe('page/DataSource/UpdateDataSource', () => {
fireEvent.click(firstOption);
await act(async () => jest.advanceTimersByTime(0));
+ // close needAuditForSqlQuery
+ expect(getBySelector('#needAuditForSqlQuery')).toBeChecked();
+ fireEvent.click(getBySelector('#needAuditForSqlQuery', baseElement));
+ await act(async () => jest.advanceTimersByTime(0));
+ expect(getBySelector('#needAuditForSqlQuery')).not.toBeChecked();
+
await act(async () => {
fireEvent.click(screen.getByText('提 交'));
await act(async () => jest.advanceTimersByTime(300));
diff --git a/packages/base/src/page/DataSource/components/UpdateDataSource/index.tsx b/packages/base/src/page/DataSource/components/UpdateDataSource/index.tsx
index c5b6fea12..b622b5a4e 100644
--- a/packages/base/src/page/DataSource/components/UpdateDataSource/index.tsx
+++ b/packages/base/src/page/DataSource/components/UpdateDataSource/index.tsx
@@ -65,28 +65,40 @@ const UpdateDataSource = () => {
port: `${values.port}`,
// #if [sqle]
sqle_config: {
+ audit_enabled: values.needSqlAuditService,
rule_template_id: values.ruleTemplateId,
rule_template_name: values.ruleTemplateName,
sql_query_config: {
allow_query_when_less_than_audit_level:
values.allowQueryWhenLessThanAuditLevel,
- audit_enabled: values.needAuditForSqlQuery
+ audit_enabled: values.needAuditForSqlQuery,
+ rule_template_id: values.workbenchTemplateId,
+ rule_template_name: values.workbenchTemplateName
}
},
// #endif
additional_params: values.asyncParams,
user: values.user,
// #if [dms]
- is_enable_masking: values.is_enable_masking,
- // #endif
- // #if [sqle && ee]
- enable_backup: values.enableBackup,
- backup_max_rows: values.backupMaxRows
+ is_enable_masking: values.is_enable_masking
// #endif
},
project_uid: projectID
};
+ // #if [sqle && ee]
+ if (params.db_service?.sqle_config) {
+ params.db_service.sqle_config.data_export_rule_template_id =
+ values.dataExportRuleTemplateId;
+ params.db_service.sqle_config.data_export_rule_template_name =
+ values.dataExportRuleTemplateName;
+ }
+ if (params.db_service) {
+ params.db_service.enable_backup = values.enableBackup;
+ params.db_service.backup_max_rows = values.backupMaxRows;
+ }
+ // #endif
+
if (!!values.needUpdatePassword && !!values.password && params.db_service) {
params.db_service.password = values.password;
}
diff --git a/packages/base/src/page/SyncDataSource/AddPage/__snapshots__/index.test.tsx.snap b/packages/base/src/page/SyncDataSource/AddPage/__snapshots__/index.test.tsx.snap
index d3d0cdc57..55faa7dc7 100644
--- a/packages/base/src/page/SyncDataSource/AddPage/__snapshots__/index.test.tsx.snap
+++ b/packages/base/src/page/SyncDataSource/AddPage/__snapshots__/index.test.tsx.snap
@@ -545,13 +545,31 @@ exports[`page/SyncDataSource/AddPage render add submit for success 1`] = `
-
- SQL审核配置
-
+
+
+ SQL审核配置
+
+
+
+
+ 管理不同业务场景下SQL执行所需遵循的审核规则,实现精细化管控
+
+
+
+
+
+
+
+
+
+
+
+ custom_template
+
+
+ custom_template_b
+
+
+
+
+
+
+
+
+ custom_template
+
+
+
+
+
+ custom_template_b
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ custom_template
+
+
+ custom_template_b
+
+
+
+
+
+
+
+
+ custom_template
+
+
+
+
-
- SQL审核配置
-
+
+
+ SQL审核配置
+
+
+
+
+ 管理不同业务场景下SQL执行所需遵循的审核规则,实现精细化管控
+
+
+
@@ -3225,13 +3798,31 @@ exports[`page/SyncDataSource/AddPage render form item for prepare api 1`] = `
-
- SQL审核配置
-
+
+
+ SQL审核配置
+
+
+
+
+ 管理不同业务场景下SQL执行所需遵循的审核规则,实现精细化管控
+
+
+
diff --git a/packages/base/src/page/SyncDataSource/AddPage/index.test.tsx b/packages/base/src/page/SyncDataSource/AddPage/index.test.tsx
index 502ed7a3f..05e7ba7d5 100644
--- a/packages/base/src/page/SyncDataSource/AddPage/index.test.tsx
+++ b/packages/base/src/page/SyncDataSource/AddPage/index.test.tsx
@@ -130,9 +130,23 @@ describe('page/SyncDataSource/AddPage', () => {
getBySelector('div[title="custom_template_b"]', baseElement)
);
+ // dataExportRuleTemplateName
+ fireEvent.mouseDown(
+ getBySelector('#dataExportRuleTemplateName', baseElement)
+ );
+ await act(async () => jest.advanceTimersByTime(300));
+ fireEvent.click(getAllBySelector('div[title="custom_template"]')[1]);
+ await act(async () => jest.advanceTimersByTime(300));
+
// sql query config
fireEvent.click(getBySelector('#needAuditForSqlQuery', baseElement));
+ // workbenchTemplateName
+ fireEvent.mouseDown(getBySelector('#workbenchTemplateName', baseElement));
+ await act(async () => jest.advanceTimersByTime(0));
+ fireEvent.click(getAllBySelector('div[title="custom_template"]')[2]);
+ await act(async () => jest.advanceTimersByTime(0));
+
fireEvent.mouseDown(
getBySelector('#allowQueryWhenLessThanAuditLevel', baseElement)
);
@@ -154,11 +168,16 @@ describe('page/SyncDataSource/AddPage', () => {
db_type: 'mysql',
source: 'source1',
sqle_config: {
+ audit_enabled: true,
rule_template_id: '2',
rule_template_name: 'custom_template_b',
+ data_export_rule_template_id: '9',
+ data_export_rule_template_name: 'custom_template',
sql_query_config: {
audit_enabled: true,
- allow_query_when_less_than_audit_level: 'notice'
+ allow_query_when_less_than_audit_level: 'notice',
+ rule_template_id: '9',
+ rule_template_name: 'custom_template'
}
},
cron_express: '0 0 * * *',
diff --git a/packages/base/src/page/SyncDataSource/AddPage/index.tsx b/packages/base/src/page/SyncDataSource/AddPage/index.tsx
index f9e7fae46..bed15ceb2 100644
--- a/packages/base/src/page/SyncDataSource/AddPage/index.tsx
+++ b/packages/base/src/page/SyncDataSource/AddPage/index.tsx
@@ -53,12 +53,17 @@ const AddSyncTask: React.FC = () => {
source: values.source,
// #if [sqle]
sqle_config: {
+ audit_enabled: values.needSqlAuditService,
rule_template_id: values.ruleTemplateId,
rule_template_name: values.ruleTemplateName,
+ data_export_rule_template_id: values.dataExportRuleTemplateId,
+ data_export_rule_template_name: values.dataExportRuleTemplateName,
sql_query_config: {
audit_enabled: values.needAuditForSqlQuery,
allow_query_when_less_than_audit_level:
- values.allowQueryWhenLessThanAuditLevel
+ values.allowQueryWhenLessThanAuditLevel,
+ rule_template_id: values.workbenchTemplateId,
+ rule_template_name: values.workbenchTemplateName
}
},
// #endif
@@ -70,6 +75,7 @@ const AddSyncTask: React.FC = () => {
)
}
};
+
DBServiceSyncTaskService.AddDBServiceSyncTask(params)
.then((res) => {
if (res.data.code === ResponseCode.SUCCESS) {
diff --git a/packages/base/src/page/SyncDataSource/Form/__snapshots__/index.test.tsx.snap b/packages/base/src/page/SyncDataSource/Form/__snapshots__/index.test.tsx.snap
index 3ca366d6b..b4c2c8786 100644
--- a/packages/base/src/page/SyncDataSource/Form/__snapshots__/index.test.tsx.snap
+++ b/packages/base/src/page/SyncDataSource/Form/__snapshots__/index.test.tsx.snap
@@ -361,13 +361,31 @@ exports[`page/SyncDataSource/SyncTaskForm render for loading form 1`] = `
-
- SQL审核配置
-
+
+
+ SQL审核配置
+
+
+
+
+ 管理不同业务场景下SQL执行所需遵循的审核规则,实现精细化管控
+
+
+
@@ -1144,13 +1209,31 @@ exports[`page/SyncDataSource/SyncTaskForm render name rule 1`] = `
-
- SQL审核配置
-
+
+
+ SQL审核配置
+
+
+
+
+ 管理不同业务场景下SQL执行所需遵循的审核规则,实现精细化管控
+
+
+
+
+
+
+
+
@@ -2697,13 +2892,31 @@ exports[`page/SyncDataSource/SyncTaskForm render syncInterval for form item 1`]
-
- SQL审核配置
-
+
+
+ SQL审核配置
+
+
+
+
+ 管理不同业务场景下SQL执行所需遵循的审核规则,实现精细化管控
+
+
+
+
+
+
diff --git a/packages/base/src/page/SyncDataSource/Form/index.tsx b/packages/base/src/page/SyncDataSource/Form/index.tsx
index 0f23ea99d..dc9568e13 100644
--- a/packages/base/src/page/SyncDataSource/Form/index.tsx
+++ b/packages/base/src/page/SyncDataSource/Form/index.tsx
@@ -1,10 +1,9 @@
import { useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
-import { Alert, Form, Popconfirm, Select, Spin } from 'antd';
+import { Alert, Form, Spin } from 'antd';
import {
BasicInput,
BasicSelect,
- BasicSwitch,
CronInput,
EmptyBox,
TypedLink
@@ -28,12 +27,10 @@ import { nameRule } from '@actiontech/shared/lib/utils/FormRule';
import EmitterKey from '../../../data/EmitterKey';
import EventEmitter from '../../../utils/EventEmitter';
import useGlobalRuleTemplate from 'sqle/src/hooks/useGlobalRuleTemplate';
-import useSqlReviewTemplateToggle from '../../../hooks/useSqlReviewTemplateToggle';
import AutoCreatedFormItemByApi from 'sqle/src/components/BackendForm/AutoCreatedFormItemByApi';
-import { SQLQueryConfigAllowQueryWhenLessThanAuditLevelEnum } from '@actiontech/shared/lib/api/base/service/common.enum';
import useAsyncParams from 'sqle/src/components/BackendForm/useAsyncParams';
import { SyncTaskFormProps } from './index.type';
-import { FaLessThanEqualOutlined } from '@actiontech/icons';
+import SqlAuditFields from '../../DataSource/components/Form/SqlAuditFields';
const SyncTaskForm: React.FC = ({
form,
@@ -45,7 +42,6 @@ const SyncTaskForm: React.FC = ({
const { t } = useTranslation();
const isUpdate = useMemo(() => !!defaultValue, [defaultValue]);
const source = Form.useWatch('source', form);
- const auditEnabled = Form.useWatch('needAuditForSqlQuery', form);
const { generateFormValueByParams } = useAsyncParams();
@@ -60,10 +56,14 @@ const SyncTaskForm: React.FC = ({
const handleChangeInstanceType = (type: string) => {
// #if [sqle]
- form.setFieldsValue({
- ruleTemplateId: undefined,
- ruleTemplateName: undefined
- });
+ form.resetFields([
+ 'ruleTemplateId',
+ 'ruleTemplateName',
+ 'dataExportRuleTemplateId',
+ 'dataExportRuleTemplateName',
+ 'workbenchTemplateId',
+ 'workbenchTemplateName'
+ ]);
updateGlobalRuleTemplateList(type);
// #endif
};
@@ -97,21 +97,13 @@ const SyncTaskForm: React.FC = ({
globalRuleTemplateList
} = useGlobalRuleTemplate();
- const handleChangeRuleTemplate = (templateName: string) => {
- form.setFieldsValue({
- ruleTemplateId: globalRuleTemplateList.find(
- (v) => v.rule_template_name === templateName
- )?.rule_template_id
- });
- };
-
- const {
- auditRequired,
- auditRequiredPopupVisible,
- onAuditRequiredPopupOpenChange,
- clearRuleTemplate,
- changeAuditRequired
- } = useSqlReviewTemplateToggle(form);
+ const templateOptions = useMemo(() => {
+ return globalRuleTemplateList.map((v) => ({
+ key: v.rule_template_id,
+ label: v.rule_template_name,
+ value: v.rule_template_name
+ }));
+ }, [globalRuleTemplateList]);
// #endif
useEffect(() => {
@@ -133,6 +125,11 @@ const SyncTaskForm: React.FC = ({
// #if [sqle]
'ruleTemplateId',
'ruleTemplateName',
+ 'dataExportRuleTemplateId',
+ 'dataExportRuleTemplateName',
+ 'workbenchTemplateId',
+ 'workbenchTemplateName',
+ 'allowQueryWhenLessThanAuditLevel',
// #endif
'syncInterval'
]);
@@ -165,11 +162,19 @@ const SyncTaskForm: React.FC = ({
url: defaultValue.url,
instanceType: defaultValue.db_type,
// #if [sqle]
- needSqlAuditService: !!defaultValue.sqle_config?.rule_template_id,
+ needSqlAuditService: !!defaultValue.sqle_config?.audit_enabled,
ruleTemplateId: defaultValue.sqle_config?.rule_template_id ?? '',
ruleTemplateName: defaultValue.sqle_config?.rule_template_name ?? '',
+ dataExportRuleTemplateId:
+ defaultValue.sqle_config?.data_export_rule_template_id ?? '',
+ dataExportRuleTemplateName:
+ defaultValue.sqle_config?.data_export_rule_template_name ?? '',
needAuditForSqlQuery:
!!defaultValue.sqle_config?.sql_query_config?.audit_enabled,
+ workbenchTemplateId:
+ defaultValue.sqle_config?.sql_query_config?.rule_template_id ?? '',
+ workbenchTemplateName:
+ defaultValue.sqle_config?.sql_query_config?.rule_template_name ?? '',
allowQueryWhenLessThanAuditLevel:
defaultValue.sqle_config?.sql_query_config
?.allow_query_when_less_than_audit_level,
@@ -327,81 +332,11 @@ const SyncTaskForm: React.FC = ({
{/* #if [sqle] */}
-
-
- {t('dmsSyncDataSource.syncTaskForm.sqlConfig')}
-
-
-
-
-
-
-
-
-
-
- ({
- key: v.rule_template_id,
- label: v.rule_template_name,
- value: v.rule_template_name
- }))}
- />
-
-
-
-
-
- }>
- {Object.values(
- SQLQueryConfigAllowQueryWhenLessThanAuditLevelEnum
- ).map((v) => {
- return (
-
- {v}
-
- );
- })}
-
-
-
+
{/* #endif */}
diff --git a/packages/base/src/page/SyncDataSource/Form/index.type.ts b/packages/base/src/page/SyncDataSource/Form/index.type.ts
index 4bae38bdc..9d3e52ece 100644
--- a/packages/base/src/page/SyncDataSource/Form/index.type.ts
+++ b/packages/base/src/page/SyncDataSource/Form/index.type.ts
@@ -17,6 +17,10 @@ export type SyncTaskFormFields = {
params: BackendFormValues;
allowQueryWhenLessThanAuditLevel?: SQLQueryConfigAllowQueryWhenLessThanAuditLevelEnum;
needAuditForSqlQuery?: boolean;
+ workbenchTemplateId?: string;
+ workbenchTemplateName?: string;
+ dataExportRuleTemplateId?: string;
+ dataExportRuleTemplateName?: string;
};
export type SyncTaskFormProps = {
diff --git a/packages/base/src/page/SyncDataSource/UpdatePage/__snapshots__/index.test.tsx.snap b/packages/base/src/page/SyncDataSource/UpdatePage/__snapshots__/index.test.tsx.snap
index 4fb4df698..0774d21f7 100644
--- a/packages/base/src/page/SyncDataSource/UpdatePage/__snapshots__/index.test.tsx.snap
+++ b/packages/base/src/page/SyncDataSource/UpdatePage/__snapshots__/index.test.tsx.snap
@@ -425,13 +425,31 @@ exports[`page/SyncDataSource/UpdateSyncTask get task source failed 1`] = `
-
- SQL审核配置
-
+
+
+ SQL审核配置
+
+
+
+
+ 管理不同业务场景下SQL执行所需遵循的审核规则,实现精细化管控
+
+
+
@@ -1451,16 +1516,34 @@ exports[`page/SyncDataSource/UpdateSyncTask render click reset btn 1`] = `
-
- SQL审核配置
-
+
@@ -2413,26 +2543,55 @@ exports[`page/SyncDataSource/UpdateSyncTask render click reset btn 2`] = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 基础配置
-
@@ -3119,7 +3122,7 @@ exports[`page/SyncDataSource/UpdateSyncTask render edit database snap 1`] = `
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-