diff --git a/packages/base/src/page/CloudBeaver/List/__snapshots__/index.test.tsx.snap b/packages/base/src/page/CloudBeaver/List/__snapshots__/index.test.tsx.snap index deda6e93d2..a9df6dfd2c 100644 --- a/packages/base/src/page/CloudBeaver/List/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/CloudBeaver/List/__snapshots__/index.test.tsx.snap @@ -181,39 +181,47 @@ exports[`test base/CloudBeaver/List filter data with search 1`] = `
-
- + @@ -572,7 +580,7 @@ exports[`test base/CloudBeaver/List filter data with search 1`] = `
-
- +
@@ -3392,7 +3400,7 @@ exports[`test base/DataExport/List render table filter items 1`] = `
-
- +
@@ -1210,7 +1218,7 @@ exports[`page/DataSource/DataSourceList render table by filter enable masking 1`
-
- +
@@ -2202,7 +2218,7 @@ exports[`page/DataSource/DataSourceList render table filter option val 1`] = `
-
- +
@@ -2095,7 +2103,7 @@ exports[`page/GlobalDataSource/List render table filter option val 1`] = `
( - `/v1/projects/${project_name}/blacklist/${blacklist_id}`, - paramsData, - options - ); - } - public deleteBlackList( params: IDeleteBlackListParams, options?: AxiosRequestConfig diff --git a/packages/shared/lib/api/sqle/service/common.d.ts b/packages/shared/lib/api/sqle/service/common.d.ts index 3d2edf02cf..dd3ae618f7 100644 --- a/packages/shared/lib/api/sqle/service/common.d.ts +++ b/packages/shared/lib/api/sqle/service/common.d.ts @@ -438,8 +438,6 @@ export interface IBlacklistResV1 { content?: string; - created_at?: string; - desc?: string; last_match_time?: string; @@ -553,10 +551,6 @@ export interface ICreateAuditWhitelistResV1 { message?: string; } -export interface ICreateBlacklistDataV1 { - blacklist_id?: number; -} - export interface ICreateBlacklistReqV1 { content?: string; @@ -565,14 +559,6 @@ export interface ICreateBlacklistReqV1 { type?: CreateBlacklistReqV1TypeEnum; } -export interface ICreateBlacklistResV1 { - code?: number; - - data?: ICreateBlacklistDataV1; - - message?: string; -} - export interface ICreateCustomRuleReqV1 { annotation?: string; @@ -995,14 +981,6 @@ export interface IGetAuditWhitelistResV1 { total_nums?: number; } -export interface IGetBlacklistDetailResV1 { - code?: number; - - data?: IBlacklistResV1; - - message?: string; -} - export interface IGetBlacklistResV1 { code?: number; @@ -1460,6 +1438,8 @@ export interface IGetSqlManageListResp { message?: string; + source_extra?: ISourceExtra; + sql_manage_bad_num?: number; sql_manage_optimized_num?: number; @@ -3527,6 +3507,38 @@ export interface IRuleTemplateV2 { name?: string; } +export interface ISourceExtra { + enabled?: boolean; + + filter_meta_list?: IFilterMeta[]; + + head?: ISourceExtraHead[]; + + rows?: ISourceExtraRow[]; + + source?: string; + + source_desc?: string; +} + +export interface ISourceExtraHead { + desc?: string; + + name?: string; + + sortable?: boolean; + + type?: string; +} + +export interface ISourceExtraRow { + id?: number; + + values?: { + [key: string]: string; + }; +} + export interface ITaskAnalysisDataV2 { performance_statistics?: IPerformanceStatistics; diff --git a/packages/shared/lib/api/sqle/service/common.enum.ts b/packages/shared/lib/api/sqle/service/common.enum.ts index 08431fe272..d73f93382e 100644 --- a/packages/shared/lib/api/sqle/service/common.enum.ts +++ b/packages/shared/lib/api/sqle/service/common.enum.ts @@ -119,9 +119,7 @@ export enum BlacklistResV1TypeEnum { host = 'host', - instance = 'instance', - - db_user = 'db_user' + instance = 'instance' } export enum CreateAuditTaskReqV1ExecModeEnum { @@ -147,9 +145,7 @@ export enum CreateBlacklistReqV1TypeEnum { host = 'host', - instance = 'instance', - - db_user = 'db_user' + instance = 'instance' } export enum CreateCustomRuleReqV1LevelEnum { @@ -365,9 +361,7 @@ export enum UpdateBlacklistReqV1TypeEnum { host = 'host', - instance = 'instance', - - db_user = 'db_user' + instance = 'instance' } export enum UpdateCustomRuleReqV1LevelEnum { diff --git a/packages/shared/lib/components/ActiontechTable/Table.tsx b/packages/shared/lib/components/ActiontechTable/Table.tsx index 5341c81ca9..94efc0d770 100644 --- a/packages/shared/lib/components/ActiontechTable/Table.tsx +++ b/packages/shared/lib/components/ActiontechTable/Table.tsx @@ -22,6 +22,7 @@ const ActiontechTable = < filterContainerProps, columns = [], isPaginationFixed = true, + disableRowHover = false, ...props }: ActiontechTableProps) => { const { t } = useTranslation(); @@ -47,11 +48,14 @@ const ActiontechTable = < return mergerColumns; } return mergerColumns - .filter((v) => localColumns?.[v.dataIndex]?.show) - .map((v) => ({ + .filter((v) => localColumns?.[v.dataIndex]?.show ?? true) + .map((v, index) => ({ ...v, - fixed: localColumns?.[v.dataIndex]?.fixed, - order: localColumns?.[v.dataIndex]?.order + fixed: localColumns?.[v.dataIndex] + ? localColumns[v.dataIndex].fixed + : v.fixed, + // 尚未写入 localStorage 的动态列沿用 mergerColumns 下标,避免 order 为 0 被排到最前 + order: localColumns?.[v.dataIndex]?.order ?? index + 1 })) .sort((prev, current) => prev.order - current.order); }, [localColumns, mergerColumns, props.setting]); @@ -73,7 +77,9 @@ const ActiontechTable = <
>({
-
+
- {getColumnsLabel(data.title)} + {data.settingMarked ? ( + + {getColumnsLabel(data.title)} + + ) : ( + getColumnsLabel(data.title) + )}
diff --git a/packages/shared/lib/components/ActiontechTable/components/FilterButton.tsx b/packages/shared/lib/components/ActiontechTable/components/FilterButton.tsx index ef25536833..bff78cc991 100644 --- a/packages/shared/lib/components/ActiontechTable/components/FilterButton.tsx +++ b/packages/shared/lib/components/ActiontechTable/components/FilterButton.tsx @@ -2,6 +2,7 @@ import { TableFilterButtonProps } from '../index.type'; import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import BasicButton from '../../BasicButton'; +import BasicToolTips from '../../BasicToolTips'; import { DownOutlined, UpOutlined } from '@actiontech/icons'; import { ColumnsSettingStyleWrapper } from './style'; @@ -18,27 +19,35 @@ const FilterButton = >({ ); return ( - updateAllSelectedFilterItem(!hasSelectedFilter)} - style={{ - padding: '0 6px 0 10px' - }} + - - {hasSelectedFilter - ? t('common.actiontechTable.filterButton.clearFilter') - : t('common.actiontechTable.filterButton.filter')} + updateAllSelectedFilterItem(!hasSelectedFilter)} + style={{ + padding: '0 6px 0 10px' + }} + > + + {hasSelectedFilter + ? t('common.actiontechTable.filterButton.clearFilter') + : t('common.actiontechTable.filterButton.filter')} - {hasSelectedFilter ? ( - - ) : ( - - )} - - + {hasSelectedFilter ? ( + + ) : ( + + )} + + + ); }; diff --git a/packages/shared/lib/components/ActiontechTable/components/style.ts b/packages/shared/lib/components/ActiontechTable/components/style.ts index d5260d528e..1e48b70a23 100644 --- a/packages/shared/lib/components/ActiontechTable/components/style.ts +++ b/packages/shared/lib/components/ActiontechTable/components/style.ts @@ -30,7 +30,7 @@ export const SearchInputStyleWrapper = styled(BasicInput)` `; export const ColumnsSettingDropdownStyleWrapper = styled('div')` - width: 220px; + width: 280px; background-color: ${({ theme }) => theme.sharedTheme.components.columnsSetting.dropdown.backgroundColor}; border-radius: 8px; @@ -93,6 +93,23 @@ export const ColumnsSettingDropdownStyleWrapper = styled('div')` theme.sharedTheme.components.columnsSetting.dropdown.item.iconColor}; } + .actiontech-table-setting-extra-mark { + position: relative; + display: inline-block; + padding-right: 0.55em; + max-width: 100%; + + &::after { + content: '*'; + position: absolute; + top: 0.2em; + right: 0; + font-size: 12px; + line-height: 1; + color: ${({ theme }) => theme.sharedTheme.uiToken.colorPrimary}; + } + } + &-label { font-weight: 500; font-size: 13px; diff --git a/packages/shared/lib/components/ActiontechTable/components/test/__snapshots__/ColumnsItems.test.tsx.snap b/packages/shared/lib/components/ActiontechTable/components/test/__snapshots__/ColumnsItems.test.tsx.snap index 67cb00f2d6..9e0d285487 100644 --- a/packages/shared/lib/components/ActiontechTable/components/test/__snapshots__/ColumnsItems.test.tsx.snap +++ b/packages/shared/lib/components/ActiontechTable/components/test/__snapshots__/ColumnsItems.test.tsx.snap @@ -42,7 +42,7 @@ exports[`lib/ActiontechTable-ColumnsItems render column item left | right 1`] =
-
- +
`; @@ -43,39 +51,47 @@ exports[`lib/ActiontechTable-FilterButton render click filter btn 1`] = ` exports[`lib/ActiontechTable-FilterButton render click filter btn 2`] = `
-
- +
`; diff --git a/packages/shared/lib/components/ActiontechTable/hooks/useTableFilterContainer.tsx b/packages/shared/lib/components/ActiontechTable/hooks/useTableFilterContainer.tsx index 417f93587e..cf40e5f692 100644 --- a/packages/shared/lib/components/ActiontechTable/hooks/useTableFilterContainer.tsx +++ b/packages/shared/lib/components/ActiontechTable/hooks/useTableFilterContainer.tsx @@ -48,10 +48,14 @@ export const mergeFilterButtonMeta = < // #if [DEV] if ( - Array.from(map).some( - ([_, value]) => - value.filterLabel === '' && value.filterCustomType !== 'search-input' - ) + Array.from(map).some(([_, value]) => { + const label = value.filterLabel; + const isEmptyLabel = + label == null || + label === '' || + (typeof label === 'string' && label.trim() === ''); + return isEmptyLabel && value.filterCustomType !== 'search-input'; + }) ) { throw new Error('Filter label cannot be empty'); } diff --git a/packages/shared/lib/components/ActiontechTable/hooks/useTableSettings.tsx b/packages/shared/lib/components/ActiontechTable/hooks/useTableSettings.tsx index ff1a4045ba..428c49a36d 100644 --- a/packages/shared/lib/components/ActiontechTable/hooks/useTableSettings.tsx +++ b/packages/shared/lib/components/ActiontechTable/hooks/useTableSettings.tsx @@ -9,6 +9,164 @@ import EmitterKey from '../../../data/EmitterKey'; import { getColumnsLabel } from '../utils'; import LocalStorageWrapper from '../../../utils/LocalStorageWrapper'; import { isEqual } from 'lodash'; +import { ACTIONTECH_TABLE_OPERATOR_COLUMN_DATA_INDEX } from './useTableAction'; + +/** + * 仅用于「首次写入」默认列配置:保证操作列 order 在最后。 + * 用户已有缓存时不要调用,以免覆盖用户调整过的操作列位置。 + */ +const ensureOperatorColumnLast = < + T extends Record, + OtherColumnKeys extends string = '' +>( + columnsRecord: CatchTableColumnValueType +): CatchTableColumnValueType => { + const operatorColumn = + columnsRecord[ + ACTIONTECH_TABLE_OPERATOR_COLUMN_DATA_INDEX as keyof typeof columnsRecord + ]; + if (!operatorColumn) { + return columnsRecord; + } + + const maxOtherOrder = Object.entries(columnsRecord).reduce( + (max, [key, value]) => { + if (key === ACTIONTECH_TABLE_OPERATOR_COLUMN_DATA_INDEX) { + return max; + } + return Math.max(max, value?.order ?? 0); + }, + 0 + ); + + if ((operatorColumn.order ?? 0) > maxOtherOrder) { + return columnsRecord; + } + + return { + ...columnsRecord, + [ACTIONTECH_TABLE_OPERATOR_COLUMN_DATA_INDEX]: { + ...operatorColumn, + order: maxOtherOrder + 1 + } + }; +}; + +/** + * 动态新增列首次写入时:插在当前操作列之前(或数据列末尾)。 + * 会平移操作列及之后列的 order,但不会把操作列强行拽到全局最后 + *(若用户已把操作列挪到中间,相对位置保持)。 + */ +const assignOrdersForNewColumns = < + T extends Record, + OtherColumnKeys extends string = '' +>( + columnsRecord: CatchTableColumnValueType, + newDataIndexes: string[] +): CatchTableColumnValueType => { + const newNonOperatorIndexes = newDataIndexes.filter( + (key) => key !== ACTIONTECH_TABLE_OPERATOR_COLUMN_DATA_INDEX + ); + if (newNonOperatorIndexes.length === 0) { + return columnsRecord; + } + + const operatorColumn = + columnsRecord[ + ACTIONTECH_TABLE_OPERATOR_COLUMN_DATA_INDEX as keyof typeof columnsRecord + ]; + const newDataIndexSet = new Set(newNonOperatorIndexes); + const shiftCount = newNonOperatorIndexes.length; + + let insertAt: number; + if (typeof operatorColumn?.order === 'number') { + insertAt = operatorColumn.order; + } else { + const maxExistingOrder = Object.entries(columnsRecord).reduce( + (max, [key, value]) => { + if (newDataIndexSet.has(key)) { + return max; + } + return Math.max(max, value?.order ?? 0); + }, + 0 + ); + insertAt = maxExistingOrder + 1; + } + + const nextRecord = { ...columnsRecord }; + + if (typeof operatorColumn?.order === 'number') { + Object.keys(nextRecord).forEach((key) => { + if (newDataIndexSet.has(key)) { + return; + } + const col = nextRecord[key as keyof typeof nextRecord]; + if (col && (col.order ?? 0) >= insertAt) { + nextRecord[key as keyof typeof nextRecord] = { + ...col, + order: (col.order ?? 0) + shiftCount + }; + } + }); + } + + newNonOperatorIndexes.forEach((dataIndex, i) => { + const col = nextRecord[dataIndex as keyof typeof nextRecord]; + if (col) { + nextRecord[dataIndex as keyof typeof nextRecord] = { + ...col, + order: insertAt + i + }; + } + }); + + return nextRecord; +}; + +/** settingMarked 仅在 true 时持久化;缺失与 false 视为等价,避免 localStorage 反复重写 */ +const omitFalseSettingMarked = < + T extends Record, + OtherColumnKeys extends string = '' +>( + columnsRecord: CatchTableColumnValueType +): CatchTableColumnValueType => { + const nextRecord = { ...columnsRecord }; + + Object.keys(nextRecord).forEach((key) => { + const col = nextRecord[key as keyof typeof nextRecord]; + if (!col?.settingMarked) { + const { settingMarked: _removed, ...rest } = col ?? {}; + nextRecord[key as keyof typeof nextRecord] = rest as typeof col; + } + }); + + return nextRecord; +}; + +const buildColumnCacheEntry = < + T extends Record, + OtherColumnKeys extends string = '' +>( + column: CatchTableColumnValueType[string] | undefined, + defaults: Partial[string]>, + title: string, + settingMarked?: boolean +): CatchTableColumnValueType[string] => { + const entry = { + ...column, + ...defaults, + title + } as CatchTableColumnValueType[string]; + + if (settingMarked) { + entry.settingMarked = true; + } else if (entry.settingMarked !== true) { + delete entry.settingMarked; + } + + return entry; +}; const useTableSettings = < T extends Record, @@ -37,36 +195,65 @@ const useTableSettings = < const localData = localStr ? JSON.parse(localStr) : undefined; if (localData?.[username]) { const localColumnsRecord = localData?.[username]; + const newDataIndexes: string[] = []; const newColumnsRecord = defaultColumns.reduce( (acc, cur, index) => { if (localColumnsRecord[cur.dataIndex]) { return { ...acc, - [cur.dataIndex]: { - ...localColumnsRecord[cur.dataIndex], - title: getColumnsLabel(cur.title) - } + [cur.dataIndex]: buildColumnCacheEntry( + localColumnsRecord[cur.dataIndex], + {}, + getColumnsLabel(cur.title), + cur.settingMarked + ) }; } + newDataIndexes.push(String(cur.dataIndex)); return { ...acc, - [cur.dataIndex]: { - order: index + 1, - show: cur.show ?? true, - fixed: cur?.fixed, - title: getColumnsLabel(cur.title) - } + [cur.dataIndex]: buildColumnCacheEntry( + undefined, + { + order: index + 1, + show: cur.show ?? true, + fixed: cur?.fixed + }, + getColumnsLabel(cur.title), + cur.settingMarked + ) }; }, {} as CatchTableColumnValueType ); - if (isEqual(newColumnsRecord, localColumnsRecord)) { + let normalizedColumnsRecord = assignOrdersForNewColumns( + newColumnsRecord, + newDataIndexes + ); + + // 操作列本身是首次出现时,默认仍放最后 + if ( + newDataIndexes.includes( + ACTIONTECH_TABLE_OPERATOR_COLUMN_DATA_INDEX + ) + ) { + normalizedColumnsRecord = ensureOperatorColumnLast( + normalizedColumnsRecord + ); + } + + if ( + isEqual( + omitFalseSettingMarked(normalizedColumnsRecord), + omitFalseSettingMarked(localColumnsRecord) + ) + ) { return; } const data: CatchTableColumnsType = { ...localData, - [username]: newColumnsRecord + [username]: normalizedColumnsRecord }; eventEmitter.emit( @@ -78,19 +265,25 @@ const useTableSettings = < return; } const columnsInfo: CatchTableColumnValueType = - defaultColumns.reduce< - CatchTableColumnValueType - >((acc, cur, index) => { - return { - ...acc, - [cur.dataIndex]: { - order: index + 1, - show: cur.show ?? true, - fixed: cur?.fixed, - title: getColumnsLabel(cur.title) - } - }; - }, {} as CatchTableColumnValueType); + ensureOperatorColumnLast( + defaultColumns.reduce< + CatchTableColumnValueType + >((acc, cur, index) => { + return { + ...acc, + [cur.dataIndex]: buildColumnCacheEntry( + undefined, + { + order: index + 1, + show: cur.show ?? true, + fixed: cur?.fixed + }, + getColumnsLabel(cur.title), + cur.settingMarked + ) + }; + }, {} as CatchTableColumnValueType) + ); const data: CatchTableColumnsType = localData ? { ...localData, [username]: columnsInfo } diff --git a/packages/shared/lib/components/ActiontechTable/index.type.ts b/packages/shared/lib/components/ActiontechTable/index.type.ts index 78f8eef84d..3e07438c04 100644 --- a/packages/shared/lib/components/ActiontechTable/index.type.ts +++ b/packages/shared/lib/components/ActiontechTable/index.type.ts @@ -148,9 +148,9 @@ export type ActiontechTableFilterMetaValue< filterKey?: keyof F | Array; /** - * 筛选项的 label + * 筛选项的 label(支持自定义节点,如动态筛选项标记) */ - filterLabel?: string; + filterLabel?: ReactNode; }; /** @@ -225,6 +225,11 @@ export type CatchTableColumnValueType< * 表头名, 通 columns 中的 title, 如果 columns 中的 title 为 ReactNode, 会使用 utils 中的 getColumnsLabel 来获取中文 */ title: string; + + /** + * 列设置中是否展示扩展标记(如蓝色 *),与表头扩展列标识对齐 + */ + settingMarked?: boolean; }; }; @@ -338,6 +343,10 @@ export type ActiontechTableColumn< { [K in keyof Required]: { show?: boolean; + /** + * 列设置面板中是否展示扩展标记(如蓝色 *) + */ + settingMarked?: boolean; dataIndex: ExcludeSymbol; render?: ( value: K | OtherColumnKeys extends keyof T ? T[K] : never, @@ -395,4 +404,9 @@ export interface ActiontechTableProps< * 控制表格的分页器是否固定于页面底部,默认为true,固定在页面底部,注意:只有在表格有pagination时,设置isPaginationFixed才有意义 */ isPaginationFixed?: boolean; + + /** + * 禁用表格行 hover 时的背景色变化(sticky 操作列场景下避免左侧内容透出) + */ + disableRowHover?: boolean; } diff --git a/packages/shared/lib/components/ActiontechTable/style.tsx b/packages/shared/lib/components/ActiontechTable/style.tsx index 9fe80cb894..0a5c9b4b45 100644 --- a/packages/shared/lib/components/ActiontechTable/style.tsx +++ b/packages/shared/lib/components/ActiontechTable/style.tsx @@ -70,6 +70,18 @@ export const ActiontechTableStyleWrapper = styled(Table)` } } + /* sticky 操作列使用不透明背景,避免横向滚动时左侧单元格内容透出 */ + .ant-table-thead + > tr + > th.${ACTIONTECH_TABLE_OPERATOR_COLUMN_CLS}, + .ant-table-tbody + > tr + > td.${ACTIONTECH_TABLE_OPERATOR_COLUMN_CLS} { + background-color: ${({ theme }) => + theme.sharedTheme.uiToken.colorBgBase} !important; + z-index: 2; + } + .ant-checkbox-wrapper { .ant-checkbox { .ant-checkbox-inner { @@ -181,4 +193,13 @@ export const ActiontechTableStyleWrapper = styled(Table)` &.ant-table-wrapper.actiontech-table-namespace.clear-padding-bottom { padding-bottom: 0; } + + /* opt-in:取消整行 hover 底色变化(含 sticky 操作列),避免 sticky 列透出 */ + &.ant-table-wrapper.actiontech-table-namespace.disable-row-hover { + .ant-table-tbody > tr.ant-table-row:hover > td, + .ant-table-tbody > tr > td.ant-table-cell-row-hover { + background-color: ${({ theme }) => + theme.sharedTheme.uiToken.colorBgBase} !important; + } + } `; diff --git a/packages/shared/lib/components/BasicTable/__snapshots__/index.test.tsx.snap b/packages/shared/lib/components/BasicTable/__snapshots__/index.test.tsx.snap index dc4b661248..99ea9418e2 100644 --- a/packages/shared/lib/components/BasicTable/__snapshots__/index.test.tsx.snap +++ b/packages/shared/lib/components/BasicTable/__snapshots__/index.test.tsx.snap @@ -3,7 +3,7 @@ exports[`lib/BasicTable render custom pagination for table 1`] = `
-
- +
@@ -357,7 +365,7 @@ exports[`sqle/OperationRecord/List render action when filter item show 1`] = `
-
- +
@@ -411,7 +419,7 @@ exports[`sqle/SqlAudit/List render action when filter item show 1`] = `
- + + + + + + + + + + - + scope="col" + > + 审核ID + + + 数据源 + + + 审核状态 + + + 业务标签 + + + 审核评分 + + + 审核通过率(%) + + + 创建人 + + + 审核时间 + + +
+   +
+ + +
+   +
+ + +
+   +
+ + +
+   +
+ + +
+   +
+ + +
+   +
+ + +
+   +
+
ActiontechTableFilterMeta< diff --git a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/ModifySqlStatement/__tests__/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/ModifySqlStatement/__tests__/__snapshots__/index.test.tsx.snap index def1b3fae2..473956b911 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/ModifySqlStatement/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/ModifySqlStatement/__tests__/__snapshots__/index.test.tsx.snap @@ -713,7 +713,7 @@ exports[`sqle/ExecWorkflow/Detail/ModifySqlStatement render snap when click form
-
- SQL管控 -
-
- + + + + + + 导出报表 + + +
-
-
- - 0 - - - SQL总数 - -
-
-
0 - 问题SQL数 + SQL总数
-
-
- - 0 - - + + 0 + + + 问题SQL数 + +
+
+
- 已优化SQL数 - + + 0 + + + 已优化SQL数 + +
-
-
- - - - - + +
+ 已人工审核 +
+ +
-
-
- - - - - - - -
-
-
- + +
-
-
- -
-
- +
+
- - 与我相关 - - -
-
- +
+
- - 批量指派 - - -
-
- +
+
- - 批量解决 - - -
-
- +
+
- - 批量忽略 - - + +
-
-
-
-
- -
-
- + + +
-
-
- - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + - + - + - - - - - - - - - + + + + + + + + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - -
-
+
- - - - SQL指纹 - - SQL - - 来源 - - 最初审核结果 - - 当前审核结果 - - 数据源 - - Schema - - 优先级 - -
+ + + + +
+
- - 出现数量 - - + + SQL + + 来源 + + 最初审核结果 + + 当前审核结果 + + 数据源 + + Schema + + 优先级 + +
+ - - + + - - + + - -
-
-
+
- - 初次出现时间 - - + - - + + - - + + - - - -
+
- - 最后一次出现时间 - - + - - + + - - + + - - - - 负责人 - - 端点信息 - - 状态 - - 备注 - - 操作 -
-
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - -
-
-
+
+   +
+ + + + +
+ + + + +
@@ -974,7 +978,7 @@ exports[`page/SqlManagement render sql management page 1`] = `
-
+
diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/__snapshots__/index.test.tsx.snap index 79e572562f..11551a96d3 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/__snapshots__/index.test.tsx.snap @@ -3,1518 +3,1493 @@ exports[`page/SqlManagement/SQLEEIndex filter data with rule name 1`] = `
-
- SQL管控 -
-
-
+
- - - - - - - 导出报表 - - + + + + + + 导出报表 + + +
-
-
- - 2 - - - SQL总数 - -
-
-
- 1 + 2 - 问题SQL数 + SQL总数
-
-
- - 1 - - + + 1 + + + 问题SQL数 + +
+
+
- 已优化SQL数 - + + 1 + + + 已优化SQL数 + +
-
-
- - - - - + +
+ 已人工审核 +
+ +
-
-
- - - - - - - -
-
-
- +
-
-
- -
-
- -
-
- -
-
- -
-
- +
+
- - 批量忽略 - - -
-
-
-
- +
- - - + + 批量指派 + +
- 表格设置 +
+ +
+
+
+
+ +
+
+
-
- -
-
- + + +
-
-
- - - - + + + - 业务 - - - 请选择{{name}} + + 业务 + + + 请选择{{name}} + - +
+
-
-
-
- - - - + + + - 数据源 - - - 请选择{{name}} + + 数据源 + + + 请选择{{name}} + - +
+
-
-
-
- - - - + + + - 来源 - - - 请选择{{name}} + + 来源 + + + 请选择{{name}} + - +
+
-
-
-
- - - - + + + - 最低审核等级 - - - 请选择{{name}} + + 最低审核等级 + + + 请选择{{name}} + - +
+
-
-
-
- -
-
- - - -
-
- +
+ + + +
+
+ +
+
-
-
- - 时间范围 + + 时间范围 + - +
-
-
- - - - + + + - 审核规则 - - - 请选择{{name}} + + 审核规则 + + + 请选择{{name}} + - +
+
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - + - + - - - - - - - - - + + + + + + + + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + + - - - - - + + + - - - - - - - + + + + + + - - - + + - + - - -
-
+
- - - - SQL指纹 - - SQL - - 来源 - - 最初审核结果 - - 当前审核结果 - - 数据源 - - Schema - - 优先级 - -
+ + + + +
+
+ SQL指纹 + + SQL + + 来源 + + 最初审核结果 + + 当前审核结果 + + 数据源 + + Schema + + 优先级 + - - 出现数量 - - + - - - + + + - - - -
+
- - 初次出现时间 - - + - - + + - - + + - - - -
+
- - 最后一次出现时间 - - + - - + + - - + + - - - - 负责人 - - 端点信息 - - 状态 - - 备注 - - 操作 -
-
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - - -
+   +
+
-   - -
+   + +
- - - - - - - - -
+ + + + +
+ + + - + + - +
- - - - - × - 2 + + + + + × + 2 + - +
- -
- mysql - - dms - - 高优先 - - 0 - - 2024-01-02 11:28:34 - - 2024-01-03 11:28:34 - -
+
+ mysql + + dms + + 高优先 + + 0 + + 2024-01-02 11:28:34 + + 2024-01-03 11:28:34 +
- - T + + T + - +
- -
- + - 12 - - - - 未处理 - - -
- this is remark text -
- - - -
+
+ +
+ this is remark text
- -
-
- +
- -
-
- +
+
- - 变更状态 - - + +
- - - -
+ + + + + +
+ + + + +
-
-
    -
  • - - 共 2 条数据 - -
  • -
  • - -
  • -
  • - - 1 - -
  • -
  • - -
  • -
  • -
  • -
    - - - - 20 / page + -
    -
  • +
  • + + 1 + +
  • +
  • +
- - + + +
  • + +
  • + +
    -
    +
    -
    - SQL管控 -
    -
    - + + + + + + 导出报表 + + +
    -
    -
    - - 0 - - + 0 + + + SQL总数 + +
    +
    +
    + + 0 + + + 问题SQL数 + +
    +
    +
    - SQL总数 - -
    -
    -
    0 - 问题SQL数 + 已优化SQL数
    -
    - - 0 - - - 已优化SQL数 - -
    -
    -
    - - - - - + +
    + 已人工审核 +
    + +
    -
    -
    - - - - - - - -
    -
    -
    - + +
    -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - +
    +
    - - 批量忽略 - - -
    -
    -
    -
    - +
    - - - + + 批量指派 + +
    - 表格设置 +
    + +
    +
    +
    +
    + +
    +
    +
    -
    - -
    -
    - + + +
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - + - + - - - - - - - - - + + + + + + + + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + + -
    - -
    - -
    -
    +
    - - - - SQL指纹 - - SQL - - 来源 - - 最初审核结果 - - 当前审核结果 - - 数据源 - - Schema - - 优先级 - -
    + + + + +
    +
    + SQL指纹 + + SQL + + 来源 + + 最初审核结果 + + 当前审核结果 + + 数据源 + + Schema + + 优先级 + - - 出现数量 - - + - - + + - - + + - - - -
    +
    - - 初次出现时间 - - + - - + + - - + + - - - -
    +
    - - 最后一次出现时间 - - + - - + + - - + + - - - - 负责人 - - 端点信息 - - 状态 - - 备注 - - 操作 -
    -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - -
    +   + +
    + +
    + + + + +
    @@ -2925,7 +2941,7 @@ exports[`page/SqlManagement/SQLEEIndex filter data with sort 1`] = `
    -
    +
    `; @@ -2933,969 +2949,973 @@ exports[`page/SqlManagement/SQLEEIndex filter data with sort 1`] = ` exports[`page/SqlManagement/SQLEEIndex render sql statics data 1`] = `
    -
    - SQL管控 -
    -
    -
    +
    - - - - - - - 导出报表 - - + + + + + + 导出报表 + + +
    -
    -
    - - 0 - - - SQL总数 - -
    -
    -
    0 - 问题SQL数 + SQL总数
    -
    -
    - - 0 - - + + 0 + + + 问题SQL数 + +
    +
    +
    - 已优化SQL数 - + + 0 + + + 已优化SQL数 + +
    -
    -
    - - - - - + +
    + 已人工审核 +
    + +
    -
    -
    - - - - - - - -
    -
    -
    - + +
    -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - +
    +
    - - 批量忽略 - - -
    -
    -
    -
    - +
    - - - + + 批量指派 + +
    - 表格设置 +
    + +
    +
    +
    +
    + +
    +
    +
    -
    - -
    -
    - + + +
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - + - + - - - - - - - - - + + + + + + + + + - - + - + - + - + - + - + - + - + - + - + + - + - + - + - + - + - + + -
    -   -
    - - - - - - -
    -
    +
    - - - - SQL指纹 - - SQL - - 来源 - - 最初审核结果 - - 当前审核结果 - - 数据源 - - Schema - - 优先级 - -
    + + + + +
    +
    + SQL指纹 + + SQL + + 来源 + + 最初审核结果 + + 当前审核结果 + + 数据源 + + Schema + + 优先级 + - - 出现数量 - - + - - + + - - + + - - - -
    +
    - - 初次出现时间 - - + - - + + - - + + - - - -
    +
    - - 最后一次出现时间 - - + - - + + - - + + - - - - 负责人 - - 端点信息 - - 状态 - - 备注 - - 操作 -
    -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    +
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - +   + +
    -
    -
    +
    + + + + +
    @@ -3903,7 +3923,7 @@ exports[`page/SqlManagement/SQLEEIndex render sql statics data 1`] = `
    -
    +
    `; @@ -3911,1158 +3931,1125 @@ exports[`page/SqlManagement/SQLEEIndex render sql statics data 1`] = ` exports[`page/SqlManagement/SQLEEIndex render table data 1`] = `
    -
    - SQL管控 -
    -
    -
    +
    - - - - - - - 导出报表 - - + + + + + + 导出报表 + + +
    -
    -
    - - 2 - - - SQL总数 - -
    -
    -
    - 1 + 2 - 问题SQL数 + SQL总数
    -
    -
    - - 1 - - + + 1 + + + 问题SQL数 + +
    +
    +
    - 已优化SQL数 - + + 1 + + + 已优化SQL数 + +
    -
    -
    - - - - - + +
    + 已人工审核 +
    + +
    -
    -
    - - - - - - - -
    -
    -
    - + +
    -
    -
    - -
    -
    - -
    -
    - -
    -
    - +
    +
    - - 批量解决 - - -
    -
    - +
    +
    - - 批量忽略 - - -
    -
    -
    -
    - +
    - - - + + 批量解决 + +
    - 表格设置 + +
    +
    +
    +
    +
    -
    - -
    -
    - + + +
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - + - + - - - - - - - - - + + + + + + + + + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + + + - - - - - + + + - - - - - - - + + + + + + - - - + + - - - - - + + + - - - - - - - - - - + - - - - + + + + + + + + + + + + - - - - + + - + + - - - + + - - - - - - - - - - + + + + + + + + - - - - - + + - + + - - - + + - - - - - - - - - - + + + + + + + - + - - - - - + + - - - + - - - - - - - - - - + - + + + + + + + + + + - - -
    -
    +
    - - - - SQL指纹 - - SQL - - 来源 - - 最初审核结果 - - 当前审核结果 - - 数据源 - - Schema - - 优先级 - -
    + + + + +
    +
    + SQL指纹 + + SQL + + 来源 + + 最初审核结果 + + 当前审核结果 + + 数据源 + + Schema + + 优先级 + - - 出现数量 - - + - - + + - - + + - - - -
    +
    - - 初次出现时间 - - + - - + + - - + + - - - -
    +
    - - 最后一次出现时间 - - + - - + + - - + + - - - - 负责人 - - 端点信息 - - 状态 - - 备注 - - 操作 -
    -
    -   -
    -
    -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - -
    +   + + +
    +   +
    +
    - - - - - - - - -
    + + + + +
    + + + - + + - +
    - - - - - × - 2 + + + + + × + 2 + - +
    - -
    - mysql - - dms - - 高优先 - - 0 - - 2024-01-02 11:28:34 - - 2024-01-03 11:28:34 - -
    +
    + mysql + + dms + + 高优先 + + 0 + + 2024-01-02 11:28:34 + + 2024-01-03 11:28:34 +
    - - T + + T + - +
    - -
    - - 12 - - - - 未处理 - - -
    +
    - this is remark text -
    - - - -
    +
    + +
    + this is remark text
    - - - -
    - -
    -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    - - -
    -
    - - - CREATE - - - - TABLE - - \`plugins\` ( - \`name\` - - varchar - - ( - - 200 - - ) - - COLLATE - - utf8mb4_unicode_ci - - NOT - - - - NULL - - -) ENGINE + + +
    + +
    + + +
    +
    +
    +
    - = - - utf8mb4 - + + 指派负责人 + + +
    +
    - COLLATE - + +
    +
    +
    -
    +
    + - - - 慢日志 - - - - - - - - - - - - - - - 低优先 - - 0 - - - - - - - -
    +
    - + - T + CREATE + + + + TABLE + + \`plugins\` ( + \`name\` + + varchar + + ( + + 200 + + ) + + COLLATE + + utf8mb4_unicode_ci + + NOT + + + + NULL + + +) ENGINE + + = + + InnoDB + + DEFAULT + + CHARSET + + = + + utf8mb4 + + COLLATE + + = + + utf8mb4_unicode_ci
    -
    -
    - + +
    - -
    - - - - - - - + - - - - - - - -
    +
    + - + + - + + - + + - + + 低优先 + + 0 + + - + + - +
    - +
    - +
    +
    + - + + - + - -
    - - -
    +
    - - - CREATE - - - - TABLE - - \`projects\` ( - - - UNIQUE - - KEY \`name\` (\`name\`) -) ENGINE - - = - - InnoDB - - DEFAULT - - CHARSET - +
    - = - - utf8mb4 - + + 指派负责人 + + +
    +
    - COLLATE - + +
    +
    + -
    +
    + -
    +
    - - - CREATE - - - - TABLE - - \`projects\` ( +
    + + + CREATE + + + + TABLE + + \`projects\` ( - - UNIQUE - - KEY \`name\` (\`name\`) + + UNIQUE + + KEY \`name\` (\`name\`) ) ENGINE - - = - - InnoDB - - DEFAULT - - CHARSET - - = - - utf8mb4 - - COLLATE + + = + + InnoDB + + DEFAULT + + CHARSET + + = + + utf8mb4 + + COLLATE + + + = + + utf8mb4_unicode_ci +
    +
    - = + - utf8mb4_unicode_ci - +
    +
    - - + CREATE + + + + TABLE + + \`projects\` ( + + + UNIQUE + + KEY \`name\` (\`name\`) +) ENGINE + + = + + InnoDB + + DEFAULT + + CHARSET + + = + + utf8mb4 + + COLLATE + + + = + + utf8mb4_unicode_ci + +
    +
    + - - - + + +
    - -
    - - 慢日志 - - - - - -
    +
    + + 慢日志 + + + - +
    - - - - - × - 1 + + + + + × + 1 + - +
    - -
    - mysql - - dms - - - - - 0 - - - - - - - - - - - - - - - 未处理 - - - + mysql + + dms + + - + + 0 + + - + + - + + - + + - + - - - + 未处理 - - -
    +
    -
    -
    - -
    -
    - -
    -
    - -
    - - -
    +
    - - - CREATE - - - - TABLE - - \`projects\` ( - - - UNIQUE - - KEY \`name\` (\`name\`) -) ENGINE - - = - - InnoDB - - DEFAULT - - CHARSET - +
    - = - - utf8mb4 - + + 指派负责人 + + +
    +
    - COLLATE - + +
    +
    + -
    +
    + -
    +
    - - - CREATE - - - - TABLE - - \`projects\` ( +
    + + + CREATE + + + + TABLE + + \`projects\` ( - - UNIQUE - - KEY \`name\` (\`name\`) + + UNIQUE + + KEY \`name\` (\`name\`) ) ENGINE - - = - - InnoDB - - DEFAULT - - CHARSET - - = - - utf8mb4 - - COLLATE + + = + + InnoDB + + DEFAULT + + CHARSET + + = + + utf8mb4 + + COLLATE + + + = + + utf8mb4_unicode_ci +
    +
    - = + - utf8mb4_unicode_ci - +
    +
    - - + CREATE + + + + TABLE + + \`projects\` ( + + + UNIQUE + + KEY \`name\` (\`name\`) +) ENGINE + + = + + InnoDB + + DEFAULT + + CHARSET + + = + + utf8mb4 + + COLLATE + + + = + + utf8mb4_unicode_ci + +
    +
    + - - - + + +
    - -
    - - 慢日志 - - - - - -
    +
    + + 慢日志 + + + - +
    - - - - - × - 1 + + + + + × + 1 + - +
    - -
    - mysql - - dms - - - - - 0 - - - - - - - - - - - - 34 - - - - 未处理 - - - + mysql + + dms + + - + + 0 + + - + + - + + - + - - - + 34 - - -
    +
    -
    -
    - -
    -
    - -
    -
    + 未处理 + +
    - -
    - - -
    +
    - - - SELECT - - ? - -
    -
    - - - -
    - -
    -
    -
    - - + + 指派负责人 + + +
    +
    - SELECT - - + +
    +
    + -
    +
    + - - SQL审核 - - - - - -
    +
    -
    + - - - + SELECT - +
    +
    + + -
    + + +
    - -
    - MYSQL_3307 - - db1 - - - - - 0 - - - - - - - -
    +
    - + - T + SELECT + + + + 1 + ;
    -
    -
    - + +
    - -
    - - - - + - 未处理 - - - - + +
    - - - - - -
    -
    +
    + + + + + + + 审核通过 + +
    +
    + + +
    + MYSQL_3307 + + db1 + + - + + 0 + + - + + - +
    - +
    - +
    +
    + - + + + 未处理 + + - -
    + + +
    +
    +
    + +
    +
    + +
    +
    + +
    + + + + +
    -
    -
      -
    • - - 共 2 条数据 - -
    • -
    • - -
    • -
    • - - 1 - -
    • -
    • - -
    • -
    • -
    • -
      - - - - 20 / page + -
      -
    • +
    • + + 1 + +
    • +
    • +
    - - + + +
  • + +
  • + +
    -
    +
    `; @@ -6801,1122 +6825,1083 @@ exports[`page/SqlManagement/SQLEEIndex render table for not admin 1`] = ` tab-index="-1" />
    -
    - SQL管控 -
    -
    - + + + + + + 导出报表 + + +
    -
    -
    - - 2 - - - SQL总数 - -
    -
    -
    - 1 + 2 - 问题SQL数 + SQL总数
    -
    -
    - - 1 - - + + 1 + + + 问题SQL数 + +
    +
    +
    - 已优化SQL数 - + + 1 + + + 已优化SQL数 + +
    -
    -
    - - - - - + +
    + 已人工审核 +
    + +
    -
    -
    - - - - - - - -
    -
    - -
    -
    -
    -
    -
    -
    + + +
    -
    - -
    -
    - -
    +
    + 筛选 +
    +
    + + + +
    +
    +
    +
    +
    -
    - 表格设置 +
    +
    +
    +
    + +
    +
    +
    -
    - -
    -
    - + + +
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - - + + + + + + + + + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - + + - - - - - + + + - - - - - - - + + + + + + - - - + + - + - - -
    -
    - -
    -
    - SQL指纹 - - SQL - - 来源 - - 最初审核结果 - - 当前审核结果 - - 数据源 - - Schema - - 优先级 - -
    +
    - - 出现数量 - - - + SQL指纹 + + SQL + + 来源 + + 最初审核结果 + + 当前审核结果 + + 数据源 + + Schema + + 优先级 + +
    + + 出现数量 + + + + + - -
    -
    -
    +
    - - 初次出现时间 - - + - - + + - - + + - - - -
    +
    - - 最后一次出现时间 - - + - - + + - - + + - - - - 负责人 - - 端点信息 - - 状态 - - 备注 - - 操作 -
    -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - - -
    +   +
    +
    -   - -
    +   + +
    - - - - - - - - -
    + + + + +
    + + + - + + - +
    - - - - - × - 2 + + + + + × + 2 + - +
    - -
    - mysql - - dms - - 高优先 - - 0 - - 2024-01-02 11:28:34 - - 2024-01-03 11:28:34 - -
    +
    + mysql + + dms + + 高优先 + + 0 + + 2024-01-02 11:28:34 + + 2024-01-03 11:28:34 +
    - - T + + T + - +
    - -
    - - 12 - - - - 未处理 - - -
    +
    - this is remark text -
    - - - -
    +
    + +
    + this is remark text
    - -
    -
    - +
    -
    -
    - -
    -
    + + + + + +
    + + + + +
    -
    -
      -
    • - - 共 2 条数据 - -
    • -
    • - -
    • -
    • - - 1 - -
    • -
    • - -
    • -
    • -
    • -
      - - - - 20 / page + -
      -
    • +
    • + + 1 + +
    • +
    • +
    - - + + +
  • + +
  • + +
    -
    +
    `; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/buildSourceExtraColumns.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/buildSourceExtraColumns.tsx new file mode 100644 index 0000000000..c5047e57be --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/buildSourceExtraColumns.tsx @@ -0,0 +1,39 @@ +import { BasicTypographyEllipsis, BasicToolTips } from '@actiontech/shared'; +import { ActiontechTableColumn } from '@actiontech/shared/lib/components/ActiontechTable'; +import { + ISourceExtraHead, + ISqlManage +} from '@actiontech/shared/lib/api/sqle/service/common'; +import { t } from '../../../../locale'; +import { SqlManagementTableFilterParamType } from './column'; + +export const buildSourceExtraColumns = ( + headList: ISourceExtraHead[] +): ActiontechTableColumn< + ISqlManage, + SqlManagementTableFilterParamType, + string +> => { + return headList.map((head) => { + const dataIndex = head.name ?? ''; + const columnTitle = head.desc || head.name || ''; + return { + dataIndex, + title: () => ( + + {columnTitle} + + ), + className: 'sql-manage-source-extra-column', + settingMarked: true, + sorter: !!head.sortable, + sortDirections: ['descend', 'ascend'] as ['descend', 'ascend'], + render: (value: string | undefined) => { + if (value === undefined || value === null || value === '') { + return '-'; + } + return ; + } + }; + }); +}; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/column.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/column.tsx index 24640e8892..02e8b5822c 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/column.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/column.tsx @@ -28,7 +28,8 @@ import { SQLAuditRecordListUrlParamsKey } from './index.data'; export type SqlManagementTableFilterParamType = PageInfoWithoutIndexAndSize< IGetSqlManageListV2Params, 'fuzzy_search_sql_fingerprint' | 'filter_status' | 'project_name' ->; +> & + Record; export type ExtraFilterMetaType = ISqlManage & { filter_business?: string; @@ -39,6 +40,10 @@ export type ExtraFilterMetaType = ISqlManage & { time?: string; }; +/** 静态 + source_extra 动态筛选项 meta 的 record 类型 */ +export type SqlManagementFilterMetaRecordType = ExtraFilterMetaType & + Record; + export const ExtraFilterMeta: () => ActiontechTableFilterMeta< ExtraFilterMetaType, SqlManagementTableFilterParamType diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useSqlManageSourceExtra.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useSqlManageSourceExtra.tsx new file mode 100644 index 0000000000..32bbabafc9 --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/hooks/useSqlManageSourceExtra.tsx @@ -0,0 +1,232 @@ +import { useTranslation } from 'react-i18next'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { BasicToolTips } from '@actiontech/shared'; +import { + ActiontechTableColumn, + ActiontechTableFilterMeta, + FilterCustomProps, + UpdateTableFilterInfoType +} from '@actiontech/shared/lib/components/ActiontechTable/index.type'; +import useTableFilterContainer, { + mergeFilterButtonMeta +} from '@actiontech/shared/lib/components/ActiontechTable/hooks/useTableFilterContainer'; +import { + ISourceExtra, + ISqlManage +} from '@actiontech/shared/lib/api/sqle/service/common'; +import useBackendTable from '../../../../../hooks/useBackendTable'; +import { buildSourceExtraColumns } from '../buildSourceExtraColumns'; +import { + ExtraFilterMeta, + SqlManagementFilterMetaRecordType, + SqlManagementTableFilterParamType +} from '../column'; +import { + buildExtraFiltersPayload, + canApplySourceExtraFilters, + getSourceExtraFilterNames, + getSourceExtraHeadList, + isSourceExtraEnabled, + joinSourceExtraValuesToList, + omitSourceExtraFilterKeys, + resolveSortFieldForRequest +} from '../sourceExtra.utils'; +import useGetTableFilterInfo from './useGetTableFilterInfo'; + +type UseSqlManageSourceExtraParams = { + baseColumns: ActiontechTableColumn< + ISqlManage, + SqlManagementTableFilterParamType + >; + tableFilterInfo: SqlManagementTableFilterParamType; + updateTableFilterInfo: UpdateTableFilterInfoType; + filterSource: string | undefined; +}; + +const useSqlManageSourceExtra = ({ + baseColumns, + tableFilterInfo, + updateTableFilterInfo, + filterSource +}: UseSqlManageSourceExtraParams) => { + const { t } = useTranslation(); + const [sourceExtra, setSourceExtra] = useState(); + const prevSourceExtraFilterNamesRef = useRef([]); + const { tableFilterMetaFactory } = useBackendTable(); + const { filterCustomProps: staticFilterCustomProps } = + useGetTableFilterInfo(); + + const sourceExtraActive = canApplySourceExtraFilters( + sourceExtra, + filterSource + ); + + const sourceExtraFilterNames = useMemo( + () => (sourceExtraActive ? getSourceExtraFilterNames(sourceExtra) : []), + [sourceExtra, sourceExtraActive] + ); + + const sourceExtraHeadList = useMemo( + () => (sourceExtraActive ? getSourceExtraHeadList(sourceExtra) : []), + [sourceExtra, sourceExtraActive] + ); + + const columns = useMemo( + () => + [ + ...baseColumns, + ...buildSourceExtraColumns(sourceExtraHeadList) + ] as typeof baseColumns, + [baseColumns, sourceExtraHeadList] + ); + + const staticExtraFilterMeta = useMemo(() => ExtraFilterMeta(), []); + + const dynamicSourceExtraFilterMeta = useMemo(() => { + if (!sourceExtraActive || !sourceExtra?.filter_meta_list?.length) { + return undefined; + } + return tableFilterMetaFactory(sourceExtra.filter_meta_list, true); + }, [sourceExtra, sourceExtraActive, tableFilterMetaFactory]); + + const mergedExtraFilterMeta = useMemo((): ActiontechTableFilterMeta< + SqlManagementFilterMetaRecordType, + SqlManagementTableFilterParamType + > => { + const map = new Map(staticExtraFilterMeta) as ActiontechTableFilterMeta< + SqlManagementFilterMetaRecordType, + SqlManagementTableFilterParamType + >; + dynamicSourceExtraFilterMeta?.extraTableFilterMeta.forEach((value, key) => { + const labelText = + typeof value.filterLabel === 'string' ? value.filterLabel : ''; + map.set(key, { + ...value, + filterLabel: ( + + {labelText} + + ) + }); + }); + return map; + }, [staticExtraFilterMeta, dynamicSourceExtraFilterMeta, t]); + + const filterColumns = baseColumns as ActiontechTableColumn< + SqlManagementFilterMetaRecordType, + SqlManagementTableFilterParamType + >; + + const { + filterButtonMeta, + filterContainerMeta, + updateAllSelectedFilterItem, + updateFilterButtonMeta + } = useTableFilterContainer< + SqlManagementFilterMetaRecordType, + SqlManagementTableFilterParamType + >(filterColumns, updateTableFilterInfo, mergedExtraFilterMeta); + + const filterCustomProps = useMemo(() => { + const map = new Map< + keyof SqlManagementFilterMetaRecordType, + FilterCustomProps + >(staticFilterCustomProps); + dynamicSourceExtraFilterMeta?.tableFilterCustomProps?.forEach( + (value, key) => { + map.set(key, value as FilterCustomProps); + } + ); + return map; + }, [staticFilterCustomProps, dynamicSourceExtraFilterMeta]); + + useEffect(() => { + // source_extra 变化时合并筛选项 meta,但必须保留已展开筛选项的 checked, + // 否则 mergeFilterButtonMeta 会把静态筛选项重置为 checked:false,导致原有筛选项从容器中消失。 + updateFilterButtonMeta((prev) => { + const merged = mergeFilterButtonMeta( + filterColumns, + mergedExtraFilterMeta + ); + const next = new Map(merged); + next.forEach((value, key) => { + const previous = prev.get(key); + if (previous) { + next.set(key, { ...value, checked: previous.checked }); + } + }); + return next; + }); + }, [filterColumns, mergedExtraFilterMeta, updateFilterButtonMeta]); + + useEffect(() => { + const prevNames = prevSourceExtraFilterNamesRef.current; + const nextNames = sourceExtraFilterNames; + const removedNames = prevNames.filter((name) => !nextNames.includes(name)); + if (removedNames.length) { + updateTableFilterInfo( + omitSourceExtraFilterKeys( + { ...(tableFilterInfo as Record) }, + removedNames + ) as SqlManagementTableFilterParamType + ); + } + prevSourceExtraFilterNamesRef.current = nextNames; + // tableFilterInfo is read once when source-extra filter keys change + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [sourceExtraFilterNames, updateTableFilterInfo]); + + const handleSourceExtraFromResponse = useCallback( + (nextSourceExtra: ISourceExtra | undefined) => { + setSourceExtra( + isSourceExtraEnabled(nextSourceExtra) ? nextSourceExtra : undefined + ); + }, + [] + ); + + const buildExtraFiltersForRequest = useCallback( + (filters: SqlManagementTableFilterParamType) => { + if (!sourceExtraActive) { + return undefined; + } + const extraFilters = buildExtraFiltersPayload( + filters as Record, + sourceExtraFilterNames + ); + return extraFilters.length ? JSON.stringify(extraFilters) : undefined; + }, + [sourceExtraActive, sourceExtraFilterNames] + ); + + const resolveListSortField = useCallback( + (sortField: string | undefined) => + resolveSortFieldForRequest(sortField, sourceExtra, filterSource), + [sourceExtra, filterSource] + ); + + const joinListData = useCallback( + (list: ISqlManage[] | undefined) => + joinSourceExtraValuesToList( + list, + sourceExtraActive ? sourceExtra : undefined + ), + [sourceExtra, sourceExtraActive] + ); + + return { + columns, + filterButtonMeta, + filterContainerMeta, + filterCustomProps, + updateAllSelectedFilterItem, + handleSourceExtraFromResponse, + buildExtraFiltersForRequest, + resolveListSortField, + joinListData + }; +}; + +export default useSqlManageSourceExtra; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx index 1956e3158d..08cde8c763 100644 --- a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/index.tsx @@ -5,7 +5,6 @@ import { BasicButton, PageHeader } from '@actiontech/shared'; import SQLStatistics, { ISQLStatisticsProps } from '../SQLStatistics'; import { ActiontechTable, - useTableFilterContainer, useTableRequestError, TableFilterContainer, TableToolbar, @@ -26,20 +25,21 @@ import StatusFilter, { TypeStatus } from './StatusFilter'; import { GetSqlManageListV2FilterPriorityEnum, GetSqlManageListV2FilterStatusEnum, - GetSqlManageListV2SortFieldEnum, GetSqlManageListV2SortOrderEnum, exportSqlManageV1FilterPriorityEnum, exportSqlManageV1FilterStatusEnum, exportSqlManageRemediationV1ExportScopeEnum } from '@actiontech/shared/lib/api/sqle/service/SqlManage/index.enum'; import SqlManagementColumn, { - ExtraFilterMeta, SqlManagementRowAction, type SqlManagementTableFilterParamType } from './column'; import { ModalName } from '../../../../data/ModalName'; import { SorterResult, TableRowSelection } from 'antd/es/table/interface'; -import { ISqlManage } from '@actiontech/shared/lib/api/sqle/service/common'; +import { + ISourceExtra, + ISqlManage +} from '@actiontech/shared/lib/api/sqle/service/common'; import { Spin, message, Dropdown } from 'antd'; import type { MenuProps } from 'antd'; import SqlManagementModal from './Modal'; @@ -49,12 +49,14 @@ import { DB_TYPE_RULE_NAME_SEPARATOR } from '../../../../hooks/useRuleTips'; import useSqlManagementRedux from './hooks/useSqlManagementRedux'; import useBatchIgnoreOrSolve from './hooks/useBatchIgnoreOrSolve'; import { actionsButtonData, defaultActionButton } from './index.data'; -import useGetTableFilterInfo from './hooks/useGetTableFilterInfo'; import { DownArrowLineOutlined } from '@actiontech/icons'; import useSqlManagementExceptionRedux from '../../../SqlManagementException/hooks/useSqlManagementExceptionRedux'; import useWhitelistRedux from '../../../Whitelist/hooks/useWhitelistRedux'; import { toSqlManageRuleExceptionRecord } from '../../../RuleException/index.data'; import { BlacklistResV1TypeEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { SqlManagementListStyleWrapper } from './style'; +import { pickStaticSqlManageFilters } from './sourceExtra.utils'; +import useSqlManageSourceExtra from './hooks/useSqlManageSourceExtra'; const SQLEEIndex = () => { const { t } = useTranslation(); @@ -96,74 +98,7 @@ const SQLEEIndex = () => { optimizedSQLNum: 0 }); - const getCurrentSortParams = ( - sortData: SorterResult | SorterResult[] - ): Pick => { - if (Array.isArray(sortData)) { - return {}; - } - const orderDesc = { - descend: GetSqlManageListV2SortOrderEnum.desc, - ascend: GetSqlManageListV2SortOrderEnum.asc - }; - - return { - sort_field: - (sortData.field as unknown as GetSqlManageListV2SortFieldEnum) ?? - undefined, - sort_order: sortData?.order - ? orderDesc[sortData?.order] ?? undefined - : undefined - }; - }; - - const { - data: sqlList, - loading: getListLoading, - refresh, - error: getListError - } = useRequest( - () => { - const { filter_rule_name, ...otherTableFilterInfo } = tableFilterInfo; - const params: IGetSqlManageListV2Params = { - ...otherTableFilterInfo, - ...pagination, - ...getCurrentSortParams(sortInfo), - 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], - filter_status: filterStatus === 'all' ? undefined : filterStatus, - fuzzy_search_sql_fingerprint: searchKeyword, - project_name: projectName, - filter_assignee: isAssigneeSelf ? uid : undefined, // filter_assignee 需要用 id - filter_priority: isHighPriority - ? GetSqlManageListV2FilterPriorityEnum.high - : undefined - }; - return handleTableRequestError(SqlManage.GetSqlManageListV2(params)); - }, - { - refreshDeps: [ - pagination, - projectName, - filterStatus, - isAssigneeSelf, - isHighPriority, - tableFilterInfo, - sortInfo - ], - onFinally: (params, data) => { - setSQLNum({ - SQLTotalNum: data?.otherData?.sql_manage_total_num ?? 0, - problemSQlNum: data?.otherData?.sql_manage_bad_num ?? 0, - optimizedSQLNum: data?.otherData?.sql_manage_optimized_num ?? 0 - }); - } - } - ); + const filterSource = tableFilterInfo.filter_source; const openModal = useCallback((name: ModalName, row?: ISqlManage) => { if (row) { @@ -213,32 +148,139 @@ const SQLEEIndex = () => { [openAuditWhitelistCreateWithPrefill] ); - const actions = useMemo(() => { - return SqlManagementRowAction( - openModal, - jumpToAnalyze, - isAdmin || isProjectManager(projectName), - onCreateSqlManagementException, - onCreateWhitelist + const actionPermission = useMemo(() => { + return isAdmin || isProjectManager(projectName); + }, [isAdmin, isProjectManager, projectName]); + + const updateRemarkProtect = useRef(false); + const updateRemarkRef = useRef<(id: number, remark: string) => void>( + () => undefined + ); + + const baseColumns = useMemo( + () => + SqlManagementColumn( + projectID, + actionPermission && !projectArchive, + (id, remark) => updateRemarkRef.current(id, remark), + openModal + ), + [projectID, actionPermission, projectArchive, openModal] + ); + + const { + columns, + filterButtonMeta, + filterContainerMeta, + filterCustomProps, + updateAllSelectedFilterItem, + handleSourceExtraFromResponse, + buildExtraFiltersForRequest, + resolveListSortField, + joinListData + } = useSqlManageSourceExtra({ + baseColumns, + tableFilterInfo, + updateTableFilterInfo, + filterSource + }); + + const getCurrentSortParams = ( + sortData: SorterResult | SorterResult[] + ): Pick => { + if (Array.isArray(sortData)) { + return {}; + } + const orderDesc = { + descend: GetSqlManageListV2SortOrderEnum.desc, + ascend: GetSqlManageListV2SortOrderEnum.asc + }; + const rawSortField = + typeof sortData.field === 'string' ? sortData.field : undefined; + const sortField = resolveListSortField(rawSortField); + + return { + sort_field: sortField, + sort_order: sortField + ? sortData?.order + ? orderDesc[sortData?.order] ?? undefined + : undefined + : undefined + }; + }; + + const buildListRequestParams = useCallback((): IGetSqlManageListV2Params => { + const { filter_rule_name, ...otherTableFilterInfo } = tableFilterInfo; + const staticFilters = pickStaticSqlManageFilters( + otherTableFilterInfo as Record ); + + return { + ...(staticFilters as Partial), + ...pagination, + ...getCurrentSortParams(sortInfo), + 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], + filter_status: filterStatus === 'all' ? undefined : filterStatus, + fuzzy_search_sql_fingerprint: searchKeyword, + project_name: projectName, + filter_assignee: isAssigneeSelf ? uid : undefined, + filter_priority: isHighPriority + ? GetSqlManageListV2FilterPriorityEnum.high + : undefined, + extra_filters: buildExtraFiltersForRequest(tableFilterInfo) + }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ - isAdmin, - isProjectManager, - jumpToAnalyze, - openModal, + tableFilterInfo, + buildExtraFiltersForRequest, + pagination, + sortInfo, + filterStatus, + searchKeyword, projectName, - onCreateSqlManagementException, - onCreateWhitelist + isAssigneeSelf, + uid, + isHighPriority, + resolveListSortField ]); - const actionPermission = useMemo(() => { - return isAdmin || isProjectManager(projectName); - }, [isAdmin, isProjectManager, projectName]); - - const [selectedRowKeys, setSelectedRowKeys] = useState([]); - const [selectedRowData, setSelectedRowData] = useState([]); + const { + data: sqlList, + loading: getListLoading, + refresh, + error: getListError + } = useRequest( + () => { + return handleTableRequestError( + SqlManage.GetSqlManageListV2(buildListRequestParams()) + ); + }, + { + refreshDeps: [ + pagination, + projectName, + filterStatus, + isAssigneeSelf, + isHighPriority, + tableFilterInfo, + sortInfo + ], + onFinally: (_params, data) => { + setSQLNum({ + SQLTotalNum: data?.otherData?.sql_manage_total_num ?? 0, + problemSQlNum: data?.otherData?.sql_manage_bad_num ?? 0, + optimizedSQLNum: data?.otherData?.sql_manage_optimized_num ?? 0 + }); + handleSourceExtraFromResponse( + data?.otherData?.source_extra as ISourceExtra | undefined + ); + } + } + ); - const updateRemarkProtect = useRef(false); const updateRemark = useCallback( (id: number, remark: string) => { if ( @@ -264,17 +306,28 @@ const SQLEEIndex = () => { }, [actionPermission, projectName, refresh, projectArchive] ); + updateRemarkRef.current = updateRemark; - const columns = useMemo( - () => - SqlManagementColumn( - projectID, - actionPermission && !projectArchive, - updateRemark, - openModal - ), - [projectID, actionPermission, projectArchive, updateRemark, openModal] - ); + const actions = useMemo(() => { + return SqlManagementRowAction( + openModal, + jumpToAnalyze, + isAdmin || isProjectManager(projectName), + onCreateSqlManagementException, + onCreateWhitelist + ); + }, [ + isAdmin, + isProjectManager, + jumpToAnalyze, + openModal, + projectName, + onCreateSqlManagementException, + onCreateWhitelist + ]); + + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [selectedRowData, setSelectedRowData] = useState([]); const tableSetting = useMemo( () => ({ @@ -283,10 +336,11 @@ const SQLEEIndex = () => { }), [username] ); - const { filterButtonMeta, filterContainerMeta, updateAllSelectedFilterItem } = - useTableFilterContainer(columns, updateTableFilterInfo, ExtraFilterMeta()); - const { filterCustomProps } = useGetTableFilterInfo(); + const dataSource = useMemo( + () => joinListData(sqlList?.list), + [joinListData, sqlList?.list] + ); const rowSelection: TableRowSelection = { selectedRowKeys, @@ -320,24 +374,18 @@ const SQLEEIndex = () => { const hideLoading = messageApi.loading( t('sqlManagement.pageHeader.action.exporting') ); - const { filter_rule_name, ...otherTableFilterInfo } = tableFilterInfo; - + const listParams = buildListRequestParams(); const params = { - ...otherTableFilterInfo, + ...listParams, filter_status: filterStatus === 'all' ? undefined : (filterStatus as unknown as exportSqlManageV1FilterStatusEnum), - fuzzy_search_sql_fingerprint: searchKeyword, - project_name: projectName, - filter_assignee: isAssigneeSelf ? uid : undefined, filter_priority: isHighPriority ? exportSqlManageV1FilterPriorityEnum.high : undefined, - 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] + page_index: undefined, + page_size: undefined } as IExportSqlManageV1Params; SqlManage.exportSqlManageV1(params, { responseType: 'blob' }) .then((res) => { @@ -473,88 +521,87 @@ const SQLEEIndex = () => { }; return ( - - {messageContextHolder} - } - disabled={exportButtonDisabled} - onClick={handleExport} - > - {t('sqlManagement.pageHeader.action.exportReport')} - - ) : ( - + + + {messageContextHolder} + } disabled={exportButtonDisabled} + onClick={handleExport} > {t('sqlManagement.pageHeader.action.exportReport')} - - ) - } - /> - {/* page */} - {/* page - total */} - - {/* table */} - { - refreshBySearchKeyword(); + ) : ( + + } + disabled={exportButtonDisabled} + > + {t('sqlManagement.pageHeader.action.exportReport')} + + + ) } - }} - > - - - - { - return `${record?.id}`; - }} - rowSelection={rowSelection as TableRowSelection} - pagination={{ - total: SQLNum.SQLTotalNum, - current: pagination.page_index - }} - columns={columns} - errorMessage={requestErrorMessage} - onChange={tableChange} - actions={projectArchive ? undefined : actions} - /> - {/* modal & drawer */} - - + /> + + { + refreshBySearchKeyword(); + } + }} + > + + + + { + return `${record?.id}`; + }} + rowSelection={rowSelection as TableRowSelection} + pagination={{ + total: SQLNum.SQLTotalNum, + current: pagination.page_index + }} + columns={columns} + errorMessage={requestErrorMessage} + onChange={tableChange} + actions={projectArchive ? undefined : actions} + /> + + + ); }; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/sourceExtra.data.ts b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/sourceExtra.data.ts new file mode 100644 index 0000000000..b54bf8bf90 --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/sourceExtra.data.ts @@ -0,0 +1,41 @@ +import { GetSqlManageListSortFieldEnum } from '@actiontech/shared/lib/api/sqle/service/SqlManage/index.enum'; + +/** Classic sort fields that always belong to SQL manage list (not source_extra). */ +export const SQL_MANAGE_CLASSIC_SORT_FIELDS = [ + GetSqlManageListSortFieldEnum.first_appear_timestamp, + GetSqlManageListSortFieldEnum.last_receive_timestamp, + GetSqlManageListSortFieldEnum.fp_count +] as const; + +export type SqlManageClassicSortField = + (typeof SQL_MANAGE_CLASSIC_SORT_FIELDS)[number]; + +export const isSqlManageClassicSortField = ( + field: string | undefined | null +): field is SqlManageClassicSortField => { + if (!field) { + return false; + } + return (SQL_MANAGE_CLASSIC_SORT_FIELDS as readonly string[]).includes(field); +}; + +/** + * Known static filter keys that map to GetSqlManageListV2 query params. + * Dynamic source_extra filters must NOT be spread into those params. + */ +export const SQL_MANAGE_STATIC_FILTER_KEYS = [ + 'filter_business', + 'filter_source', + 'filter_instance_id', + 'filter_audit_level', + 'filter_rule_name', + 'filter_last_audit_start_time_from', + 'filter_last_audit_start_time_to', + 'filter_assignee', + 'filter_priority', + 'filter_status', + 'filter_db_type', + 'fuzzy_search_sql_fingerprint', + 'fuzzy_search_endpoint', + 'fuzzy_search_schema_name' +] as const; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/sourceExtra.utils.ts b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/sourceExtra.utils.ts new file mode 100644 index 0000000000..a29ea83d6b --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/sourceExtra.utils.ts @@ -0,0 +1,165 @@ +import { + IFilter, + ISourceExtra, + ISourceExtraHead, + ISqlManage +} from '@actiontech/shared/lib/api/sqle/service/common'; +import { + isSqlManageClassicSortField, + SQL_MANAGE_STATIC_FILTER_KEYS +} from './sourceExtra.data'; + +export const isSourceExtraEnabled = ( + sourceExtra: ISourceExtra | undefined | null +): boolean => sourceExtra?.enabled === true; + +export const getSourceExtraFilterNames = ( + sourceExtra: ISourceExtra | undefined | null +): string[] => + (sourceExtra?.filter_meta_list ?? []) + .map((meta) => meta.filter_name) + .filter((name): name is string => !!name); + +export const canApplySourceExtraFilters = ( + sourceExtra: ISourceExtra | undefined | null, + filterSource: string | undefined +): boolean => + isSourceExtraEnabled(sourceExtra) && + !!filterSource && + sourceExtra?.source === filterSource; + +export const buildExtraFiltersPayload = ( + tableFilterInfo: Record, + sourceExtraFilterNames: string[] +): IFilter[] => { + const nameSet = new Set(sourceExtraFilterNames); + const filters: IFilter[] = []; + + nameSet.forEach((filterName) => { + const value = tableFilterInfo[filterName]; + if (value === undefined || value === null || value === '') { + return; + } + if (Array.isArray(value)) { + const [from, to] = value; + if (!from && !to) { + return; + } + filters.push({ + filter_name: filterName, + filter_between_value: { + from: from ? String(from) : '', + to: to ? String(to) : '' + } + }); + return; + } + filters.push({ + filter_name: filterName, + filter_compare_value: String(value) + }); + }); + + return filters; +}; + +export const omitSourceExtraFilterKeys = >( + tableFilterInfo: T, + sourceExtraFilterNames: string[] +): T => { + if (!sourceExtraFilterNames.length) { + return tableFilterInfo; + } + const nameSet = new Set(sourceExtraFilterNames); + const next = { ...tableFilterInfo }; + nameSet.forEach((name) => { + delete next[name]; + }); + return next; +}; + +export const pickStaticSqlManageFilters = ( + tableFilterInfo: Record +): Record => { + const staticKeySet = new Set(SQL_MANAGE_STATIC_FILTER_KEYS); + return Object.keys(tableFilterInfo).reduce>( + (acc, key) => { + if (staticKeySet.has(key)) { + acc[key] = tableFilterInfo[key]; + } + return acc; + }, + {} + ); +}; + +export const resolveSortFieldForRequest = ( + sortField: string | undefined, + sourceExtra: ISourceExtra | undefined | null, + filterSource: string | undefined +): string | undefined => { + if (!sortField) { + return undefined; + } + if (isSqlManageClassicSortField(sortField)) { + return sortField; + } + if (!canApplySourceExtraFilters(sourceExtra, filterSource)) { + return undefined; + } + const sortableNames = new Set( + (sourceExtra?.head ?? []) + .filter((head) => head.sortable && head.name) + .map((head) => head.name as string) + ); + return sortableNames.has(sortField) ? sortField : undefined; +}; + +export const joinSourceExtraValuesToList = ( + list: ISqlManage[] | undefined, + sourceExtra: ISourceExtra | undefined | null +): ISqlManage[] => { + if (!list?.length || !isSourceExtraEnabled(sourceExtra)) { + return list ?? []; + } + const valueMap = new Map>(); + (sourceExtra?.rows ?? []).forEach((row) => { + if (typeof row.id === 'number') { + valueMap.set(row.id, row.values ?? {}); + } + }); + const headNameSet = new Set( + (sourceExtra?.head ?? []) + .map((head) => head.name) + .filter((name): name is string => !!name) + ); + + return list.map((item) => { + if (typeof item.id !== 'number') { + return item; + } + const values = valueMap.get(item.id); + if (!values) { + return item; + } + const whitelistedValues = Object.fromEntries( + Object.entries(values).filter(([key]) => headNameSet.has(key)) + ); + if (!Object.keys(whitelistedValues).length) { + return item; + } + return { + ...item, + ...whitelistedValues + }; + }); +}; + +export const getSourceExtraHeadList = ( + sourceExtra: ISourceExtra | undefined | null +): ISourceExtraHead[] => { + if (!isSourceExtraEnabled(sourceExtra)) { + return []; + } + return (sourceExtra?.head ?? []).filter((head) => !!head.name); +}; diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/style.ts b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/style.ts new file mode 100644 index 0000000000..d04cd8eb2b --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/style.ts @@ -0,0 +1,20 @@ +import { styled } from '@mui/material/styles'; + +export const SqlManagementListStyleWrapper = styled('section')` + /* 动态列 / 动态筛选项共用:蓝色 * 标记 */ + .sql-manage-source-extra-mark { + position: relative; + display: inline-block; + padding-right: 0.55em; + + &::after { + content: '*'; + position: absolute; + top: 0.2em; + right: 0; + font-size: 12px; + line-height: 1; + color: ${({ theme }) => theme.sharedTheme.uiToken.colorPrimary}; + } + } +`; diff --git a/packages/sqle/src/page/SqlManagementConf/Detail/Overview/__tests__/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlManagementConf/Detail/Overview/__tests__/__snapshots__/index.test.tsx.snap index ea0947c106..fd781ba32f 100644 --- a/packages/sqle/src/page/SqlManagementConf/Detail/Overview/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlManagementConf/Detail/Overview/__tests__/__snapshots__/index.test.tsx.snap @@ -9,7 +9,7 @@ exports[`test Overview should match snapshot when getUserOperationPermissionLoad class="ant-spin-container" >
    -
    - +
    @@ -2167,7 +2175,7 @@ exports[`test sqle/SqlManagementConf/List render filter list data by active stat