import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { useStudioStore } from '../store'; import { useShallow } from 'zustand/shallow'; import { FolderClosed, FolderOpen, Search, List } from 'lucide-react'; import { useState, useMemo, useEffect } from 'react'; interface RouteItem { id: string; path?: string; key?: string; description?: string; metadata?: Record; } interface GroupedRoutes { [group: string]: RouteItem[]; } type TabType = 'grouped' | 'all'; export const RouterGroupDialog = () => { const { showRouterGroup, setShowRouterGroup, routes, allRoutes, searchRoutes, setShowFilter, getAllRoutes } = useStudioStore( useShallow((state) => ({ showRouterGroup: state.showRouterGroup, setShowRouterGroup: state.setShowRouterGroup, routes: state.routes, allRoutes: state.allRoutes, searchRoutes: state.searchRoutes, setShowFilter: state.setShowFilter, getAllRoutes: state.getAllRoutes, })) ); const [expandedGroups, setExpandedGroups] = useState>(new Set()); const [activeTab, setActiveTab] = useState('grouped'); useEffect(() => { if (showRouterGroup && activeTab === 'all') { getAllRoutes(); } }, [showRouterGroup, activeTab, getAllRoutes]); const displayRoutes = activeTab === 'grouped' ? routes : allRoutes; // 按 path 分组 const groupedRoutes = useMemo(() => { const groups: GroupedRoutes = {}; displayRoutes.forEach((route: RouteItem) => { if (!route.path) return; // 获取第一级路径作为分组 const firstSegment = route.path.split('/').filter(Boolean)[0] || 'root'; if (!groups[firstSegment]) { groups[firstSegment] = []; } groups[firstSegment].push(route); }); return groups; }, [displayRoutes]); const toggleGroup = (group: string) => { const newExpanded = new Set(expandedGroups); if (newExpanded.has(group)) { newExpanded.delete(group); } else { newExpanded.add(group); } setExpandedGroups(newExpanded); }; const handleSearchByPath = (e: React.MouseEvent, path: string) => { e.stopPropagation(); const keyword = `WHERE path='${path}'`; searchRoutes(keyword); setShowFilter(true); setShowRouterGroup(false); }; const handleSearchByKey = (e: React.MouseEvent, path: string, key: string) => { e.stopPropagation(); const keyword = `WHERE path='${path}' AND key='${key}'`; searchRoutes(keyword); setShowFilter(true); setShowRouterGroup(false); }; const sortedGroups = Object.keys(groupedRoutes).sort(); const renderRouteItem = (route: RouteItem) => (
{route.path} {route.key && ( <> / {route.key} )}
{route.description && ( {route.description} )}
); const renderGroup = (group: string) => { const isExpanded = expandedGroups.has(group); const groupRoutes = groupedRoutes[group]; // 使用分组的第一个路由的完整 path 作为搜索关键词 const searchPath = groupRoutes[0]?.path || `/${group}`; return (
toggleGroup(group)} > {isExpanded ? ( ) : ( )} /{group} ({groupRoutes.length} 个路由)
{isExpanded && (
{groupRoutes.map(renderRouteItem)}
)}
); }; return ( 路由分组 {/* Tabs */}
{sortedGroups.length === 0 ? (
{activeTab === 'all' && allRoutes.length === 0 ? '加载中...' : '暂无路由数据'}
) : ( sortedGroups.map(renderGroup) )}
); };