Add debug/play button to HTTP Request workflow block (#4265)

This commit is contained in:
Marc Kelechava
2025-12-10 15:43:23 -08:00
committed by GitHub
parent 3e9246cb65
commit a9058d1292
2 changed files with 17 additions and 37 deletions

View File

@@ -6,19 +6,16 @@ import {
} from "@/components/ui/accordion"; } from "@/components/ui/accordion";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import { useDeleteNodeCallback } from "@/routes/workflows/hooks/useDeleteNodeCallback";
import { useNodeLabelChangeHandler } from "@/routes/workflows/hooks/useLabelChangeHandler"; import { useNodeLabelChangeHandler } from "@/routes/workflows/hooks/useLabelChangeHandler";
import { Handle, NodeProps, Position, useEdges, useNodes } from "@xyflow/react"; import { Handle, NodeProps, Position, useEdges, useNodes } from "@xyflow/react";
import { useCallback } from "react"; import { useCallback } from "react";
import { EditableNodeTitle } from "../components/EditableNodeTitle"; import { NodeHeader } from "../components/NodeHeader";
import { NodeActionMenu } from "../NodeActionMenu"; import type { WorkflowBlockType } from "@/routes/workflows/types/workflowTypes";
import type { HttpRequestNode as HttpRequestNodeType } from "./types"; import type { HttpRequestNode as HttpRequestNodeType } from "./types";
import { HelpTooltip } from "@/components/HelpTooltip"; import { HelpTooltip } from "@/components/HelpTooltip";
import { Switch } from "@/components/ui/switch"; import { Switch } from "@/components/ui/switch";
import { placeholders, helpTooltips } from "../../helpContent"; import { placeholders, helpTooltips } from "../../helpContent";
import { WorkflowBlockInputTextarea } from "@/components/WorkflowBlockInputTextarea"; import { WorkflowBlockInputTextarea } from "@/components/WorkflowBlockInputTextarea";
import { WorkflowBlockIcon } from "../WorkflowBlockIcon";
import { WorkflowBlockTypes } from "@/routes/workflows/types/workflowTypes";
import { AppNode } from ".."; import { AppNode } from "..";
import { getAvailableOutputParameterKeys } from "../../workflowEditorUtils"; import { getAvailableOutputParameterKeys } from "../../workflowEditorUtils";
import { ParametersMultiSelect } from "../TaskNode/ParametersMultiSelect"; import { ParametersMultiSelect } from "../TaskNode/ParametersMultiSelect";
@@ -64,13 +61,12 @@ const timeoutTooltip = "Request timeout in seconds.";
const followRedirectsTooltip = const followRedirectsTooltip =
"Whether to automatically follow HTTP redirects."; "Whether to automatically follow HTTP redirects.";
function HttpRequestNode({ id, data }: NodeProps<HttpRequestNodeType>) { function HttpRequestNode({ id, data, type }: NodeProps<HttpRequestNodeType>) {
const { editable } = data; const { editable } = data;
const [label, setLabel] = useNodeLabelChangeHandler({ const [label] = useNodeLabelChangeHandler({
id, id,
initialValue: data.label, initialValue: data.label,
}); });
const deleteNodeCallback = useDeleteNodeCallback();
const rerender = useRerender({ prefix: "accordian" }); const rerender = useRerender({ prefix: "accordian" });
const nodes = useNodes<AppNode>(); const nodes = useNodes<AppNode>();
const edges = useEdges(); const edges = useEdges();
@@ -139,27 +135,14 @@ function HttpRequestNode({ id, data }: NodeProps<HttpRequestNodeType>) {
className="opacity-0" className="opacity-0"
/> />
<div className="w-[36rem] space-y-4 rounded-lg bg-slate-elevation3 px-6 py-4"> <div className="w-[36rem] space-y-4 rounded-lg bg-slate-elevation3 px-6 py-4">
<header className="flex h-[2.75rem] justify-between"> <NodeHeader
<div className="flex gap-2"> blockLabel={label}
<div className="flex h-[2.75rem] w-[2.75rem] items-center justify-center rounded border border-slate-600"> editable={editable}
<WorkflowBlockIcon nodeId={id}
workflowBlockType={WorkflowBlockTypes.HttpRequest} totpIdentifier={null}
className="size-6" totpUrl={null}
/> type={type as WorkflowBlockType}
</div> extraActions={
<div className="flex flex-col gap-1">
<EditableNodeTitle
value={label}
editable={editable}
onChange={setLabel}
titleClassName="text-base"
inputClassName="text-base"
/>
<span className="text-xs text-slate-400">HTTP Request Block</span>
</div>
</div>
<div className="flex gap-2">
{/* Quick Action Buttons */}
<CurlImportDialog onImport={handleCurlImport}> <CurlImportDialog onImport={handleCurlImport}>
<Button <Button
variant="outline" variant="outline"
@@ -171,14 +154,8 @@ function HttpRequestNode({ id, data }: NodeProps<HttpRequestNodeType>) {
Import cURL Import cURL
</Button> </Button>
</CurlImportDialog> </CurlImportDialog>
}
<NodeActionMenu />
onDelete={() => {
deleteNodeCallback(id);
}}
/>
</div>
</header>
<div className="space-y-4"> <div className="space-y-4">
{/* Method and URL Section */} {/* Method and URL Section */}

View File

@@ -64,6 +64,7 @@ interface Props {
blockLabel: string; // today, this + wpid act as the identity of a block blockLabel: string; // today, this + wpid act as the identity of a block
disabled?: boolean; disabled?: boolean;
editable: boolean; editable: boolean;
extraActions?: React.ReactNode;
nodeId: string; nodeId: string;
totpIdentifier: string | null; totpIdentifier: string | null;
totpUrl: string | null; totpUrl: string | null;
@@ -156,6 +157,7 @@ function NodeHeader({
blockLabel, blockLabel,
disabled = false, disabled = false,
editable, editable,
extraActions,
nodeId, nodeId,
totpIdentifier, totpIdentifier,
totpUrl, totpUrl,
@@ -563,6 +565,7 @@ function NodeHeader({
</div> </div>
</div> </div>
<div className="pointer-events-auto ml-auto flex items-center gap-2"> <div className="pointer-events-auto ml-auto flex items-center gap-2">
{extraActions}
{thisBlockIsPlaying && ( {thisBlockIsPlaying && (
<div className="ml-auto"> <div className="ml-auto">
<button className="rounded p-1 hover:bg-red-500 hover:text-black disabled:opacity-50"> <button className="rounded p-1 hover:bg-red-500 hover:text-black disabled:opacity-50">