Fix ruff config: consolidate into pyproject.toml (#4755)
Co-authored-by: Suchintan Singh <suchintan@skyvern.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { ReloadIcon, CopyIcon, CheckIcon } from "@radix-ui/react-icons";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
@@ -40,6 +40,7 @@ type TestWebhookDialogProps = {
|
||||
runId?: string | null;
|
||||
initialWebhookUrl?: string;
|
||||
trigger?: React.ReactNode;
|
||||
autoRunOnOpen?: boolean;
|
||||
};
|
||||
|
||||
function TestWebhookDialog({
|
||||
@@ -47,6 +48,7 @@ function TestWebhookDialog({
|
||||
runId,
|
||||
initialWebhookUrl,
|
||||
trigger,
|
||||
autoRunOnOpen = true,
|
||||
}: TestWebhookDialogProps) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [targetUrl, setTargetUrl] = useState(initialWebhookUrl || "");
|
||||
@@ -123,14 +125,19 @@ function TestWebhookDialog({
|
||||
}
|
||||
};
|
||||
|
||||
// Only sync URL and optionally auto-run on the closed→open transition,
|
||||
// not when initialWebhookUrl changes while the dialog is already open
|
||||
const prevOpen = useRef(false);
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
return;
|
||||
if (open && !prevOpen.current) {
|
||||
const nextUrl = initialWebhookUrl || "";
|
||||
setTargetUrl(nextUrl);
|
||||
setResult(null);
|
||||
if (autoRunOnOpen) {
|
||||
void runTest(nextUrl);
|
||||
}
|
||||
}
|
||||
|
||||
const nextUrl = initialWebhookUrl || "";
|
||||
setTargetUrl(nextUrl);
|
||||
void runTest(nextUrl);
|
||||
prevOpen.current = open;
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [open, initialWebhookUrl]);
|
||||
|
||||
@@ -182,16 +189,28 @@ function TestWebhookDialog({
|
||||
<Input
|
||||
id="test-webhook-url"
|
||||
value={targetUrl}
|
||||
onChange={(event) => setTargetUrl(event.target.value)}
|
||||
onChange={(event) => {
|
||||
setTargetUrl(event.target.value);
|
||||
setResult(null);
|
||||
}}
|
||||
placeholder="https://your-endpoint.com/webhook"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{loading && !result ? (
|
||||
{loading ? (
|
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<ReloadIcon className="h-4 w-4 animate-spin" />
|
||||
Sending test webhook…
|
||||
</div>
|
||||
) : !result ? (
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => void runTest(targetUrl)}
|
||||
disabled={!targetUrl.trim()}
|
||||
variant="secondary"
|
||||
>
|
||||
Send Test Request
|
||||
</Button>
|
||||
) : null}
|
||||
|
||||
{result && (
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { ProxyLocation } from "@/api/types";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { HelpTooltip } from "@/components/HelpTooltip";
|
||||
@@ -76,6 +76,31 @@ function StartNode({ id, data, parentId }: NodeProps<StartNode>) {
|
||||
const toggleScriptForNodeCallback = useToggleScriptForNodeCallback();
|
||||
const isRecording = recordingStore.isRecording;
|
||||
|
||||
// Local state for webhook URL to fix race condition where data.webhookCallbackUrl
|
||||
// isn't updated yet when user clicks "Test Webhook" after typing
|
||||
const webhookCallbackUrl = data.withWorkflowSettings
|
||||
? data.webhookCallbackUrl
|
||||
: "";
|
||||
const [localWebhookUrl, setLocalWebhookUrl] = useState(webhookCallbackUrl);
|
||||
const prevWebhookUrl = useRef(webhookCallbackUrl);
|
||||
|
||||
// Sync from parent only on external changes (e.g., undo/redo), not our own updates
|
||||
useEffect(() => {
|
||||
if (!data.withWorkflowSettings) {
|
||||
setLocalWebhookUrl("");
|
||||
return;
|
||||
}
|
||||
|
||||
const parentChanged = webhookCallbackUrl !== prevWebhookUrl.current;
|
||||
const isExternalChange =
|
||||
parentChanged && localWebhookUrl === prevWebhookUrl.current;
|
||||
|
||||
if (isExternalChange) {
|
||||
setLocalWebhookUrl(webhookCallbackUrl);
|
||||
}
|
||||
prevWebhookUrl.current = webhookCallbackUrl;
|
||||
}, [data.withWorkflowSettings, webhookCallbackUrl, localWebhookUrl]);
|
||||
|
||||
const parentNode = parentId ? reactFlowInstance.getNode(parentId) : null;
|
||||
const isInsideConditional = parentNode?.type === "conditional";
|
||||
const isInsideLoop = parentNode?.type === "loop";
|
||||
@@ -222,9 +247,10 @@ function StartNode({ id, data, parentId }: NodeProps<StartNode>) {
|
||||
<div className="flex flex-col gap-2">
|
||||
<Input
|
||||
className="w-full"
|
||||
value={data.webhookCallbackUrl}
|
||||
value={localWebhookUrl}
|
||||
placeholder="https://"
|
||||
onChange={(event) => {
|
||||
setLocalWebhookUrl(event.target.value);
|
||||
update({
|
||||
webhookCallbackUrl: event.target.value,
|
||||
});
|
||||
@@ -233,15 +259,14 @@ function StartNode({ id, data, parentId }: NodeProps<StartNode>) {
|
||||
<TestWebhookDialog
|
||||
runType="workflow_run"
|
||||
runId={null}
|
||||
initialWebhookUrl={
|
||||
data.webhookCallbackUrl || undefined
|
||||
}
|
||||
initialWebhookUrl={localWebhookUrl || undefined}
|
||||
autoRunOnOpen={false}
|
||||
trigger={
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
className="self-start"
|
||||
disabled={!data.webhookCallbackUrl}
|
||||
disabled={!localWebhookUrl}
|
||||
>
|
||||
Test Webhook
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user