/** * 请求标签页栏。 */ import { KIND_LABELS, findNode } from "@opsxapi/core"; import { useState } from "react"; import { useWorkspace } from "../workspaceStore"; import { ContextMenu, cx, type MenuItem } from "./common"; import { Icon, type IconName } from "./icons"; const KIND_TAB_ICON: Record = { graphql: "hexagon", websocket: "zap", sse: "radio", socketio: "plug-zap", mqtt: "mailbox", }; export function TabBar() { const collections = useWorkspace((s) => s.collections); const openTabIds = useWorkspace((s) => s.openTabIds); const activeTabId = useWorkspace((s) => s.activeTabId); const setActiveTab = useWorkspace((s) => s.setActiveTab); const closeTab = useWorkspace((s) => s.closeTab); const closeOtherTabs = useWorkspace((s) => s.closeOtherTabs); const [menu, setMenu] = useState<{ x: number; y: number; id: string } | null>(null); const nodes = openTabIds .map((id) => findNode(collections, id)?.node) .filter((n): n is NonNullable => Boolean(n)); const menuItems = (id: string): MenuItem[] => [ { label: "关闭", onClick: () => closeTab(id) }, { label: "关闭其他", onClick: () => closeOtherTabs(id) }, { label: "关闭全部", onClick: () => { for (const n of nodes) closeTab(n.id); }, }, ]; return (
{ if (e.target === e.currentTarget) e.preventDefault(); }} > {nodes.length === 0 && (
没有打开的请求
)} {nodes.map((node) => { const active = node.id === activeTabId; const runtime = useWorkspace.getState().runtime[node.id]; const busy = runtime?.loading || runtime?.status === "connecting" || runtime?.status === "open"; return (
setActiveTab(node.id)} onAuxClick={(e) => e.button === 1 && closeTab(node.id)} onContextMenu={(e) => { e.preventDefault(); setMenu({ x: e.clientX, y: e.clientY, id: node.id }); }} title={node.name} > {node.type === "request" && node.kind === "http" ? ( {node.data.method} ) : node.type === "request" ? ( ) : null} {node.name} {busy && }
); })} setMenu(null)} />
); }