审核结果
@@ -1619,46 +1528,97 @@ exports[`sqle/components/ReportDrawer render snap when showSourceFile is true 1`
class="wrapper-cont"
>
-
+
+
+ message
+
+
+
+ annotation
+
+
+
+
+
+
+
+ 已设例外的规则
+
+
+
+
+
+
@@ -1671,19 +1631,19 @@ exports[`sqle/components/ReportDrawer render snap when showSourceFile is true 1`
class="title-wrap"
>
SQL语句
diff --git a/packages/sqle/src/components/ReportDrawer/__tests__/index.test.tsx b/packages/sqle/src/components/ReportDrawer/__tests__/index.test.tsx
index 2724e83dd1..22a6b2570b 100644
--- a/packages/sqle/src/components/ReportDrawer/__tests__/index.test.tsx
+++ b/packages/sqle/src/components/ReportDrawer/__tests__/index.test.tsx
@@ -1,17 +1,13 @@
import ReportDrawer from '..';
-import { sqleSuperRender } from '../../../testUtils/superRender';
+
+import { renderWithTheme } from '../../../testUtils/customRender';
import { DetailReportDrawerProps } from '../index.type';
import { cleanup, screen } from '@testing-library/react';
import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser';
-import { RuleResV1LevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum';
-import {
- ignoreConsoleErrors,
- UtilsConsoleErrorStringsEnum
-} from '@actiontech/shared/lib/testUtil/common';
describe('sqle/components/ReportDrawer', () => {
const customRender = (params: DetailReportDrawerProps) => {
- return sqleSuperRender(
);
+ return renderWithTheme(
);
};
beforeEach(() => {
@@ -23,7 +19,7 @@ describe('sqle/components/ReportDrawer', () => {
jest.useRealTimers();
cleanup();
});
- ignoreConsoleErrors([UtilsConsoleErrorStringsEnum.UNKNOWN_EVENT_HANDLER]);
+
it('render snap open is false', () => {
const { baseElement } = customRender({
open: false,
@@ -57,7 +53,7 @@ describe('sqle/components/ReportDrawer', () => {
{
rule_name: 'rule a',
message: 'message',
- level: RuleResV1LevelEnum.error,
+ level: 'level',
annotation: 'annotation',
db_type: 'mysql'
}
@@ -83,7 +79,7 @@ describe('sqle/components/ReportDrawer', () => {
{
rule_name: 'rule a',
message: 'message',
- level: RuleResV1LevelEnum.warn,
+ level: 'level',
annotation: 'annotation',
db_type: 'mysql'
}
@@ -109,7 +105,7 @@ describe('sqle/components/ReportDrawer', () => {
{
rule_name: 'rule a',
message: 'message',
- level: RuleResV1LevelEnum.normal,
+ level: 'level',
annotation: 'annotation',
db_type: 'mysql'
}
@@ -135,7 +131,7 @@ describe('sqle/components/ReportDrawer', () => {
{
rule_name: 'rule a',
message: 'message1',
- level: RuleResV1LevelEnum.warn,
+ level: 'level',
annotation: 'annotation',
db_type: 'mysql',
isRuleDeleted: true
@@ -143,7 +139,7 @@ describe('sqle/components/ReportDrawer', () => {
{
rule_name: 'rule b',
message: 'message2',
- level: RuleResV1LevelEnum.error,
+ level: 'level',
annotation: 'annotation',
db_type: 'mysql'
}
@@ -167,7 +163,7 @@ describe('sqle/components/ReportDrawer', () => {
{
rule_name: 'rule a',
message: 'message',
- level: RuleResV1LevelEnum.error,
+ level: 'level',
annotation: 'annotation',
db_type: 'mysql'
}
@@ -179,66 +175,62 @@ describe('sqle/components/ReportDrawer', () => {
expect(baseElement).toMatchSnapshot();
});
- it('render snap when audit rule is exception', () => {
- const { baseElement } = customRender({
+ it('should hide rule exception entry without create permission', () => {
+ customRender({
open: true,
title: 'this is a title',
showAnnotation: true,
data: {
sql: 'select 1',
- sqlSourceFile: 'file_source',
- sqlStartLine: 3,
auditResult: [
{
rule_name: 'rule a',
message: 'message',
- level: RuleResV1LevelEnum.error,
+ level: 'level',
annotation: 'annotation',
- db_type: 'mysql',
- execution_failed: false
- },
- {
- rule_name: 'rule b',
- message: 'rule b',
- error_info: 'message',
- level: ' RuleResV1LevelEnum.error',
- annotation: 'annotation',
- db_type: 'mysql',
- execution_failed: true
+ db_type: 'mysql'
}
]
},
- onClose: jest.fn(),
- extra:
extra
+ ruleExceptionContext: {
+ projectName: 'default',
+ projectID: '700300',
+ instanceName: 'mysql_local_sqle',
+ sqlFingerprint: 'fp'
+ },
+ onClose: jest.fn()
});
- expect(baseElement).toMatchSnapshot();
+
+ expect(screen.queryByText('添加为单规则例外')).not.toBeInTheDocument();
});
- it('should hidden audit result when all rule execution failed', () => {
+ it('should show rule exception entry with create permission', () => {
customRender({
open: true,
title: 'this is a title',
showAnnotation: true,
data: {
sql: 'select 1',
- sqlSourceFile: 'file_source',
- sqlStartLine: 3,
auditResult: [
{
- rule_name: 'rule b',
- message: 'rule b',
- error_info: 'message',
- level: RuleResV1LevelEnum.error,
+ rule_name: 'rule a',
+ message: 'message',
+ level: 'level',
annotation: 'annotation',
- db_type: 'mysql',
- execution_failed: true
+ db_type: 'mysql'
}
]
},
- onClose: jest.fn(),
- extra:
extra
+ ruleExceptionContext: {
+ projectName: 'default',
+ projectID: '700300',
+ instanceName: 'mysql_local_sqle',
+ sqlFingerprint: 'fp'
+ },
+ canCreateRuleException: true,
+ onClose: jest.fn()
});
- expect(screen.queryByText('审核结果')).not.toBeInTheDocument();
+ expect(screen.getByText('添加为单规则例外')).toBeInTheDocument();
});
});
diff --git a/packages/sqle/src/components/ReportDrawer/index.tsx b/packages/sqle/src/components/ReportDrawer/index.tsx
index 3d378c40a6..f1daf572b0 100644
--- a/packages/sqle/src/components/ReportDrawer/index.tsx
+++ b/packages/sqle/src/components/ReportDrawer/index.tsx
@@ -1,29 +1,23 @@
import { useTranslation } from 'react-i18next';
-import { useMemo } from 'react';
+import { useMemo, useState } from 'react';
import {
BasicDrawer,
BasicTag,
EmptyBox,
- BasicToolTip
-} from '@actiontech/dms-kit';
-import {
+ BasicToolTips,
SQLRenderer,
BasicTypographyEllipsis,
- parse2ReactRouterPath
+ BasicButton
} from '@actiontech/shared';
import { DetailReportDrawerProps, IAuditResultItem } from './index.type';
-import {
- AuditReportStyleWrapper,
- AuditResultExceptionStyleWrapper
-} from './style';
+import { AuditReportStyleWrapper } from './style';
import AuditResultMessage from '../AuditResultMessage';
-import { Typography, Space } from 'antd';
+import { Typography, Space, Descriptions } from 'antd';
import { ProfileSquareFilled, EnvironmentFilled } from '@actiontech/icons';
import useThemeStyleData from '../../hooks/useThemeStyleData';
import { Spin } from 'antd';
-import { ROUTE_PATHS } from '@actiontech/dms-kit';
-import AuditExceptionItem from '../AuditResultMessage/AuditExceptionItem';
-import { useCurrentUser } from '@actiontech/shared/lib/features';
+import RuleExceptionDrawer from './RuleExceptionDrawer';
+import { formatTime } from '@actiontech/shared/lib/utils/Common';
const ReportDrawer = ({
open,
@@ -33,36 +27,49 @@ const ReportDrawer = ({
showAnnotation,
showSourceFile,
loading,
- extra
+ extra,
+ ruleExceptionContext,
+ canCreateRuleException = false,
+ onRuleExceptionCreated
}: DetailReportDrawerProps) => {
const { t } = useTranslation();
+
const { sqleTheme } = useThemeStyleData();
- const { theme } = useCurrentUser();
+ const [selectedRuleException, setSelectedRuleException] =
+ useState
();
+
const closeModal = () => {
onClose();
};
- const { auditResultWithNormalLevel, auditResultWithAuditException } =
- useMemo(() => {
- const normalLevel: IAuditResultItem[] = [];
- const exceptionResult: IAuditResultItem[] = [];
- (data?.auditResult ?? []).forEach((item) => {
- if (item.execution_failed) {
- exceptionResult.push(item);
- } else {
- normalLevel.push(item);
- }
- });
- return {
- auditResultWithAuditException: exceptionResult,
- auditResultWithNormalLevel: normalLevel
- };
- }, [data?.auditResult]);
+
+ const closeRuleExceptionDrawer = () => {
+ setSelectedRuleException(undefined);
+ };
+
const resultDataIsEmpty = useMemo(() => {
return (
(Array.isArray(data?.auditResult) && !data?.auditResult.length) ||
!data?.auditResult
);
}, [data?.auditResult]);
+
+ const skippedAuditResult = useMemo(
+ () => data?.skippedAuditResult ?? [],
+ [data?.skippedAuditResult]
+ );
+
+ const openOperationRecord = () => {
+ if (!ruleExceptionContext?.projectName) {
+ return;
+ }
+
+ window.open(
+ `/sqle/project/${
+ ruleExceptionContext.projectID ?? ruleExceptionContext.projectName
+ }/operation-record`
+ );
+ };
+
return (
<>
- 0}>
-
-
- {t('auditPlan.report.drawer.subTitle.result')}
-
-
- {resultDataIsEmpty ? (
-
- ) : (
- auditResultWithNormalLevel.map(
- (item: IAuditResultItem, index: number) => {
- if (!showAnnotation || item.isRuleDeleted) {
- return (
+
+
+ {t('auditPlan.report.drawer.subTitle.result')}
+
+
+ {resultDataIsEmpty ? (
+
+ ) : (
+ (data?.auditResult ?? [])?.map(
+ (item: IAuditResultItem, index: number) => {
+ if (!showAnnotation || item.isRuleDeleted) {
+ return (
+
+ );
+ }
+ return (
+
- );
- }
- )
- )}
+
+
+ setSelectedRuleException(item)}
+ >
+ {t('whitelist.ruleException.addAction')}
+
+
+
+
+ );
+ }
+ )
+ )}
+
+
+
+
+
+ {t('whitelist.ruleException.skippedModule.title')}
+
+
+ {skippedAuditResult.map((item, index) => (
+
+
+
+ {item.rule_name || '-'}
+
+
+ {item.rule_level || item.level || '-'}
+
+
+ {item.rule_desc ||
+ item.message ||
+ item.rule_name ||
+ '-'}
+
+
+ {item.created_by || '-'}
+
+
+ {formatTime(item.created_at, '-')}
+
+
+ {item.reason || '-'}
+
+
+
+ {t('whitelist.ruleException.viewAudit')}
+
+
+
+
+ ))}
-
-
0}>
-
-
-
- {t('auditPlan.report.drawer.subTitle.exception')}
-
-
-
-
- {auditResultWithAuditException.map((item, index) => {
- return (
-
- );
- })}
-
-
-
-
@@ -172,7 +237,7 @@ const ReportDrawer = ({
@@ -194,7 +259,7 @@ const ReportDrawer = ({
-
-
+
}
>
+
>
);
};
+
export default ReportDrawer;
diff --git a/packages/sqle/src/components/ReportDrawer/index.type.ts b/packages/sqle/src/components/ReportDrawer/index.type.ts
index b8c4aad919..1f445e588e 100644
--- a/packages/sqle/src/components/ReportDrawer/index.type.ts
+++ b/packages/sqle/src/components/ReportDrawer/index.type.ts
@@ -1,19 +1,34 @@
import {
IAuditResult,
- IRuleResV1
+ ISQLRuleExceptionResV1
} from '@actiontech/shared/lib/api/sqle/service/common';
import { ReactNode } from 'react';
-export type IAuditResultItem = Omit &
- IAuditResult & {
- isRuleDeleted?: boolean;
- };
+export type IAuditResultItem = IAuditResult & {
+ isRuleDeleted?: boolean;
+ annotation?: string;
+ desc?: string;
+};
+
+export type SkippedAuditResultItem = IAuditResult &
+ Partial;
+
+export type RuleExceptionContext = {
+ projectName: string;
+ projectID?: string;
+ instanceName?: string;
+ instanceId?: string;
+ dbType?: string;
+ sqlFingerprint?: string;
+};
export type TypeData = {
auditResult: Array;
+ skippedAuditResult?: Array;
sql: string;
sqlSourceFile?: string;
sqlStartLine?: number;
+ auditStatus?: string;
};
export interface DetailReportDrawerProps {
@@ -25,4 +40,19 @@ export interface DetailReportDrawerProps {
showSourceFile?: boolean;
loading?: boolean;
extra?: ReactNode;
+ ruleExceptionContext?: RuleExceptionContext;
+ canCreateRuleException?: boolean;
+ onRuleExceptionCreated?: () => void;
}
+
+export type RuleExceptionFormFields = {
+ reason: string;
+};
+
+export type RuleExceptionDrawerProps = {
+ open: boolean;
+ data?: IAuditResultItem;
+ context?: RuleExceptionContext;
+ onClose: () => void;
+ onCreated?: () => void;
+};
diff --git a/packages/sqle/src/components/ReportDrawer/style.ts b/packages/sqle/src/components/ReportDrawer/style.ts
index ad4662cecf..c429ebeb40 100644
--- a/packages/sqle/src/components/ReportDrawer/style.ts
+++ b/packages/sqle/src/components/ReportDrawer/style.ts
@@ -5,7 +5,15 @@ export const AuditReportStyleWrapper = styled('div')`
height: 100%;
.wrapper-item {
- height: 50%;
+ height: 34%;
+
+ &.skipped-rule-wrapper {
+ height: 28%;
+
+ .wrapper-cont {
+ height: calc(100% - 68px);
+ }
+ }
h3 {
margin-bottom: 0;
@@ -30,9 +38,34 @@ export const AuditReportStyleWrapper = styled('div')`
padding: 8px 12px;
margin-bottom: 4px;
+ .rule-exception-action {
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 8px;
+ }
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .skipped-rule-item {
+ background: ${({ theme }) =>
+ theme.sharedTheme.uiToken.colorFillTertiary};
+ border: 1px solid
+ ${({ theme }) => theme.sharedTheme.uiToken.colorBorderSecondary};
+ border-radius: 4px;
+ padding: 12px;
+ margin-bottom: 8px;
+
&:last-child {
margin-bottom: 0;
}
+
+ .ant-descriptions-item-label,
+ .ant-descriptions-item-content {
+ padding-bottom: 8px;
+ }
}
}
diff --git a/packages/sqle/src/locale/en-US/operationRecord.ts b/packages/sqle/src/locale/en-US/operationRecord.ts
index b4b6300806..10a933333d 100644
--- a/packages/sqle/src/locale/en-US/operationRecord.ts
+++ b/packages/sqle/src/locale/en-US/operationRecord.ts
@@ -7,6 +7,7 @@ export default {
exportButtonText: 'Export',
exporting: 'Exporting operation log list...',
exportSuccessTips: 'Operation log list exported successfully',
+ auditContentKeywordsTips: 'Located by audit content: {{keywords}}',
filterForm: {
operatingTime: 'Operation time',
projectName: 'Project name',
diff --git a/packages/sqle/src/locale/en-US/whitelist.ts b/packages/sqle/src/locale/en-US/whitelist.ts
index 9268e99045..830cd1cd77 100644
--- a/packages/sqle/src/locale/en-US/whitelist.ts
+++ b/packages/sqle/src/locale/en-US/whitelist.ts
@@ -7,6 +7,10 @@ export default {
ceTips:
"If a user enables a rule but wants to temporarily bypass the triggering of certain rules in actual use, they can enable the platform'S audit whitelist feature.\nCurrently, it supports string matching or SQL fingerprint matching. Statements added to the SQL audit whitelist will not be subject to audit rules when creating a workflow request.",
allWhitelist: 'All audit whitelist statements',
+ view: {
+ sql: 'Whole SQL exception',
+ rule: 'Rule exception'
+ },
table: {
sql: 'SQL statement',
desc: 'Audit whitelist description',
@@ -39,5 +43,36 @@ export default {
tips: 'When the match type or match content is modified, the match count and last match time of this record will be reset.'
},
sql: 'SQL'
+ },
+ ruleException: {
+ addAction: 'Add as rule exception',
+ drawerTitle: 'Add rule exception',
+ addSuccess: 'Rule exception added successfully',
+ duplicateTips:
+ 'This rule exception already exists. No need to add it again.',
+ cancelAction: 'Cancel exception',
+ deleting: 'Canceling rule exception...',
+ deleteSuccess: 'Rule exception canceled successfully',
+ confirmCancel:
+ 'Confirm canceling this rule exception? The same tuple will trigger this rule again after cancellation.',
+ project: 'Project',
+ instance: 'Data source',
+ sqlFingerprint: 'SQL fingerprint',
+ ruleName: 'Rule name',
+ ruleDesc: 'Rule description',
+ ruleLevel: 'Original rule level',
+ reason: 'Reason',
+ createdBy: 'Added by',
+ createdAt: 'Added at',
+ matchInfo: 'Hit information',
+ matchInfoWithTime: 'Hit {{count}} times, last hit {{time}}',
+ audit: 'Action',
+ viewAudit: 'View audit',
+ missingSqlFingerprint:
+ 'The current audit result does not return a SQL fingerprint, so rule exception cannot be added yet.',
+ skippedModule: {
+ title: 'Excepted rules',
+ empty: 'No excepted rules in this audit result'
+ }
}
};
diff --git a/packages/sqle/src/locale/zh-CN/operationRecord.ts b/packages/sqle/src/locale/zh-CN/operationRecord.ts
index 034ac19ac5..e391105cb1 100644
--- a/packages/sqle/src/locale/zh-CN/operationRecord.ts
+++ b/packages/sqle/src/locale/zh-CN/operationRecord.ts
@@ -8,6 +8,7 @@ export default {
exportButtonText: '导出',
exporting: '正在导出操作记录列表...',
exportSuccessTips: '操作记录列表导出成功',
+ auditContentKeywordsTips: '已按审计内容定位:{{keywords}}',
filterForm: {
operatingTime: '操作时间',
projectName: '操作项目',
diff --git a/packages/sqle/src/locale/zh-CN/whitelist.ts b/packages/sqle/src/locale/zh-CN/whitelist.ts
index 401ccd8a3f..30fa8f73b1 100644
--- a/packages/sqle/src/locale/zh-CN/whitelist.ts
+++ b/packages/sqle/src/locale/zh-CN/whitelist.ts
@@ -7,6 +7,10 @@ export default {
ceTips:
'如果用户开启了某条规则,但在实际使用中又想临时规避某些规则的触发,可以启用平台的审核SQL例外功能。\n目前支持按字符串匹配或按照SQL指纹匹配,添加在SQL审核审核SQL例外中的语句,在提交工单申请时,将不受审核规则的约束。',
allWhitelist: '所有审核SQL例外语句',
+ view: {
+ sql: '整条 SQL 例外',
+ rule: '单规则例外'
+ },
table: {
sql: '内容',
desc: '描述',
@@ -39,5 +43,34 @@ export default {
tips: '当修改匹配类型或匹配内容后,该条记录的匹配次数和最后匹配时间将被重置。'
},
sql: 'SQL语句'
+ },
+ ruleException: {
+ addAction: '添加为单规则例外',
+ drawerTitle: '添加单规则例外',
+ addSuccess: '添加单规则例外成功',
+ duplicateTips: '该规则例外已存在,无需重复添加',
+ cancelAction: '取消例外',
+ deleting: '正在取消单规则例外...',
+ deleteSuccess: '取消单规则例外成功',
+ confirmCancel:
+ '确认取消这条单规则例外么?取消后同四元组复审将重新触发该规则。',
+ project: '项目',
+ instance: '数据源',
+ sqlFingerprint: 'SQL指纹',
+ ruleName: '规则名',
+ ruleDesc: '规则描述',
+ ruleLevel: '规则原级别',
+ reason: '添加原因',
+ createdBy: '添加例外的人',
+ createdAt: '添加时间',
+ matchInfo: '命中信息',
+ matchInfoWithTime: '命中 {{count}} 次,最近命中 {{time}}',
+ audit: '操作',
+ viewAudit: '查看审计',
+ missingSqlFingerprint: '当前审核结果未返回 SQL 指纹,暂不能添加单规则例外',
+ skippedModule: {
+ title: '已设例外的规则',
+ empty: '暂无已设例外的规则'
+ }
}
};
diff --git a/packages/sqle/src/page/OperationRecord/List/index.tsx b/packages/sqle/src/page/OperationRecord/List/index.tsx
index 16b577fc0a..0269812280 100644
--- a/packages/sqle/src/page/OperationRecord/List/index.tsx
+++ b/packages/sqle/src/page/OperationRecord/List/index.tsx
@@ -1,14 +1,15 @@
-import { useMemo } from 'react';
+import { useMemo, useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
+import { useSearchParams } from 'react-router-dom';
import { Space, message } from 'antd';
import { useRequest, useBoolean } from 'ahooks';
-import { BasicButton, PageHeader } from '@actiontech/dms-kit';
-import operationRecord from '@actiontech/shared/lib/api/base/service/OperationRecord';
+import { BasicButton, PageHeader } from '@actiontech/shared';
+import operationRecord from '@actiontech/shared/lib/api/sqle/service/OperationRecord';
import {
IGetOperationRecordListV1Params,
IGetExportOperationRecordListV1Params
} from '@actiontech/shared/lib/api/sqle/service/OperationRecord/index.d';
-import { IOperationRecordListItem } from '@actiontech/shared/lib/api/base/service/common';
+import { IOperationRecordList } from '@actiontech/shared/lib/api/sqle/service/common';
import {
ActiontechTable,
useTableRequestParams,
@@ -17,28 +18,58 @@ import {
useTableFilterContainer,
FilterCustomProps,
TableToolbar
-} from '@actiontech/dms-kit/es/components/ActiontechTable';
-import {
- useCurrentProject,
- useCurrentUser
-} from '@actiontech/shared/lib/features';
+} from '@actiontech/shared/lib/components/ActiontechTable';
+import { useCurrentProject } from '@actiontech/shared/lib/global';
import {
OperationRecordListColumn,
OperationRecordListFilterParamType
} from './column';
+import useOperationTypeName from '../../../hooks/useOperationTypeName';
+import useOperationActions from '../../../hooks/useOperationActions';
import { ResponseCode } from '../../../data/common';
import { DownArrowLineOutlined } from '@actiontech/icons';
+
const OperationRecordList: React.FC = () => {
const { t } = useTranslation();
+ const [searchParams] = useSearchParams();
+
const [messageApi, contextHolder] = message.useMessage();
+
const { projectName } = useCurrentProject();
- const { bindProjects, userRoles } = useCurrentUser();
+
+ const [currentOperationTypeName, setCurrentOperationTypeName] =
+ useState();
const [
exportButtonEnableStatus,
{ setFalse: finishExport, setTrue: startExport }
] = useBoolean(false);
+ const { updateOperationTypeNameList, operationTypeNameOptions } =
+ useOperationTypeName();
+
+ const { updateOperationActions, operationActionOptions } =
+ useOperationActions();
+
+ const defaultFilterInfo = useMemo(() => {
+ const filterOperateTypeName = searchParams.get('filter_operate_type_name');
+
+ if (!filterOperateTypeName) {
+ return {};
+ }
+
+ return {
+ filter_operate_type_name: filterOperateTypeName
+ };
+ }, [searchParams]);
+
+ const auditContentKeywords = useMemo(
+ () =>
+ searchParams.get('audit_content_keywords')?.split('|').filter(Boolean) ??
+ [],
+ [searchParams]
+ );
+
const {
tableFilterInfo,
updateTableFilterInfo,
@@ -48,11 +79,15 @@ const OperationRecordList: React.FC = () => {
setSearchKeyword,
refreshBySearchKeyword
} = useTableRequestParams<
- IOperationRecordListItem,
+ IOperationRecordList,
OperationRecordListFilterParamType
- >();
+ >({
+ defaultFilterInfo
+ });
+
const { requestErrorMessage, handleTableRequestError } =
useTableRequestError();
+
const {
data: operationRecordList,
loading,
@@ -61,46 +96,38 @@ const OperationRecordList: React.FC = () => {
() => {
const params: IGetOperationRecordListV1Params = {
...pagination,
+ page_size: auditContentKeywords.length > 0 ? 100 : pagination.page_size,
...tableFilterInfo,
+ filter_operate_project_name: projectName,
fuzzy_search_operate_user_name: searchKeyword
};
- if (!!projectName) {
- params.filter_operate_project_name = projectName;
- }
return handleTableRequestError(
- operationRecord.GetOperationRecordList(params)
- );
+ operationRecord.getOperationRecordListV1(params)
+ ).then((res) => {
+ if (auditContentKeywords.length === 0) {
+ return res;
+ }
+
+ const filteredData = res.list?.filter((item) => {
+ return auditContentKeywords.every((keyword) =>
+ item.operation_content?.includes(keyword)
+ );
+ });
+
+ return {
+ ...res,
+ list: filteredData,
+ total: filteredData?.length ?? 0
+ };
+ });
},
{
- refreshDeps: [pagination, tableFilterInfo]
+ refreshDeps: [pagination, tableFilterInfo, auditContentKeywords]
}
);
+
const filterCustomProps = useMemo(() => {
- let operationOptions;
- if (
- userRoles.admin ||
- userRoles.auditAdministrator ||
- userRoles.systemAdministrator
- ) {
- operationOptions = [
- {
- label: t('operationRecord.list.filterForm.globalOperation'),
- value: ''
- },
- ...bindProjects.map((v) => ({
- label: v.project_name,
- value: v.project_name
- }))
- ];
- } else {
- operationOptions = bindProjects
- .filter((i) => i.is_manager)
- .map((v) => ({
- label: v.project_name,
- value: v.project_name
- }));
- }
- return new Map([
+ return new Map([
[
'operation_time',
{
@@ -108,25 +135,34 @@ const OperationRecordList: React.FC = () => {
}
],
[
- 'project_name',
+ 'operation_type_name',
+ {
+ options: operationTypeNameOptions,
+ onChange: (value: unknown) => {
+ setCurrentOperationTypeName(value as string);
+ }
+ }
+ ],
+ [
+ 'operation_content',
{
- options: operationOptions
+ options: operationActionOptions(currentOperationTypeName)
}
]
]);
- }, [bindProjects, t, userRoles]);
-
- const columns = useMemo(() => {
- if (!!projectName) {
- return OperationRecordListColumn.filter(
- (column) => column.dataIndex !== 'project_name'
- );
- }
- return OperationRecordListColumn;
- }, [projectName]);
+ }, [
+ operationTypeNameOptions,
+ operationActionOptions,
+ currentOperationTypeName
+ ]);
const { filterButtonMeta, filterContainerMeta, updateAllSelectedFilterItem } =
- useTableFilterContainer(columns, updateTableFilterInfo);
+ useTableFilterContainer(OperationRecordListColumn, updateTableFilterInfo);
+
+ useEffect(() => {
+ updateOperationTypeNameList();
+ updateOperationActions();
+ }, [updateOperationActions, updateOperationTypeNameList]);
const onExport = () => {
startExport();
@@ -136,13 +172,11 @@ const OperationRecordList: React.FC = () => {
);
const param: IGetExportOperationRecordListV1Params = {
...tableFilterInfo,
+ filter_operate_project_name: projectName,
fuzzy_search_operate_user_name: searchKeyword
};
- if (!!projectName) {
- param.filter_operate_project_name = projectName;
- }
operationRecord
- .ExportOperationRecordList(param, {
+ .getExportOperationRecordListV1(param, {
responseType: 'blob'
})
.then((res) => {
@@ -155,15 +189,12 @@ const OperationRecordList: React.FC = () => {
finishExport();
});
};
+
return (
{contextHolder}
{
}
/>
+ {auditContentKeywords.length > 0 && (
+
+ {t('operationRecord.list.auditContentKeywordsTips', {
+ keywords: auditContentKeywords.join(' / ')
+ })}
+
+ )}
{
current: pagination.page_index
}}
loading={loading}
- columns={columns}
+ columns={OperationRecordListColumn}
onChange={tableChange}
errorMessage={requestErrorMessage}
/>
);
};
+
export default OperationRecordList;
diff --git a/packages/sqle/src/page/OperationRecord/index.test.tsx b/packages/sqle/src/page/OperationRecord/index.test.tsx
index 9332bac567..64f67cc578 100644
--- a/packages/sqle/src/page/OperationRecord/index.test.tsx
+++ b/packages/sqle/src/page/OperationRecord/index.test.tsx
@@ -1,6 +1,7 @@
import { screen, cleanup } from '@testing-library/react';
-import { superRender } from '@actiontech/shared/lib/testUtil/superRender';
-import operationRecord from '@actiontech/shared/lib/testUtil/mockApi/sqle/operationRecord';
+import { renderWithReduxAndTheme } from '@actiontech/shared/lib/testUtil/customRender';
+import { MemoryRouter } from 'react-router-dom';
+import operationRecord from '../../testUtils/mockApi/operationRecord';
import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject';
import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser';
import OperationRecord from '.';
@@ -20,9 +21,16 @@ describe('slqe/OperationRecord', () => {
});
test('should render operation record list', async () => {
- const { baseElement } = superRender();
+ const { baseElement } = renderWithReduxAndTheme(
+
+
+
+ );
expect(baseElement).toMatchSnapshot();
expect(operationRecordListSpy).toHaveBeenCalledTimes(1);
expect(screen.getByText('导出')).toBeInTheDocument();
+ expect(
+ screen.queryByText('操作记录列表为企业版功能')
+ ).not.toBeInTheDocument();
});
});
diff --git a/packages/sqle/src/page/OperationRecord/index.tsx b/packages/sqle/src/page/OperationRecord/index.tsx
index d496f0ffc4..5779ac9971 100644
--- a/packages/sqle/src/page/OperationRecord/index.tsx
+++ b/packages/sqle/src/page/OperationRecord/index.tsx
@@ -1,38 +1,19 @@
import { useTranslation } from 'react-i18next';
-import { PageHeader } from '@actiontech/dms-kit';
-import { EnterpriseFeatureDisplay } from '@actiontech/shared';
-import { Typography } from 'antd';
+import { PageHeader } from '@actiontech/shared';
import OperationRecordList from './List';
-import { useCurrentProject } from '@actiontech/shared/lib/features';
const OperationRecord = () => {
const { t } = useTranslation();
- const { projectName } = useCurrentProject();
-
return (
<>
{/* #if [ce] */}
-
+
{/* #endif */}
-
- {t('operationRecord.ceTips')}
-
- }
- >
-
-
+
>
);
};
+
export default OperationRecord;
diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/AuditResultDrawer.tsx b/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/AuditResultDrawer.tsx
index 99924f0dc8..d833d12867 100644
--- a/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/AuditResultDrawer.tsx
+++ b/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/AuditResultDrawer.tsx
@@ -1,33 +1,39 @@
-import { AiOutlined } from '@actiontech/icons';
import ReportDrawer from '../../../../../components/ReportDrawer';
import useAuditResultRuleInfo from '../../../../../components/ReportDrawer/useAuditResultRuleInfo';
import { AuditResultDrawerProps } from './index.type';
import { AuditResultDrawerTitleStyleWrapper } from './style';
-import { BasicButton } from '@actiontech/dms-kit';
+import { BasicButton } from '@actiontech/shared';
import { useTranslation } from 'react-i18next';
-import { Space } from 'antd';
+
const AuditResultDrawer: React.FC = ({
onClose,
open,
auditResultRecord,
dbType,
- clickAnalyze,
- handleClickSqlRewritten
+ projectID,
+ projectName,
+ instanceName,
+ canCreateRuleException,
+ onRuleExceptionCreated,
+ clickAnalyze
}) => {
const { t } = useTranslation();
const { auditResultRuleInfo, loading } = useAuditResultRuleInfo(
auditResultRecord?.audit_result ?? [],
dbType ?? ''
);
+
return (
= ({
}
showAnnotation
loading={loading}
+ ruleExceptionContext={
+ projectName && canCreateRuleException
+ ? {
+ projectName,
+ projectID,
+ instanceName,
+ dbType,
+ sqlFingerprint:
+ auditResultRecord?.sql_fingerprint ??
+ auditResultRecord?.audit_fingerprint ??
+ auditResultRecord?.exec_sql
+ }
+ : undefined
+ }
+ canCreateRuleException={canCreateRuleException}
+ onRuleExceptionCreated={onRuleExceptionCreated}
extra={
-
- {handleClickSqlRewritten && (
- }
- onClick={() => {
- handleClickSqlRewritten(auditResultRecord!);
- onClose();
- }}
- >
- {t('sqlRewrite.actionName')}
-
- )}
- clickAnalyze(auditResultRecord?.number)}>
- {t('execWorkflow.audit.table.analyze')}
-
-
+ clickAnalyze(auditResultRecord?.number)}>
+ {t('execWorkflow.audit.table.analyze')}
+
}
/>
);
};
+
export default AuditResultDrawer;
diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/index.tsx
index 4961e796f2..be1ec6a7f5 100644
--- a/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/index.tsx
+++ b/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/index.tsx
@@ -1,100 +1,91 @@
-import { useEffect, useRef, useState, useMemo, useCallback } from 'react';
+import { useEffect, useRef, useState } from 'react';
import { useBoolean, useRequest } from 'ahooks';
import task from '@actiontech/shared/lib/api/sqle/service/task';
-import { ResponseCode } from '@actiontech/dms-kit';
+import { ResponseCode } from '@actiontech/shared/lib/enum';
import { IAuditTaskSQLResV2 } from '@actiontech/shared/lib/api/sqle/service/common';
import {
ActiontechTable,
useTableRequestError,
useTableRequestParams
-} from '@actiontech/dms-kit/es/components/ActiontechTable';
+} from '@actiontech/shared/lib/components/ActiontechTable';
import { AuditResultTableProps } from './index.type';
-import { AuditResultForCreateWorkflowColumn } from './column';
+import {
+ AuditResultForCreateWorkflowActions,
+ AuditResultForCreateWorkflowColumn
+} from './column';
import AuditResultDrawer from './AuditResultDrawer';
import useWhitelistRedux from '../../../../Whitelist/hooks/useWhitelistRedux';
import AddWhitelistModal from '../../../../Whitelist/Drawer/AddWhitelist';
-import { AuditResultForCreateWorkflowActions } from './actions';
-import { usePermission, PERMISSIONS } from '@actiontech/shared/lib/features';
-import { parse2ReactRouterPath } from '@actiontech/shared/lib/components/TypedRouter/utils';
-import { ROUTE_PATHS } from '@actiontech/dms-kit';
-import SwitchSqlBackupStrategyModal from './SwitchSqlBackupStrategyModal';
-import { EmptyBox } from '@actiontech/dms-kit';
-import EventEmitter from '../../../../../utils/EventEmitter';
-import EmitterKey from '../../../../../data/EmitterKey';
-import SqlRewrittenDrawer from '../../../../../components/SqlRewrittenDrawer/index';
-import useSqlRewrittenDrawerState from '../../../../../components/SqlRewrittenDrawer/hooks/useSqlRewrittenDrawerState';
+
const AuditResultTable: React.FC = ({
noDuplicate,
taskID,
auditLevelFilterValue,
projectID,
+ projectName,
updateTaskRecordCount,
dbType,
instanceName,
- schema,
- allowSwitchBackupPolicy = false,
- supportedBackupPolicies,
- updateTaskAuditRuleExceptionStatus
+ canCreateRuleException,
+ onRuleExceptionCreated
}) => {
- const {
- sqlRewrittenOpen,
- handleCloseSqlRewrittenDrawer,
- handleOpenSqlRewrittenDrawer,
- originSqlInfo,
- handleChangeOriginInfo
- } = useSqlRewrittenDrawerState();
const [currentAuditResultRecord, setCurrentAuditResultRecord] =
useState();
const [
auditResultDrawerVisibility,
{ setFalse: closeAuditResultDrawer, setTrue: openAuditResultDrawer }
] = useBoolean();
- const [execSqlID, setExecSqlID] = useState();
const { pagination, tableChange, setPagination } = useTableRequestParams();
const { requestErrorMessage, handleTableRequestError } =
useTableRequestError();
- const { parse2TableActionPermissions, checkActionDisabledByBWP } =
- usePermission();
- const isBusinessWriteDisabled = checkActionDisabledByBWP(
- PERMISSIONS.ACTIONS.SQLE.SQL_EXEC_WORKFLOW.CREATE
- );
- const { openCreateWhitelistModal, updateSelectWhitelistRecord } =
- useWhitelistRedux();
- const [
- switchBackupPolicyOpen,
- {
- setTrue: openSwitchBackupPolicyModal,
- setFalse: closeSwitchBackupPolicyModal
+
+ const {
+ openCreateWhitelistModal,
+ updateSelectWhitelistRecord,
+ actionPermission
+ } = useWhitelistRedux();
+
+ const handleClickAnalyze = (sqlNum?: number) => {
+ if (typeof sqlNum === 'undefined') {
+ return;
}
- ] = useBoolean();
- const handleClickAnalyze = useCallback(
- (sqlNum?: number) => {
- if (typeof sqlNum === 'undefined') {
- return;
- }
- window.open(
- parse2ReactRouterPath(ROUTE_PATHS.SQLE.SQL_EXEC_WORKFLOW.analyze, {
- params: {
- projectID,
- taskId: taskID ?? '',
- sqlNum: sqlNum.toString()
- },
- queries: {
- instance_name: instanceName ?? '',
- schema: schema ?? ''
- }
- })
- );
- },
- [projectID, taskID, instanceName, schema]
- );
+ window.open(
+ `/sqle/project/${projectID}/exec-workflow/${taskID}/${sqlNum}/analyze`
+ );
+ };
const updateSqlDescribeProtect = useRef(false);
+ const updateSqlDescribe = (sqlNum: number, sqlDescribe: string) => {
+ if (updateSqlDescribeProtect.current) {
+ return;
+ }
+ updateSqlDescribeProtect.current = true;
+ task
+ .updateAuditTaskSQLsV1({
+ number: `${sqlNum}`,
+ description: sqlDescribe,
+ task_id: taskID!
+ })
+ .then((res) => {
+ if (res.data.code === ResponseCode.SUCCESS) {
+ refresh();
+ }
+ })
+ .finally(() => {
+ updateSqlDescribeProtect.current = false;
+ });
+ };
+
+ const onClickAuditResult = (record: IAuditTaskSQLResV2) => {
+ openAuditResultDrawer();
+ setCurrentAuditResultRecord(record);
+ };
+
const { data, loading, refresh } = useRequest(
() =>
handleTableRequestError(
task.getAuditTaskSQLsV2({
task_id: taskID!,
- filter_audit_level: auditLevelFilterValue ?? undefined,
+ filter_audit_level: auditLevelFilterValue,
page_index: pagination.page_index.toString(),
page_size: pagination.page_size.toString(),
no_duplicate: noDuplicate
@@ -104,106 +95,15 @@ const AuditResultTable: React.FC = ({
ready: typeof taskID === 'string',
refreshDeps: [pagination, taskID],
onSuccess(res) {
- if (auditLevelFilterValue === null) {
+ if (auditLevelFilterValue === undefined) {
updateTaskRecordCount?.(taskID ?? '', res.total ?? 0);
}
- updateTaskAuditRuleExceptionStatus?.(res.list ?? []);
},
onError() {
updateTaskRecordCount?.(taskID ?? '', 0);
- updateTaskAuditRuleExceptionStatus?.([]);
}
}
);
- const updateSqlDescribe = useCallback(
- (sqlNum: number, sqlDescribe: string) => {
- if (updateSqlDescribeProtect.current) {
- return;
- }
- updateSqlDescribeProtect.current = true;
- task
- .updateAuditTaskSQLsV1({
- number: `${sqlNum}`,
- description: sqlDescribe,
- task_id: taskID!
- })
- .then((res) => {
- if (res.data.code === ResponseCode.SUCCESS) {
- refresh();
- }
- })
- .finally(() => {
- updateSqlDescribeProtect.current = false;
- });
- },
- [refresh, taskID]
- );
- const onClickAuditResult = useCallback(
- (record: IAuditTaskSQLResV2) => {
- openAuditResultDrawer();
- setCurrentAuditResultRecord(record);
- },
- [openAuditResultDrawer]
- );
- const onCreateWhitelist = useCallback(
- (record?: IAuditTaskSQLResV2) => {
- openCreateWhitelistModal();
- updateSelectWhitelistRecord({
- value: record?.exec_sql
- });
- },
- [openCreateWhitelistModal, updateSelectWhitelistRecord]
- );
- const handleClickSqlRewritten = useCallback(
- (record: IAuditTaskSQLResV2) => {
- handleOpenSqlRewrittenDrawer();
- handleChangeOriginInfo({
- sql: record.exec_sql ?? '',
- number: record.number ?? 0,
- instanceName: instanceName ?? '',
- schema: schema ?? ''
- });
- },
- [handleOpenSqlRewrittenDrawer, handleChangeOriginInfo, instanceName, schema]
- );
- const actions = useMemo(() => {
- return parse2TableActionPermissions(
- AuditResultForCreateWorkflowActions(
- handleClickAnalyze,
- onCreateWhitelist,
- handleClickSqlRewritten
- )
- );
- }, [
- parse2TableActionPermissions,
- handleClickAnalyze,
- onCreateWhitelist,
- handleClickSqlRewritten
- ]);
- const onSwitchSqlBackupPolicy = useCallback(
- (sqlId?: number) => {
- openSwitchBackupPolicyModal();
- setExecSqlID(sqlId);
- },
- [openSwitchBackupPolicyModal]
- );
- const columns = useMemo(() => {
- const columnList = AuditResultForCreateWorkflowColumn(
- updateSqlDescribe,
- onClickAuditResult,
- onSwitchSqlBackupPolicy,
- isBusinessWriteDisabled
- );
- return allowSwitchBackupPolicy
- ? columnList
- : columnList.filter((column) => column.dataIndex !== 'backup_strategy');
- }, [
- onSwitchSqlBackupPolicy,
- updateSqlDescribe,
- onClickAuditResult,
- allowSwitchBackupPolicy,
- isBusinessWriteDisabled
- ]);
// @feature: useTableRequestParams 整合自定义filter info
useEffect(() => {
@@ -213,21 +113,23 @@ const AuditResultTable: React.FC = ({
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [auditLevelFilterValue, noDuplicate]);
- useEffect(() => {
- if (allowSwitchBackupPolicy) {
- const { unsubscribe } = EventEmitter.subscribe(
- EmitterKey.Refresh_Sql_Exec_workflow_Audit_Result_List,
- refresh
- );
- return unsubscribe;
- }
- }, [allowSwitchBackupPolicy, refresh]);
+
+ const onCreateWhitelist = (record?: IAuditTaskSQLResV2) => {
+ openCreateWhitelistModal();
+ updateSelectWhitelistRecord({
+ value: record?.exec_sql
+ });
+ };
+
return (
<>
= ({
total: data?.total ?? 0,
current: pagination.page_index ?? 1
}}
- actions={actions}
+ actions={AuditResultForCreateWorkflowActions(
+ handleClickAnalyze,
+ onCreateWhitelist,
+ actionPermission
+ )}
/>
-
- {/* #if [ee] */}
-
-
-
- {/* #endif */}
>
);
};
+
export default AuditResultTable;
diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/index.type.ts b/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/index.type.ts
index 904a81dbdb..7ec48b0fdf 100644
--- a/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/index.type.ts
+++ b/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/Table/index.type.ts
@@ -1,39 +1,28 @@
import { IAuditTaskSQLResV2 } from '@actiontech/shared/lib/api/sqle/service/common';
import { getAuditTaskSQLsV2FilterAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/task/index.enum';
-import { InstanceTipResV2SupportedBackupStrategyEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum';
-import { AuditResultListProps } from '../index.type';
-export interface AuditResultTableProps
- extends Pick<
- AuditResultListProps,
- | 'updateTaskRecordCount'
- | 'allowSwitchBackupPolicy'
- | 'updateTaskAuditRuleExceptionStatus'
- > {
+export type AuditResultTableProps = {
noDuplicate: boolean;
taskID?: string;
- auditLevelFilterValue: getAuditTaskSQLsV2FilterAuditLevelEnum | null;
+ auditLevelFilterValue?: getAuditTaskSQLsV2FilterAuditLevelEnum;
projectID: string;
+ updateTaskRecordCount?: (taskId: string, sqlNumber: number) => void;
dbType?: string;
+ projectName?: string;
instanceName?: string;
- schema?: string;
- supportedBackupPolicies?: InstanceTipResV2SupportedBackupStrategyEnum[];
-}
+ canCreateRuleException?: boolean;
+ onRuleExceptionCreated?: () => void;
+};
export type AuditResultDrawerProps = {
open: boolean;
onClose: () => void;
auditResultRecord?: IAuditTaskSQLResV2;
dbType?: string;
+ projectID?: string;
+ projectName?: string;
+ instanceName?: string;
+ canCreateRuleException?: boolean;
+ onRuleExceptionCreated?: () => void;
clickAnalyze: (sqlNum?: number) => void;
- handleClickSqlRewritten?: (record: IAuditTaskSQLResV2) => void;
-};
-
-export type SwitchSqlBackupStrategyModalProps = {
- sqlID?: number;
- open: boolean;
- onCancel: () => void;
- taskID?: string;
- refresh: () => void;
- supportedBackupPolicies?: InstanceTipResV2SupportedBackupStrategyEnum[];
};
diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/index.tsx
index 2f886048af..a18222129b 100644
--- a/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/index.tsx
+++ b/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/index.tsx
@@ -1,5 +1,5 @@
-import { BasicSegmented, EmptyBox, BasicButton } from '@actiontech/dms-kit';
-import { SegmentedRowStyleWrapper } from '@actiontech/dms-kit';
+import { BasicSegmented, EmptyBox } from '@actiontech/shared';
+import { SegmentedRowStyleWrapper } from '@actiontech/shared/lib/styleWrapper/element';
import { Divider, Space } from 'antd';
import { useTranslation } from 'react-i18next';
import { AuditResultForCreateWorkflowStyleWrapper } from './style';
@@ -12,40 +12,47 @@ import DownloadRecord from '../DownloadRecord';
import AuditResultTable from './Table';
import AuditResultFilterContainer from '../AuditResultFilterContainer';
import { AuditTaskResV1AuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum';
-import { useCurrentProject } from '@actiontech/shared/lib/features';
+import {
+ useCurrentProject,
+ useCurrentUser
+} from '@actiontech/shared/lib/global';
import useAuditResultFilterParams from '../AuditResultFilterContainer/useAuditResultFilterParams';
import {
auditLevelDictionary,
translateDictionaryI18nLabel
} from '../../../../hooks/useStaticStatus/index.data';
+
const AuditResultList: React.FC = ({
tasks,
updateTaskRecordCount,
showTaskTab = true,
- allowSwitchBackupPolicy = false,
- onBatchSwitchBackupPolicy,
- tasksSupportedBackupPolicies,
- updateTaskAuditRuleExceptionStatus
+ onRuleExceptionCreated
}) => {
const { t } = useTranslation();
- const { projectID } = useCurrentProject();
+ const { projectID, projectName, projectArchive } = useCurrentProject();
+ const { isAdmin, isProjectManager } = useCurrentUser();
const {
noDuplicate,
setNoDuplicate,
auditLevelFilterValue,
setAuditLevelFilterValue
} = useAuditResultFilterParams();
+
const [currentTaskID, setCurrentTaskID] = useState();
+
const currentTask = useMemo(
() => tasks.find((v) => `${v.task_id}` === currentTaskID),
[currentTaskID, tasks]
);
- const currentTaskSupportedBackupPolicies = useMemo(() => {
- return tasksSupportedBackupPolicies?.[currentTask?.task_id ?? 0];
- }, [tasksSupportedBackupPolicies, currentTask?.task_id]);
+
+ const canCreateRuleException = useMemo(() => {
+ return (isAdmin || isProjectManager(projectName)) && !projectArchive;
+ }, [isAdmin, isProjectManager, projectName, projectArchive]);
+
const handleChangeCurrentTask = (taskID?: string) => {
setCurrentTaskID(taskID);
};
+
const generateCurrentTaskLabel = (
instanceName?: string,
auditLevel?: AuditTaskResV1AuditLevelEnum
@@ -53,6 +60,7 @@ const AuditResultList: React.FC = ({
if (!instanceName) {
return '-';
}
+
return (
= ({
/>
);
};
+
useEffect(() => {
if (typeof tasks?.[0]?.task_id !== 'undefined') {
setCurrentTaskID(`${tasks[0].task_id}`);
}
}, [tasks]);
+
return (
@@ -85,26 +95,6 @@ const AuditResultList: React.FC = ({
)}
- {/* #if [ee] */}
-
- {
- onBatchSwitchBackupPolicy?.(
- currentTaskID,
- currentTaskSupportedBackupPolicies
- );
- }}
- >
- {t('execWorkflow.create.auditResult.switchDatabaseBackupPolicy')}
-
-
-
- {/* #endif */}
{
@@ -114,19 +104,16 @@ const AuditResultList: React.FC = ({
{t('execWorkflow.create.auditResult.clearDuplicate')}
-
+
{/* todo: options 中部分数据需要后端接口支持 http://10.186.18.11/jira/browse/DMS-424*/}
-
passRate={currentTask?.pass_rate}
score={currentTask?.score}
instanceSchemaName={currentTask?.instance_schema}
@@ -136,7 +123,7 @@ const AuditResultList: React.FC = ({
options={Object.keys(getAuditTaskSQLsV2FilterAuditLevelEnum)}
withAll={{
label: t('execWorkflow.create.auditResult.allLevel'),
- value: null
+ value: undefined
}}
labelDictionary={translateDictionaryI18nLabel(auditLevelDictionary)}
/>
@@ -145,15 +132,15 @@ const AuditResultList: React.FC = ({
noDuplicate={noDuplicate}
auditLevelFilterValue={auditLevelFilterValue}
projectID={projectID}
+ projectName={projectName}
updateTaskRecordCount={updateTaskRecordCount}
dbType={currentTask?.instance_db_type}
instanceName={currentTask?.instance_name}
- schema={currentTask?.instance_schema}
- allowSwitchBackupPolicy={allowSwitchBackupPolicy}
- supportedBackupPolicies={currentTaskSupportedBackupPolicies}
- updateTaskAuditRuleExceptionStatus={updateTaskAuditRuleExceptionStatus}
+ canCreateRuleException={canCreateRuleException}
+ onRuleExceptionCreated={onRuleExceptionCreated}
/>
);
};
+
export default AuditResultList;
diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/index.type.ts b/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/index.type.ts
index 7e1db61785..38a898d69f 100644
--- a/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/index.type.ts
+++ b/packages/sqle/src/page/SqlExecWorkflow/Common/AuditResultList/index.type.ts
@@ -1,20 +1,8 @@
-import {
- IAuditTaskResV1,
- IAuditTaskSQLResV2
-} from '@actiontech/shared/lib/api/sqle/service/common';
-import { InstanceTipResV2SupportedBackupStrategyEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum';
+import { IAuditTaskResV1 } from '@actiontech/shared/lib/api/sqle/service/common';
export type AuditResultListProps = {
tasks: IAuditTaskResV1[];
- updateTaskRecordCount?: (taskId: string, sqlCount: number) => void;
- updateTaskAuditRuleExceptionStatus?: (taskSqls: IAuditTaskSQLResV2[]) => void;
+ updateTaskRecordCount?: (taskId: string, sqlNumber: number) => void;
showTaskTab?: boolean;
- allowSwitchBackupPolicy?: boolean;
- onBatchSwitchBackupPolicy?: (
- currentTaskID?: string,
- supportedBackupStrategy?: InstanceTipResV2SupportedBackupStrategyEnum[]
- ) => void;
- tasksSupportedBackupPolicies?: {
- [key: number]: InstanceTipResV2SupportedBackupStrategyEnum[] | undefined;
- };
+ onRuleExceptionCreated?: () => void;
};
diff --git a/packages/sqle/src/page/Whitelist/List/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/Whitelist/List/__snapshots__/index.test.tsx.snap
index 9e75a527bd..3f011f23f9 100644
--- a/packages/sqle/src/page/Whitelist/List/__snapshots__/index.test.tsx.snap
+++ b/packages/sqle/src/page/Whitelist/List/__snapshots__/index.test.tsx.snap
@@ -4,7 +4,7 @@ exports[`slqe/Whitelist/WhitelistList should render whitelist list 1`] = `