/** * OpsxAPI 工作台入口:组装顶栏 / 侧栏 / 标签页 / 编辑器 / 对话框。 */ import { findNode } from "@opsxapi/core"; import { useEffect } from "react"; import { closeSession } from "./send"; import { Icon } from "./components/icons"; import { Logo } from "./components/Logo"; import { useWorkspace } from "./workspaceStore"; import { Sidebar } from "./components/Sidebar"; import { TestingView } from "./components/TestingView"; import { startScheduler, stopScheduler } from "./scheduler"; import { TabBar } from "./components/TabBar"; import { TopBar } from "./components/TopBar"; import { GraphqlEditor } from "./components/editors/GraphqlEditor"; import { HttpEditor } from "./components/editors/HttpEditor"; import { MqttEditor } from "./components/editors/MqttEditor"; import { SocketIoEditor } from "./components/editors/SocketIoEditor"; import { SseEditor } from "./components/editors/SseEditor"; import { WebsocketEditor } from "./components/editors/WebsocketEditor"; import { ExportDialog } from "./components/dialogs/ExportDialog"; import { ImportDialog } from "./components/dialogs/ImportDialog"; import { AuthDialog, TeamDialog } from "./components/dialogs/AccountDialogs"; import { EnvironmentsDialog, NewItemDialog, RenameDialog, SettingsDialog, } from "./components/dialogs/WorkspaceDialogs"; export function OpsxWorkspace() { const init = useWorkspace((s) => s.init); const inited = useWorkspace((s) => s.collections.length > 0 || s.environments.length > 0); const collections = useWorkspace((s) => s.collections); const activeTabId = useWorkspace((s) => s.activeTabId); const dialog = useWorkspace((s) => s.dialog); const openTab = useWorkspace((s) => s.openTab); const view = useWorkspace((s) => s.view); useEffect(() => { init(); }, [init]); // 关闭标签页时断开实时会话 useEffect(() => { useWorkspace.subscribe((state, prev) => { const closed = prev.openTabIds.filter((id) => !state.openTabIds.includes(id)); for (const id of closed) closeSession(id); }); }, []); // 定时任务调度器(应用运行期间常驻) useEffect(() => { startScheduler(); return () => stopScheduler(); }, []); const activeRef = activeTabId ? findNode(collections, activeTabId) : null; const activeNode = activeRef?.node; return (
{view === "testing" ? ( ) : (
{inited && activeNode === undefined && ( collections[0] && openTab(collections[0].id)} /> )} {activeNode && activeNode.type === "request" && ( <> {activeNode.kind === "http" && } {activeNode.kind === "graphql" && } {activeNode.kind === "websocket" && } {activeNode.kind === "sse" && } {activeNode.kind === "socketio" && } {activeNode.kind === "mqtt" && } )} {activeNode && activeNode.type === "folder" && ( undefined} /> )}
)} {dialog?.type === "new" && } {dialog?.type === "import" && } {dialog?.type === "export" && } {dialog?.type === "environments" && } {dialog?.type === "settings" && } {dialog?.type === "rename" && } {dialog?.type === "auth" && } {dialog?.type === "team" && }
); } function EmptyState({ onQuick }: { onQuick: (kind: string) => void }) { const setDialog = useWorkspace((s) => s.setDialog); void onQuick; return (
OpsxAPI · 接口工作台
从左侧选择接口,或 /
HTTP · GraphQL · WebSocket · SSE · Socket.IO · MQTT
支持 OpenAPI / Postman / Apifox / cURL / HAR 等格式导入导出
); }