feat(sidebar/table-overview): 优化右键菜单交互,增加危险操作二级分类防误触

- 菜单增强:为数据库、表、视图、函数等底层对象节点新增「危险操作」二级子菜单
- 误触防护:将明确破坏性的「删除表」、「删除数据库」等入口移至更深层级进行视觉隔离
- UI 交互:引入 WarningOutlined 图标单独高亮标识风险区域
- 统一作用域:同步变更至侧边栏连接树 (Sidebar) 和表数据概览 (TableOverview) 的上下文菜单
This commit is contained in:
Syngnat
2026-04-02 10:11:33 +08:00
parent f992ad72e6
commit 6d533167da
2 changed files with 57 additions and 24 deletions

View File

@@ -31,7 +31,8 @@ import { Tree, message, Dropdown, MenuProps, Input, Button, Modal, Form, Badge,
TagOutlined,
CheckOutlined,
FilterOutlined,
DashboardOutlined
DashboardOutlined,
WarningOutlined
} from '@ant-design/icons';
import { useStore } from '../store';
import { buildOverlayWorkbenchTheme } from '../utils/overlayWorkbenchTheme';
@@ -3396,11 +3397,18 @@ const Sidebar: React.FC<{ onEditConnection?: (conn: SavedConnection) => void }>
}
},
{
key: 'drop-db',
label: '删除数据库',
icon: <DeleteOutlined />,
danger: true,
onClick: () => handleDeleteDatabase(node)
key: 'danger-zone',
label: '危险操作',
icon: <WarningOutlined />,
children: [
{
key: 'drop-db',
label: '删除数据库',
icon: <DeleteOutlined />,
danger: true,
onClick: () => handleDeleteDatabase(node)
}
]
},
{
key: 'refresh',
@@ -3513,11 +3521,18 @@ const Sidebar: React.FC<{ onEditConnection?: (conn: SavedConnection) => void }>
}
},
{
key: 'drop-view',
label: '删除视图',
icon: <DeleteOutlined />,
danger: true,
onClick: () => handleDropView(node)
key: 'danger-zone',
label: '危险操作',
icon: <WarningOutlined />,
children: [
{
key: 'drop-view',
label: '删除视图',
icon: <DeleteOutlined />,
danger: true,
onClick: () => handleDropView(node)
}
]
},
];
} else if (node.type === 'routine') {
@@ -3538,11 +3553,18 @@ const Sidebar: React.FC<{ onEditConnection?: (conn: SavedConnection) => void }>
},
{ type: 'divider' },
{
key: 'drop-routine',
label: `删除${typeLabel}`,
icon: <DeleteOutlined />,
danger: true,
onClick: () => handleDropRoutine(node)
key: 'danger-zone',
label: '危险操作',
icon: <WarningOutlined />,
children: [
{
key: 'drop-routine',
label: `删除${typeLabel}`,
icon: <DeleteOutlined />,
danger: true,
onClick: () => handleDropRoutine(node)
}
]
},
];
} else if (node.type === 'table') {
@@ -3594,11 +3616,18 @@ const Sidebar: React.FC<{ onEditConnection?: (conn: SavedConnection) => void }>
}
},
{
key: 'drop-table',
label: '删除表',
icon: <DeleteOutlined />,
danger: true,
onClick: () => handleDeleteTable(node)
key: 'danger-zone',
label: '危险操作',
icon: <WarningOutlined />,
children: [
{
key: 'drop-table',
label: '删除表',
icon: <DeleteOutlined />,
danger: true,
onClick: () => handleDeleteTable(node)
}
]
},
{
type: 'divider'

View File

@@ -1,6 +1,6 @@
import React, { useState, useEffect, useMemo, useCallback } from 'react';
import { Input, Spin, Empty, Dropdown, message, Tooltip, Modal } from 'antd';
import { TableOutlined, SearchOutlined, ReloadOutlined, SortAscendingOutlined, DatabaseOutlined, ConsoleSqlOutlined, EditOutlined, CopyOutlined, SaveOutlined, DeleteOutlined, ExportOutlined, AppstoreOutlined, UnorderedListOutlined } from '@ant-design/icons';
import { TableOutlined, SearchOutlined, ReloadOutlined, SortAscendingOutlined, DatabaseOutlined, ConsoleSqlOutlined, EditOutlined, CopyOutlined, SaveOutlined, DeleteOutlined, ExportOutlined, AppstoreOutlined, UnorderedListOutlined, WarningOutlined } from '@ant-design/icons';
import { useStore } from '../store';
import { DBQuery, DBShowCreateTable, ExportTable, DropTable, RenameTable } from '../../wailsjs/go/app/App';
import type { TabData } from '../types';
@@ -432,7 +432,9 @@ const TableOverview: React.FC<TableOverviewProps> = ({ tab }) => {
{ key: 'copy-structure', label: '复制表结构', icon: <CopyOutlined />, onClick: () => handleCopyStructure(t.name) },
{ key: 'backup-table', label: '备份表 (SQL)', icon: <SaveOutlined />, onClick: () => handleExport(t.name, 'sql') },
{ key: 'rename-table', label: '重命名表', icon: <EditOutlined />, onClick: () => handleRenameTable(t.name) },
{ key: 'drop-table', label: '删除表', icon: <DeleteOutlined />, danger: true, onClick: () => handleDeleteTable(t.name) },
{ key: 'danger-zone', label: '危险操作', icon: <WarningOutlined />, children: [
{ key: 'drop-table', label: '删除表', icon: <DeleteOutlined />, danger: true, onClick: () => handleDeleteTable(t.name) }
]},
{ type: 'divider' },
{ key: 'export', label: '导出表数据', icon: <ExportOutlined />, children: [
{ key: 'export-csv', label: '导出 CSV', onClick: () => handleExport(t.name, 'csv') },
@@ -544,7 +546,9 @@ const TableOverview: React.FC<TableOverviewProps> = ({ tab }) => {
{ key: 'copy-structure', label: '复制表结构', icon: <CopyOutlined />, onClick: () => handleCopyStructure(t.name) },
{ key: 'backup-table', label: '备份表 (SQL)', icon: <SaveOutlined />, onClick: () => handleExport(t.name, 'sql') },
{ key: 'rename-table', label: '重命名表', icon: <EditOutlined />, onClick: () => handleRenameTable(t.name) },
{ key: 'drop-table', label: '删除表', icon: <DeleteOutlined />, danger: true, onClick: () => handleDeleteTable(t.name) },
{ key: 'danger-zone', label: '危险操作', icon: <WarningOutlined />, children: [
{ key: 'drop-table', label: '删除表', icon: <DeleteOutlined />, danger: true, onClick: () => handleDeleteTable(t.name) }
]},
{ type: 'divider' },
{ key: 'export', label: '导出表数据', icon: <ExportOutlined />, children: [
{ key: 'export-csv', label: '导出 CSV', onClick: () => handleExport(t.name, 'csv') },