mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-22 21:27:11 +08:00
✨ feat(sidebar): 新增 Sidebar 慢 SQL 历史浮动入口
- 新建 SlowQueryRailButton:独立小组件,从 store 直接读 tabs/connections 解析激活连接 - 挂载方式:浮动在 Sidebar 右下角,不修改 Sidebar.tsx 内部代码(避免改 10275 行的大文件) - 体验优化:无激活连接时按钮自动禁用并 tooltip 提示;与 Ctrl+Shift+L 快捷键路径并存 - bundle 保持:SlowQueryPanel 继续走 lazy 加载独立 chunk,不进入主 bundle
This commit is contained in:
@@ -4,6 +4,7 @@ import { Layout, Button, ConfigProvider, theme, message, Spin, Slider, Progress,
|
||||
import { PlusOutlined, ConsoleSqlOutlined, UploadOutlined, DownloadOutlined, CloudDownloadOutlined, BugOutlined, ToolOutlined, GlobalOutlined, InfoCircleOutlined, GithubOutlined, SkinOutlined, CheckOutlined, MinusOutlined, BorderOutlined, CloseOutlined, SettingOutlined, LinkOutlined, BgColorsOutlined, AppstoreOutlined, RobotOutlined, FolderOpenOutlined, HddOutlined, SafetyCertificateOutlined, SwitcherOutlined, CodeOutlined, RightOutlined } from '@ant-design/icons';
|
||||
import { BrowserOpenURL, Environment, EventsOn, Quit, WindowFullscreen, WindowGetPosition, WindowGetSize, WindowIsFullscreen, WindowIsMaximised, WindowIsMinimised, WindowIsNormal, WindowMaximise, WindowMinimise, WindowSetPosition, WindowSetSize, WindowUnfullscreen, WindowUnmaximise } from '../wailsjs/runtime';
|
||||
import Sidebar from './components/Sidebar';
|
||||
import SlowQueryRailButton from './components/sidebar/SlowQueryRailButton';
|
||||
import TabManager from './components/TabManager';
|
||||
import ConnectionModal from './components/ConnectionModal';
|
||||
import SnippetSettingsModal from './components/SnippetSettingsModal';
|
||||
@@ -3692,6 +3693,18 @@ function App() {
|
||||
onFocusCommandSearch={handleFocusSidebarSearch}
|
||||
/>
|
||||
</div>
|
||||
{/* 慢 SQL 历史入口:浮动在 Sidebar 右下角,独立组件不依赖 Sidebar 内部 state */}
|
||||
<SlowQueryRailButton
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: 8,
|
||||
bottom: isV2Ui ? 8 : 66,
|
||||
zIndex: 10,
|
||||
background: 'var(--gn-card-bg, rgba(255,255,255,0.9))',
|
||||
borderRadius: 6,
|
||||
boxShadow: '0 1px 4px rgba(0,0,0,0.1)',
|
||||
}}
|
||||
/>
|
||||
{!connectionWorkbenchState.ready && (
|
||||
<div
|
||||
style={{
|
||||
|
||||
99
frontend/src/components/sidebar/SlowQueryRailButton.tsx
Normal file
99
frontend/src/components/sidebar/SlowQueryRailButton.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import { lazy, Suspense, useMemo, useState } from 'react'
|
||||
import { Tooltip } from 'antd'
|
||||
import { HistoryOutlined } from '@ant-design/icons'
|
||||
import { useStore } from '../../store'
|
||||
import type { ConnectionConfig } from '../../types'
|
||||
// lazy 加载避免 SlowQueryPanel(react-flow + dagre 约 200KB)进入主 bundle
|
||||
const SlowQueryPanel = lazy(() => import('../explain/SlowQueryPanel'))
|
||||
|
||||
// Sidebar 顶部的慢 SQL 历史入口。
|
||||
//
|
||||
// 设计要点:
|
||||
// - 完全独立组件,不依赖 Sidebar.tsx 内部 state(避免改 Sidebar Props)
|
||||
// - 自己从 store 读取 tabs/connections,解析当前激活 tab 的连接配置
|
||||
// - 通过 lazy import SlowQueryPanel(react-flow/dagre 不进入主 bundle)
|
||||
// - 没有激活的连接时按钮禁用,hover 给提示
|
||||
//
|
||||
// 挂载位置:由调用方决定(App.tsx 把它放在 Sidebar 容器内)
|
||||
|
||||
interface SlowQueryRailButtonProps {
|
||||
/** 自定义 className 用于外层定位 */
|
||||
className?: string
|
||||
/** 自定义 style(用于绝对定位到 Sidebar 角落) */
|
||||
style?: React.CSSProperties
|
||||
}
|
||||
|
||||
export default function SlowQueryRailButton({ className, style }: SlowQueryRailButtonProps) {
|
||||
const [open, setOpen] = useState(false)
|
||||
const tabs = useStore(s => s.tabs)
|
||||
const activeTabId = useStore(s => s.activeTabId)
|
||||
const connections = useStore(s => s.connections)
|
||||
|
||||
// 解析当前激活 tab 的 ConnectionConfig
|
||||
const activeConfig = useMemo<ConnectionConfig | null>(() => {
|
||||
if (!activeTabId) return null
|
||||
const tab = tabs.find(t => t.id === activeTabId)
|
||||
if (!tab?.connectionId) return null
|
||||
const conn = connections.find(c => c.id === tab.connectionId)
|
||||
if (!conn) return null
|
||||
return {
|
||||
...conn.config,
|
||||
port: Number(conn.config.port),
|
||||
password: conn.config.password || '',
|
||||
database: conn.config.database || '',
|
||||
useSSH: conn.config.useSSH || false,
|
||||
ssh: conn.config.ssh || { host: '', port: 22, user: '', password: '', keyPath: '' },
|
||||
} as ConnectionConfig
|
||||
}, [tabs, activeTabId, connections])
|
||||
|
||||
const activeTab = tabs.find(t => t.id === activeTabId)
|
||||
const dbName = activeTab?.dbName || ''
|
||||
|
||||
const buttonDisabled = !activeConfig
|
||||
const tooltipText = buttonDisabled
|
||||
? '请先打开一个数据库连接的查询标签'
|
||||
: '查看当前连接的慢 SQL 历史(Ctrl+Shift+L)'
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title={tooltipText} placement="right">
|
||||
<button
|
||||
type="button"
|
||||
className={className}
|
||||
onClick={() => !buttonDisabled && setOpen(true)}
|
||||
disabled={buttonDisabled}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 32,
|
||||
height: 32,
|
||||
border: 'none',
|
||||
background: 'transparent',
|
||||
cursor: buttonDisabled ? 'not-allowed' : 'pointer',
|
||||
color: buttonDisabled
|
||||
? 'var(--gn-text-muted, #adb5bd)'
|
||||
: 'var(--gn-text, #495057)',
|
||||
opacity: buttonDisabled ? 0.5 : 1,
|
||||
transition: 'opacity 0.15s, color 0.15s',
|
||||
...style,
|
||||
}}
|
||||
aria-label="慢 SQL 历史"
|
||||
>
|
||||
<HistoryOutlined style={{ fontSize: 16 }} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
||||
{open && activeConfig && (
|
||||
<Suspense fallback={null}>
|
||||
<SlowQueryPanel
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
config={activeConfig}
|
||||
dbName={dbName}
|
||||
/>
|
||||
</Suspense>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user