diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 8745404d..171e3a2d 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -46,7 +46,6 @@ import { Tree, message, Dropdown, MenuProps, Input, Button, Form, Badge, Checkbo FolderAddOutlined, SaveOutlined, EditOutlined, - DownOutlined, SearchOutlined, KeyOutlined, ThunderboltOutlined, @@ -1190,18 +1189,6 @@ const Sidebar: React.FC<{ const allSavedQueriesNode = useMemo(() => { return buildAllSavedQueriesTreeNode(savedQueries, connections); }, [connections, savedQueries]); - const v2RailConnectionGroups = useMemo( - () => buildV2RailConnectionGroups(connections, connectionTags, sidebarRootOrder), - [connections, connectionTags, sidebarRootOrder], - ); - const [collapsedV2RailGroupIds, setCollapsedV2RailGroupIds] = useState([]); - const collapsedV2RailGroupIdSet = useMemo( - () => new Set(collapsedV2RailGroupIds), - [collapsedV2RailGroupIds], - ); - const hasV2RailConnectionGroups = v2RailConnectionGroups.some((group) => !group.isUngrouped); - const [draggingV2RailRootToken, setDraggingV2RailRootToken] = useState(''); - const snapshotTreeSelectionBeforeDrag = useCallback(() => { treeDragSelectionSnapshotRef.current = { selectedKeys: [...selectedKeys], @@ -6828,101 +6815,6 @@ const Sidebar: React.FC<{ return connectionStatusMap.get(connectionId) || 'idle'; }, [connectionStatusMap]); - const toggleV2RailConnectionGroup = useCallback((groupId: string) => { - setCollapsedV2RailGroupIds((prev) => ( - prev.includes(groupId) - ? prev.filter((id) => id !== groupId) - : [...prev, groupId] - )); - }, []); - - const handleV2RailRootDrop = useCallback(( - sourceToken: string, - targetToken: string, - insertBefore: boolean, - ) => { - if (!sourceToken || !targetToken || sourceToken === targetToken) { - return; - } - reorderSidebarRoot(sourceToken, targetToken, insertBefore); - }, [reorderSidebarRoot]); - - const getRailConnectionTypeLabel = (conn: SavedConnection): string => { - const iconType = resolveConnectionIconType(conn); - if (iconType === 'mysql' || iconType === 'mariadb' || iconType === 'oceanbase') return 'MY'; - if (iconType === 'postgres') return 'PG'; - if (iconType === 'gaussdb') return 'GS'; - if (iconType === 'redis') return 'R'; - if (iconType === 'mongodb') return 'MO'; - if (iconType === 'oracle') return 'OR'; - if (iconType === 'sqlserver') return 'SS'; - if (iconType === 'starrocks') return 'SR'; - if (iconType === 'sqlite') return 'SQ'; - if (iconType === 'jvm') return 'JV'; - return iconType.slice(0, 2).toUpperCase() || 'DB'; - }; - - const getRailConnectionHostLabel = (conn: SavedConnection): string => { - const hostTokens = resolveConnectionHostTokens(conn.config); - const primaryHost = String(hostTokens[0] || '').trim().replace(/^\[|\]$/g, ''); - if (primaryHost) { - if (/^(localhost|127(?:\.\d{1,3}){3}|0\.0\.0\.0)$/i.test(primaryHost)) { - return 'LO'; - } - if (/^\d{1,3}(?:\.\d{1,3}){3}$/.test(primaryHost)) { - const lastSegment = primaryHost.split('.').pop() || ''; - return lastSegment.slice(-3).toUpperCase() || 'IP'; - } - if (primaryHost.includes(':') && /^[a-f0-9:]+$/i.test(primaryHost)) { - const lastSegment = primaryHost.split(':').filter(Boolean).pop() || ''; - return lastSegment.slice(-3).toUpperCase() || 'IP'; - } - - const hostFragments = primaryHost - .split(/[^a-z0-9\u4e00-\u9fa5]+/i) - .map((entry) => entry.trim()) - .filter(Boolean); - if (hostFragments.length >= 2) { - return `${hostFragments[0][0] || ''}${hostFragments[1][0] || ''}`.toUpperCase(); - } - const hostToken = hostFragments[0] || primaryHost.split('.')[0] || ''; - if (hostToken) { - return hostToken.replace(/[^a-z0-9\u4e00-\u9fa5]/gi, '').slice(0, 3).toUpperCase() || 'DB'; - } - } - - return getRailConnectionTypeLabel(conn); - }; - - const getRailConnectionBadgeLabel = (conn: SavedConnection): string => { - const connectionName = String(conn.name || '').trim(); - const cjkParts = connectionName.match(/[\u4e00-\u9fa5]/g); - if (cjkParts && cjkParts.length > 0) { - return cjkParts.slice(0, 2).join(''); - } - - const latinTokens = connectionName.match(/[a-z0-9]+/gi) || []; - if (latinTokens.length >= 2) { - const firstToken = latinTokens[0] || ''; - const secondToken = latinTokens[1] || ''; - return `${firstToken[0] || ''}${secondToken[0] || ''}`.toUpperCase(); - } - if (latinTokens.length === 1) { - const token = latinTokens[0]; - const alphaPrefix = token.match(/^[a-z]+/i)?.[0] || ''; - if (alphaPrefix) { - return alphaPrefix.slice(0, 3).toUpperCase(); - } - const trailingDigits = token.match(/(\d{2,})$/)?.[1]; - if (trailingDigits) { - return trailingDigits.slice(-3).toUpperCase(); - } - return token.slice(0, 3).toUpperCase(); - } - - return getRailConnectionTypeLabel(conn); - }; - const openV2ConnectionContextMenu = ( event: React.MouseEvent, connOrNode: SavedConnection | TreeNode, @@ -8893,165 +8785,6 @@ const Sidebar: React.FC<{ } }; - const renderV2RailConnectionButton = (conn: SavedConnection) => { - const accent = resolveConnectionAccentColor(conn); - const status = buildRailConnectionStatus(conn.id); - const badgeLabel = getRailConnectionBadgeLabel(conn); - const hostLabel = getRailConnectionHostLabel(conn); - const title = `${conn.name} · ${resolveConnectionHostSummary(conn.config) || conn.config.type}`; - const rootToken = buildSidebarRootConnectionToken(conn.id); - - return ( - - - - ); - }; - - const renderV2RailConnectionGroup = (group: V2RailConnectionGroup) => { - const collapsed = collapsedV2RailGroupIdSet.has(group.id); - const groupTitle = group.name || t('connection.sidebar.group.untitled'); - const rootToken = group.rootToken; - - return ( -
{ - snapshotTreeSelectionBeforeDrag(); - treeDragSelectSuppressUntilRef.current = Date.now() + 600; - setDraggingV2RailRootToken(rootToken); - setIsTreeDragging(true); - event.dataTransfer.effectAllowed = 'move'; - event.dataTransfer.setData('text/plain', rootToken); - }} - onDragEnd={() => { - restoreTreeSelectionAfterDrag(); - setDraggingV2RailRootToken(''); - setIsTreeDragging(false); - }} - onDragOver={(event) => { - if (!draggingV2RailRootToken || draggingV2RailRootToken === rootToken) { - return; - } - event.preventDefault(); - event.stopPropagation(); - event.dataTransfer.dropEffect = 'move'; - }} - onDrop={(event) => { - if (!draggingV2RailRootToken || draggingV2RailRootToken === rootToken) { - return; - } - event.preventDefault(); - event.stopPropagation(); - const rect = event.currentTarget.getBoundingClientRect(); - const insertBefore = event.clientY < rect.top + rect.height / 2; - handleV2RailRootDrop(draggingV2RailRootToken, rootToken, insertBefore); - restoreTreeSelectionAfterDrag(); - setDraggingV2RailRootToken(''); - setIsTreeDragging(false); - }} - > - {hasV2RailConnectionGroups && ( - - - - )} - {!collapsed && ( -
- {group.connections.map(renderV2RailConnectionButton)} -
- )} -
- ); - }; - const v2RailObjectActionsLabel = t('sidebar.rail.object_actions'); const v2RailSystemActionsLabel = t('sidebar.rail.system_actions'); const v2NewGroupLabel = t('sidebar.action.new_group');