feat(redis/monitor/oracle/data-viewer): 新增 Redis 实例监控并优化 Oracle 大表预览体验

- 新增 RedisMonitor 面板,展示 QPS、内存、CPU、连接数和键数量趋势图
- 引入 recharts 依赖并补齐监控图表所需前端包与锁文件
- Sidebar 新增 Redis 实例监控入口,TabManager 与 TabData 接入 redis-monitor 页签类型
- RedisCommandEditor 支持多行脚本块解析、选区执行、耗时记录与终端化结果展示
- Oracle 表预览移除自动精确 COUNT(*),避免打开大表时额外阻塞
- 无筛选整表预览接入 ALL_TABLES.NUM_ROWS 近似总数展示,并拆分近似总数与近似总页数语义
This commit is contained in:
Syngnat
2026-03-30 16:48:19 +08:00
parent 6e55d63877
commit aa9d8d243a
20 changed files with 1424 additions and 194 deletions

View File

@@ -12,6 +12,7 @@ import QueryEditor from './QueryEditor';
import TableDesigner from './TableDesigner';
import RedisViewer from './RedisViewer';
import RedisCommandEditor from './RedisCommandEditor';
import RedisMonitor from './RedisMonitor';
import TriggerViewer from './TriggerViewer';
import DefinitionViewer from './DefinitionViewer';
import TableOverview from './TableOverview';
@@ -199,17 +200,20 @@ const TabManager: React.FC = () => {
const items = useMemo(() => tabs.map((tab, index) => {
const connectionName = connections.find((conn) => conn.id === tab.connectionId)?.name;
const displayTitle = buildTabDisplayTitle(tab, connectionName);
const tabIsActive = tab.id === activeTabId;
let content;
if (tab.type === 'query') {
content = <QueryEditor tab={tab} />;
content = <QueryEditor tab={tab} isActive={tabIsActive} />;
} else if (tab.type === 'table') {
content = <DataViewer tab={tab} />;
content = <DataViewer tab={tab} isActive={tabIsActive} />;
} else if (tab.type === 'design') {
content = <TableDesigner tab={tab} />;
} else if (tab.type === 'redis-keys') {
content = <RedisViewer connectionId={tab.connectionId} redisDB={tab.redisDB ?? 0} />;
} else if (tab.type === 'redis-command') {
content = <RedisCommandEditor connectionId={tab.connectionId} redisDB={tab.redisDB ?? 0} />;
} else if (tab.type === 'redis-monitor') {
content = <RedisMonitor connectionId={tab.connectionId} redisDB={tab.redisDB ?? 0} />;
} else if (tab.type === 'trigger') {
content = <TriggerViewer tab={tab} />;
} else if (tab.type === 'view-def' || tab.type === 'routine-def') {
@@ -256,7 +260,7 @@ const TabManager: React.FC = () => {
key: tab.id,
children: content,
};
}), [tabs, connections, closeOtherTabs, closeTabsToLeft, closeTabsToRight, closeAllTabs]);
}), [tabs, connections, activeTabId, closeOtherTabs, closeTabsToLeft, closeTabsToRight, closeAllTabs]);
return (
<>