feat: TicketCreatePage tab化 + SchemaSidebar + Redis快速搜索 + Dashboard导航修复

TicketCreatePage 重构:
- SQL编辑器右侧新增数据库浏览器面板(tab化)
- 表结构Tab: 表列表→字段展开(PK/索引标记)→点击插入SQL
- 索引Tab: 选中表的索引详情(索引名/类型/字段/基数)
- Redis Keys Tab: DB选择器+Key模式搜索+Key列表+类型/TTL/值查看

SchemaSidebar 新组件(365行):
- MySQL/PostgreSQL: 左侧数据库表树→字段→点击插入SQL
- Redis: Key树(DB选择→模式搜索→Key值查看, 类似Another Redis Desktop Manager)
- 用于 QueriesPage 查询页面

Dashboard:
- 快捷按钮改用 useNavigate + onClick 替代 <a href>

API增强:
- redis.ts: 新增 getKeys/createKey/deleteKey 方法
- instanceDetail.ts: 导出 TableMeta/TableDetail/ColumnInfo/IndexInfo 类型接口
This commit is contained in:
logan committed 2026-05-24 15:10:31 +08:00
1 parent 8471f368eb
commit 0fb947dcb5
6 files changed
+1020 -476

No files matched your search

+8 -6
View File
@@ -1,4 +1,5 @@
import { useEffect, useRef, useState, useCallback, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import {
ClipboardList, Clock, CheckCircle, AlertTriangle,
Database, ChevronRight, X, AlertCircle, Info, Bell,
@@ -125,6 +126,7 @@ export default function Dashboard() {
const chartInstanceRef = useRef<echarts.ECharts | null>(null);
const { theme } = useTheme();
const { user } = useAuth();
const navigate = useNavigate();
const [dismissedIds, setDismissedIds] = useState<Set<string>>(new Set());
const [readIds, setReadIds] = useState<Set<string>>(new Set());
const [expandedId, setExpandedId] = useState<string | null>(null);
@@ -338,9 +340,9 @@ export default function Dashboard() {
}, [stats]);
const quickActions = [
{ label: '新建工单', icon: FileText, href: '/tickets', color: 'text-blue-400', bg: 'bg-blue-400/10', border: 'border-blue-400/20' },
{ label: '新建查询', icon: Search, href: '/queries', color: 'text-green-400', bg: 'bg-green-400/10', border: 'border-green-400/20' },
{ label: '添加实例', icon: Database, href: '/instances', color: 'text-purple-400', bg: 'bg-purple-400/10', border: 'border-purple-400/20' },
{ label: '新建工单', icon: FileText, onClick: () => navigate('/tickets/create'), color: 'text-blue-400', bg: 'bg-blue-400/10', border: 'border-blue-400/20' },
{ label: '新建查询', icon: Search, onClick: () => navigate('/queries'), color: 'text-green-400', bg: 'bg-green-400/10', border: 'border-green-400/20' },
{ label: '添加实例', icon: Database, onClick: () => navigate('/instances'), color: 'text-purple-400', bg: 'bg-purple-400/10', border: 'border-purple-400/20' },
];
const TrendIcon = ({ trend }: { trend: 'up' | 'down' | 'neutral' }) => {
@@ -371,15 +373,15 @@ export default function Dashboard() {
{/* ---- Quick Actions ---- */}
<div className="flex gap-2 flex-wrap">
{quickActions.map(action => (
<a
<button
key={action.label}
href={action.href}
onClick={action.onClick}
className={`flex items-center gap-2 px-4 py-2.5 rounded-lg text-sm font-medium border transition-all ${action.bg} ${action.color} ${action.border} hover:opacity-80`}
>
<action.icon className="w-4 h-4" />
{action.label}
<ArrowUpRight className="w-3 h-3 opacity-50" />
</a>
</button>
))}
</div>