mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-13 17:18:08 -05:00
Compare commits
2 Commits
fix/creden
...
codex/fix-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
696c3bbbce | ||
|
|
0861e4a759 |
@@ -18,6 +18,7 @@ import {
|
||||
BlockIOSubSchema,
|
||||
BlockUIType,
|
||||
Category,
|
||||
Node,
|
||||
NodeExecutionResult,
|
||||
} from "@/lib/autogpt-server-api";
|
||||
import {
|
||||
@@ -81,6 +82,7 @@ export type CustomNodeData = {
|
||||
outputSchema: BlockIORootSchema;
|
||||
hardcodedValues: { [key: string]: any };
|
||||
connections: ConnectionData;
|
||||
webhook?: Node["webhook"];
|
||||
isOutputOpen: boolean;
|
||||
status?: NodeExecutionResult["status"];
|
||||
/** executionResults contains outputs across multiple executions
|
||||
@@ -910,6 +912,39 @@ export const CustomNode = React.memo(
|
||||
</span>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
{data.uiType === BlockUIType.WEBHOOK_MANUAL && (
|
||||
<>
|
||||
{data.webhook ? (
|
||||
<div className="nodrag mr-5 flex flex-col gap-1">
|
||||
Webhook URL:
|
||||
<div className="flex gap-2 rounded-md bg-gray-50 p-2">
|
||||
<code className="select-all break-all text-sm">
|
||||
{data.webhook.url}
|
||||
</code>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="size-7 flex-none"
|
||||
onClick={() =>
|
||||
data.webhook &&
|
||||
navigator.clipboard.writeText(
|
||||
data.webhook.url,
|
||||
)
|
||||
}
|
||||
title="Copy webhook URL"
|
||||
>
|
||||
<CopyIcon className="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<p className="italic text-gray-500">
|
||||
(A Webhook URL will be generated when you save the
|
||||
agent)
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<div className="pointer-events-none opacity-50">
|
||||
{generateInputHandles(data.inputSchema, data.uiType)}
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
"use client";
|
||||
|
||||
import { ReactFlow, ReactFlowProvider } from "@xyflow/react";
|
||||
import {
|
||||
CustomNode,
|
||||
type CustomNode as FlowNode,
|
||||
type CustomNodeData,
|
||||
} from "@/app/(platform)/build/components/legacy-builder/CustomNode/CustomNode";
|
||||
import { BuilderContext } from "@/app/(platform)/build/components/legacy-builder/Flow/Flow";
|
||||
import {
|
||||
BlockUIType,
|
||||
type Category,
|
||||
type Node as GraphNode,
|
||||
} from "@/lib/autogpt-server-api";
|
||||
import { useMemo } from "react";
|
||||
|
||||
const mockCategories: Category[] = [
|
||||
{
|
||||
category: "triggers",
|
||||
description: "Trigger block",
|
||||
},
|
||||
];
|
||||
|
||||
const mockWebhook: NonNullable<GraphNode["webhook"]> = {
|
||||
id: "webhook-manual-123",
|
||||
url: "https://hooks.autogpt.io/very/long/path/that/should/wrap/properly/when/rendered/in/the/manual/webhook/block/and-demonstrate-that-break-all-is-working/callback?id=1234567890abcdefghijklmnopqrstuvwxyz",
|
||||
provider: "http",
|
||||
credentials_id: "",
|
||||
webhook_type: "manual",
|
||||
resource: "generic",
|
||||
events: ["POST"],
|
||||
secret: "****",
|
||||
config: {},
|
||||
};
|
||||
|
||||
const mockNodeData: CustomNodeData = {
|
||||
blockType: "WebhookManualBlock",
|
||||
blockCosts: [],
|
||||
title: "Generic Webhook (Manual)",
|
||||
description: "Trigger flows manually via incoming POST requests.",
|
||||
categories: mockCategories,
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {},
|
||||
required: [],
|
||||
},
|
||||
outputSchema: {
|
||||
type: "object",
|
||||
properties: {},
|
||||
required: [],
|
||||
},
|
||||
hardcodedValues: {},
|
||||
connections: [],
|
||||
webhook: mockWebhook,
|
||||
isOutputOpen: false,
|
||||
uiType: BlockUIType.WEBHOOK_MANUAL,
|
||||
block_id: "manual-webhook-block",
|
||||
executionResults: [],
|
||||
errors: {},
|
||||
metadata: {},
|
||||
};
|
||||
|
||||
const mockBuilderContext = {
|
||||
libraryAgent: null,
|
||||
visualizeBeads: "no" as const,
|
||||
setIsAnyModalOpen: () => undefined,
|
||||
getNextNodeId: () => "mock-node-id",
|
||||
getNodeTitle: () => mockNodeData.title,
|
||||
};
|
||||
|
||||
export default function WebhookTriggerPreviewPage() {
|
||||
const nodeData = useMemo(
|
||||
() => ({
|
||||
...mockNodeData,
|
||||
inputSchema: { ...mockNodeData.inputSchema },
|
||||
outputSchema: { ...mockNodeData.outputSchema },
|
||||
hardcodedValues: { ...mockNodeData.hardcodedValues },
|
||||
connections: [...mockNodeData.connections],
|
||||
categories: mockNodeData.categories.map((category) => ({ ...category })),
|
||||
executionResults: mockNodeData.executionResults
|
||||
? [...mockNodeData.executionResults]
|
||||
: mockNodeData.executionResults,
|
||||
webhook: mockNodeData.webhook
|
||||
? { ...mockNodeData.webhook }
|
||||
: mockNodeData.webhook,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
const nodes = useMemo<FlowNode[]>(
|
||||
() => [
|
||||
{
|
||||
id: "manual-webhook-node",
|
||||
type: "custom",
|
||||
position: { x: 0, y: 0 },
|
||||
data: nodeData,
|
||||
},
|
||||
],
|
||||
[nodeData],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center bg-gray-100 p-8">
|
||||
<ReactFlowProvider>
|
||||
<BuilderContext.Provider value={mockBuilderContext}>
|
||||
<div className="h-[600px] w-[640px] rounded-2xl bg-white p-6 shadow-lg">
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={[]}
|
||||
nodeTypes={{ custom: CustomNode }}
|
||||
panOnScroll={false}
|
||||
zoomOnScroll={false}
|
||||
nodesDraggable={false}
|
||||
nodesConnectable={false}
|
||||
elementsSelectable={false}
|
||||
fitView
|
||||
fitViewOptions={{ padding: 0.2 }}
|
||||
/>
|
||||
</div>
|
||||
</BuilderContext.Provider>
|
||||
</ReactFlowProvider>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
17
autogpt_platform/frontend/src/tests/webhook-trigger.spec.ts
Normal file
17
autogpt_platform/frontend/src/tests/webhook-trigger.spec.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
const ROUTE = "/playwright/webhook-trigger";
|
||||
|
||||
test.describe("Webhook manual block", () => {
|
||||
test("wraps long webhook URLs without overflow", async ({ page }) => {
|
||||
await page.goto(ROUTE);
|
||||
|
||||
const block = page.locator('[data-blockid="manual-webhook-block"]');
|
||||
await expect(block).toBeVisible();
|
||||
|
||||
const webhookUrl = block.locator("code");
|
||||
await expect(webhookUrl).toContainText("https://hooks.autogpt.io/");
|
||||
|
||||
await expect(block).toHaveScreenshot("webhook-manual-block.png");
|
||||
});
|
||||
});
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
Reference in New Issue
Block a user