diff --git a/e2e/virtual-servers.spec.ts b/e2e/virtual-servers.spec.ts index 9022f902..b629c29b 100644 --- a/e2e/virtual-servers.spec.ts +++ b/e2e/virtual-servers.spec.ts @@ -1208,6 +1208,45 @@ test.describe("Virtual Servers page", () => { await expect(detailsPanel.getByText("github://repo/{owner}/{repo}")).toHaveCount(0); }); + test("filters components by source in the details panel when there are several", async ({ + page, + }) => { + await routeVirtualServerTryIt(page, [ + makeTryItTool(), + makeTryItTool({ + id: "tool-post", + name: "slack.post_message", + originalName: "post_message", + gatewayId: MOCK_MCP_SERVER_2.id, + }), + ]); + // Registered after the helper's route, so it takes precedence. + await page.route("**/v1/mcp-servers?*", async (route) => { + await route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify({ gateways: [MOCK_MCP_SERVER, MOCK_MCP_SERVER_2] }), + }); + }); + + await page.goto(APP.GATEWAYS); + await page.getByRole("button", { name: "Actions for testVS" }).click(); + await page.getByRole("menuitem", { name: "View details" }).click(); + + const panel = page.getByRole("region", { name: "testVS details" }); + await panel.getByRole("tab", { name: "Components" }).click(); + + await expect(panel.getByRole("tab", { name: "All sources" })).toBeVisible(); + await expect(panel.getByRole("tab", { name: "github-mcp" })).toBeVisible(); + await expect(panel.getByRole("tab", { name: "slack-mcp" })).toBeVisible(); + await expect(panel.getByText("search_issues")).toBeVisible(); + await expect(panel.getByText("post_message")).toBeVisible(); + + await panel.getByRole("tab", { name: "slack-mcp" }).click(); + await expect(panel.getByText("post_message")).toBeVisible(); + await expect(panel.getByText("search_issues")).toHaveCount(0); + }); + test("shows a tooltip with the full endpoint when it's truncated in the Try it tab", async ({ page, }) => { diff --git a/src/components/gateways/VirtualServerDetailsPanel.test.tsx b/src/components/gateways/VirtualServerDetailsPanel.test.tsx index 70e219c1..1f1a5f6f 100644 --- a/src/components/gateways/VirtualServerDetailsPanel.test.tsx +++ b/src/components/gateways/VirtualServerDetailsPanel.test.tsx @@ -295,6 +295,36 @@ describe("VirtualServerDetailsPanel components list", () => { expect(screen.getByRole("tab", { name: "Gateway A" })).toHaveFocus(); }); + it("hides the source selector when the server has a single source", async () => { + const user = userEvent.setup(); + mswServer.use( + http.get("*/v1/virtual-servers/:id/tools", () => + HttpResponse.json({ + tools: [{ id: "t1", name: "Tool One", originalName: "tool_one", gateway_id: "gwA" }], + }), + ), + http.get("*/v1/mcp-servers", () => + HttpResponse.json({ gateways: [{ id: "gwA", name: "Gateway A" }] }), + ), + ); + + render( + , + ); + + await user.click(await screen.findByRole("tab", { name: "Components" })); + expect(await screen.findByText("tool_one")).toBeInTheDocument(); + + expect(screen.queryByRole("tab", { name: "All sources" })).not.toBeInTheDocument(); + expect(screen.queryByRole("tab", { name: "Gateway A" })).not.toBeInTheDocument(); + }); + it("moves the active tab with arrow keys", async () => { const user = userEvent.setup(); renderWithComponents(); diff --git a/src/components/gateways/VirtualServerDetailsPanel.tsx b/src/components/gateways/VirtualServerDetailsPanel.tsx index 2b02ff4d..4cf81bae 100644 --- a/src/components/gateways/VirtualServerDetailsPanel.tsx +++ b/src/components/gateways/VirtualServerDetailsPanel.tsx @@ -399,9 +399,7 @@ export function VirtualServerDetailsPanel({ return `/v1/mcp-servers?${params}`; }, []); - const { data: sourcesData, isLoading: sourcesLoading } = useQuery< - MCPServersResponse | MCPServer[] - >(sourcesPath, { + const { data: sourcesData } = useQuery(sourcesPath, { enabled: fetchEnabled && sourceIds.length > 0, }); @@ -637,7 +635,7 @@ export function VirtualServerDetailsPanel({ /> ) : ( <> - {(sourcesLoading || sourceTabs.length > 0) && ( + {sourceTabs.length > 1 && (