feat: show all block parameters including advanced settings in WR UI (#SKY-6813) (#4807)
This commit is contained in:
@@ -13,6 +13,7 @@ import { DebuggerSendEmailBlockParameters } from "./DebuggerSendEmailBlockInfo";
|
|||||||
import { ProxyLocation } from "@/api/types";
|
import { ProxyLocation } from "@/api/types";
|
||||||
import { KeyValueInput } from "@/components/KeyValueInput";
|
import { KeyValueInput } from "@/components/KeyValueInput";
|
||||||
import { HelpTooltip } from "@/components/HelpTooltip";
|
import { HelpTooltip } from "@/components/HelpTooltip";
|
||||||
|
import { Switch } from "@/components/ui/switch";
|
||||||
|
|
||||||
function DebuggerPostRunParameters() {
|
function DebuggerPostRunParameters() {
|
||||||
const { data: workflowRunTimeline, isLoading: workflowRunTimelineIsLoading } =
|
const { data: workflowRunTimeline, isLoading: workflowRunTimelineIsLoading } =
|
||||||
@@ -104,6 +105,127 @@ function DebuggerPostRunParameters() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
{activeBlock && activeBlock.block_type === WorkflowBlockTypes.Wait ? (
|
||||||
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h1 className="text-sm font-bold">Wait Block Parameters</h1>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex w-full items-center justify-start gap-2">
|
||||||
|
<h1 className="text-sm">Wait Duration</h1>
|
||||||
|
<HelpTooltip content="Seconds to wait before proceeding." />
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
value={
|
||||||
|
typeof activeBlock.wait_sec === "number"
|
||||||
|
? `${activeBlock.wait_sec}s`
|
||||||
|
: "N/A"
|
||||||
|
}
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock &&
|
||||||
|
activeBlock.block_type === WorkflowBlockTypes.HumanInteraction ? (
|
||||||
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h1 className="text-sm font-bold">
|
||||||
|
Human Interaction Block Parameters
|
||||||
|
</h1>
|
||||||
|
{activeBlock.instructions ? (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex w-full items-center justify-start gap-2">
|
||||||
|
<h1 className="text-sm">Instructions</h1>
|
||||||
|
<HelpTooltip content="Instructions for the human interaction." />
|
||||||
|
</div>
|
||||||
|
<AutoResizingTextarea
|
||||||
|
value={activeBlock.instructions}
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock.positive_descriptor ? (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<h1 className="text-sm">Positive Descriptor</h1>
|
||||||
|
<Input value={activeBlock.positive_descriptor} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock.negative_descriptor ? (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<h1 className="text-sm">Negative Descriptor</h1>
|
||||||
|
<Input value={activeBlock.negative_descriptor} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock &&
|
||||||
|
activeBlock.block_type === WorkflowBlockTypes.Conditional ? (
|
||||||
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h1 className="text-sm font-bold">Conditional Block Parameters</h1>
|
||||||
|
{activeBlock.executed_branch_expression ? (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex w-full items-center justify-start gap-2">
|
||||||
|
<h1 className="text-sm">Executed Expression</h1>
|
||||||
|
<HelpTooltip content="The branch expression that was evaluated." />
|
||||||
|
</div>
|
||||||
|
<AutoResizingTextarea
|
||||||
|
value={activeBlock.executed_branch_expression}
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{typeof activeBlock.executed_branch_result === "boolean" ? (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<h1 className="text-sm">Branch Result</h1>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Switch
|
||||||
|
checked={activeBlock.executed_branch_result}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
<span className="text-sm text-slate-400">
|
||||||
|
{activeBlock.executed_branch_result ? "True" : "False"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock.executed_branch_next_block ? (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<h1 className="text-sm">Next Block</h1>
|
||||||
|
<Input
|
||||||
|
value={activeBlock.executed_branch_next_block}
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock.executed_branch_id ? (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<h1 className="text-sm">Executed Branch ID</h1>
|
||||||
|
<Input value={activeBlock.executed_branch_id} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock &&
|
||||||
|
activeBlock.block_type === WorkflowBlockTypes.TextPrompt ? (
|
||||||
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h1 className="text-sm font-bold">Text Prompt Block Parameters</h1>
|
||||||
|
{activeBlock.prompt ? (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex w-full items-center justify-start gap-2">
|
||||||
|
<h1 className="text-sm">Prompt</h1>
|
||||||
|
<HelpTooltip content="Instructions passed to the selected LLM." />
|
||||||
|
</div>
|
||||||
|
<AutoResizingTextarea value={activeBlock.prompt} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
<div className="rounded bg-slate-elevation2 p-6">
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<h1 className="text-sm font-bold">Workflow Parameters</h1>
|
<h1 className="text-sm font-bold">Workflow Parameters</h1>
|
||||||
@@ -171,6 +293,27 @@ function DebuggerPostRunParameters() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{workflowRun.browser_session_id ? (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex w-full items-center justify-start gap-2">
|
||||||
|
<h1 className="text-sm">Browser Session ID</h1>
|
||||||
|
<HelpTooltip content="The browser session ID used for this run." />
|
||||||
|
</div>
|
||||||
|
<Input value={workflowRun.browser_session_id} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{workflowRun.max_screenshot_scrolls != null ? (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex w-full items-center justify-start gap-2">
|
||||||
|
<h1 className="text-sm">Max Screenshot Scrolls</h1>
|
||||||
|
<HelpTooltip content="Maximum number of screenshot scrolls." />
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
value={workflowRun.max_screenshot_scrolls.toString()}
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{workflowRun.task_v2 ? (
|
{workflowRun.task_v2 ? (
|
||||||
@@ -187,10 +330,6 @@ function DebuggerPostRunParameters() {
|
|||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<AutoResizingTextarea
|
|
||||||
value={workflowRun.task_v2?.prompt ?? ""}
|
|
||||||
readOnly
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -140,6 +140,29 @@ function DebuggerTaskBlockParameters({ block }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex w-full items-center justify-start gap-2">
|
||||||
|
<h1 className="text-sm">Continue on Failure</h1>
|
||||||
|
<HelpTooltip content="Whether to continue the workflow if this block fails" />
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Switch checked={block.continue_on_failure} disabled />
|
||||||
|
<span className="text-sm text-slate-400">
|
||||||
|
{block.continue_on_failure ? "Enabled" : "Disabled"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{block.engine ? (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<div className="flex w-full items-center justify-start gap-2">
|
||||||
|
<h1 className="text-sm">Engine</h1>
|
||||||
|
<HelpTooltip content="The execution engine used for this block" />
|
||||||
|
</div>
|
||||||
|
<Input value={block.engine} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ActionsApiResponse, Status } from "@/api/types";
|
import { ActionsApiResponse, RunEngine, Status } from "@/api/types";
|
||||||
import { isTaskVariantBlock, WorkflowBlockType } from "./workflowTypes";
|
import { isTaskVariantBlock, WorkflowBlockType } from "./workflowTypes";
|
||||||
import { ActionItem } from "../workflowRun/WorkflowRunOverview";
|
import { ActionItem } from "../workflowRun/WorkflowRunOverview";
|
||||||
|
|
||||||
@@ -41,6 +41,7 @@ export type WorkflowRunBlock = {
|
|||||||
terminate_criterion: string | null;
|
terminate_criterion: string | null;
|
||||||
complete_criterion: string | null;
|
complete_criterion: string | null;
|
||||||
include_action_history_in_verification: boolean | null;
|
include_action_history_in_verification: boolean | null;
|
||||||
|
engine: RunEngine | null;
|
||||||
actions: Array<ActionsApiResponse> | null;
|
actions: Array<ActionsApiResponse> | null;
|
||||||
recipients?: Array<string> | null;
|
recipients?: Array<string> | null;
|
||||||
attachments?: Array<string> | null;
|
attachments?: Array<string> | null;
|
||||||
|
|||||||
@@ -2,14 +2,19 @@ import { AutoResizingTextarea } from "@/components/AutoResizingTextarea/AutoResi
|
|||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { CodeEditor } from "@/routes/workflows/components/CodeEditor";
|
import { CodeEditor } from "@/routes/workflows/components/CodeEditor";
|
||||||
import { WorkflowRunBlock } from "../types/workflowRunTypes";
|
import { WorkflowRunBlock } from "../types/workflowRunTypes";
|
||||||
import { isTaskVariantBlock, WorkflowBlockTypes } from "../types/workflowTypes";
|
import {
|
||||||
|
isTaskVariantBlock,
|
||||||
|
WorkflowBlockTypes,
|
||||||
|
type WorkflowBlock,
|
||||||
|
} from "../types/workflowTypes";
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
block: WorkflowRunBlock;
|
block: WorkflowRunBlock;
|
||||||
|
definitionBlock?: WorkflowBlock | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
function TaskBlockParameters({ block }: Props) {
|
function TaskBlockParameters({ block, definitionBlock }: Props) {
|
||||||
const isTaskVariant = isTaskVariantBlock(block);
|
const isTaskVariant = isTaskVariantBlock(block);
|
||||||
if (!isTaskVariant) {
|
if (!isTaskVariant) {
|
||||||
return null;
|
return null;
|
||||||
@@ -32,6 +37,66 @@ function TaskBlockParameters({ block }: Props) {
|
|||||||
block.block_type === WorkflowBlockTypes.Task ||
|
block.block_type === WorkflowBlockTypes.Task ||
|
||||||
block.block_type === WorkflowBlockTypes.Navigation;
|
block.block_type === WorkflowBlockTypes.Navigation;
|
||||||
|
|
||||||
|
// Advanced settings from definition block
|
||||||
|
const errorCodeMapping =
|
||||||
|
definitionBlock &&
|
||||||
|
"error_code_mapping" in definitionBlock &&
|
||||||
|
definitionBlock.error_code_mapping
|
||||||
|
? definitionBlock.error_code_mapping
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const maxRetries =
|
||||||
|
definitionBlock && "max_retries" in definitionBlock
|
||||||
|
? definitionBlock.max_retries
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const maxStepsPerRun =
|
||||||
|
definitionBlock && "max_steps_per_run" in definitionBlock
|
||||||
|
? definitionBlock.max_steps_per_run
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const totpVerificationUrl =
|
||||||
|
definitionBlock && "totp_verification_url" in definitionBlock
|
||||||
|
? definitionBlock.totp_verification_url
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const totpIdentifier =
|
||||||
|
definitionBlock && "totp_identifier" in definitionBlock
|
||||||
|
? definitionBlock.totp_identifier
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const completeOnDownload =
|
||||||
|
definitionBlock && "complete_on_download" in definitionBlock
|
||||||
|
? definitionBlock.complete_on_download
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const downloadSuffix =
|
||||||
|
definitionBlock && "download_suffix" in definitionBlock
|
||||||
|
? definitionBlock.download_suffix
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const disableCache =
|
||||||
|
definitionBlock && "disable_cache" in definitionBlock
|
||||||
|
? definitionBlock.disable_cache
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const engine =
|
||||||
|
block.engine ??
|
||||||
|
(definitionBlock && "engine" in definitionBlock
|
||||||
|
? definitionBlock.engine
|
||||||
|
: null);
|
||||||
|
|
||||||
|
const hasAdvancedSettings =
|
||||||
|
errorCodeMapping !== null ||
|
||||||
|
typeof maxRetries === "number" ||
|
||||||
|
typeof maxStepsPerRun === "number" ||
|
||||||
|
Boolean(totpVerificationUrl) ||
|
||||||
|
Boolean(totpIdentifier) ||
|
||||||
|
completeOnDownload === true ||
|
||||||
|
Boolean(downloadSuffix) ||
|
||||||
|
disableCache === true ||
|
||||||
|
engine !== null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex gap-16">
|
<div className="flex gap-16">
|
||||||
@@ -151,6 +216,131 @@ function TaskBlockParameters({ block }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Continue on Failure</h1>
|
||||||
|
<h2 className="text-base text-slate-400">
|
||||||
|
Whether to continue the workflow if this block fails
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full items-center gap-3">
|
||||||
|
<Switch checked={block.continue_on_failure} disabled />
|
||||||
|
<span className="text-sm text-slate-400">
|
||||||
|
{block.continue_on_failure ? "Enabled" : "Disabled"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{hasAdvancedSettings ? (
|
||||||
|
<>
|
||||||
|
<h2 className="text-base font-semibold text-slate-300">
|
||||||
|
Advanced Settings
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
{engine ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Engine</h1>
|
||||||
|
<h2 className="text-base text-slate-400">
|
||||||
|
The execution engine used for this block
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<Input value={engine} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{errorCodeMapping ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Error Code Mapping</h1>
|
||||||
|
<h2 className="text-base text-slate-400">
|
||||||
|
Custom error codes and their descriptions
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<CodeEditor
|
||||||
|
className="w-full"
|
||||||
|
language="json"
|
||||||
|
value={JSON.stringify(errorCodeMapping, null, 2)}
|
||||||
|
readOnly
|
||||||
|
minHeight="96px"
|
||||||
|
maxHeight="200px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{typeof maxRetries === "number" ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Max Retries</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={maxRetries.toString()} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{typeof maxStepsPerRun === "number" ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Max Steps Per Run</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={maxStepsPerRun.toString()} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{totpVerificationUrl ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">TOTP Verification URL</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={totpVerificationUrl} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{totpIdentifier ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">TOTP Identifier</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={totpIdentifier} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{completeOnDownload === true ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Complete on Download</h1>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full items-center gap-3">
|
||||||
|
<Switch checked={true} disabled />
|
||||||
|
<span className="text-sm text-slate-400">Enabled</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{downloadSuffix ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Download Suffix</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={downloadSuffix} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{disableCache === true ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Cache Disabled</h1>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full items-center gap-3">
|
||||||
|
<Switch checked={true} disabled />
|
||||||
|
<span className="text-sm text-slate-400">
|
||||||
|
Cache is disabled for this block
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ import { CodeBlockParameters } from "./blockInfo/CodeBlockParameters";
|
|||||||
import { TextPromptBlockParameters } from "./blockInfo/TextPromptBlockParameters";
|
import { TextPromptBlockParameters } from "./blockInfo/TextPromptBlockParameters";
|
||||||
import { GotoUrlBlockParameters } from "./blockInfo/GotoUrlBlockParameters";
|
import { GotoUrlBlockParameters } from "./blockInfo/GotoUrlBlockParameters";
|
||||||
import { FileDownloadBlockParameters } from "./blockInfo/FileDownloadBlockParameters";
|
import { FileDownloadBlockParameters } from "./blockInfo/FileDownloadBlockParameters";
|
||||||
|
import { WaitBlockParameters } from "./blockInfo/WaitBlockParameters";
|
||||||
|
import { HttpRequestBlockParameters } from "./blockInfo/HttpRequestBlockParameters";
|
||||||
|
import { PrintPageBlockParameters } from "./blockInfo/PrintPageBlockParameters";
|
||||||
|
import { HumanInteractionBlockParameters } from "./blockInfo/HumanInteractionBlockParameters";
|
||||||
|
import { ConditionalBlockParameters } from "./blockInfo/ConditionalBlockParameters";
|
||||||
|
import { Taskv2BlockParameters } from "./blockInfo/Taskv2BlockParameters";
|
||||||
|
|
||||||
function WorkflowPostRunParameters() {
|
function WorkflowPostRunParameters() {
|
||||||
const { data: workflowRunTimeline, isLoading: workflowRunTimelineIsLoading } =
|
const { data: workflowRunTimeline, isLoading: workflowRunTimelineIsLoading } =
|
||||||
@@ -86,7 +92,10 @@ function WorkflowPostRunParameters() {
|
|||||||
<div className="rounded bg-slate-elevation2 p-6">
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<h1 className="text-lg font-bold">Block Parameters</h1>
|
<h1 className="text-lg font-bold">Block Parameters</h1>
|
||||||
<TaskBlockParameters block={activeBlock} />
|
<TaskBlockParameters
|
||||||
|
block={activeBlock}
|
||||||
|
definitionBlock={definitionBlock}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
@@ -191,6 +200,142 @@ function WorkflowPostRunParameters() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
{activeBlock && activeBlock.block_type === WorkflowBlockTypes.Wait ? (
|
||||||
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h1 className="text-lg font-bold">Wait Block</h1>
|
||||||
|
<WaitBlockParameters
|
||||||
|
waitSec={
|
||||||
|
activeBlock.wait_sec ??
|
||||||
|
(isBlockOfType(definitionBlock, WorkflowBlockTypes.Wait)
|
||||||
|
? definitionBlock.wait_sec ?? null
|
||||||
|
: null)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock &&
|
||||||
|
activeBlock.block_type === WorkflowBlockTypes.HttpRequest &&
|
||||||
|
isBlockOfType(definitionBlock, WorkflowBlockTypes.HttpRequest) ? (
|
||||||
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h1 className="text-lg font-bold">HTTP Request Block</h1>
|
||||||
|
<HttpRequestBlockParameters
|
||||||
|
method={definitionBlock.method}
|
||||||
|
url={definitionBlock.url}
|
||||||
|
headers={definitionBlock.headers}
|
||||||
|
body={definitionBlock.body}
|
||||||
|
files={definitionBlock.files}
|
||||||
|
timeout={definitionBlock.timeout}
|
||||||
|
followRedirects={definitionBlock.follow_redirects}
|
||||||
|
downloadFilename={definitionBlock.download_filename}
|
||||||
|
saveResponseAsFile={definitionBlock.save_response_as_file}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock &&
|
||||||
|
activeBlock.block_type === WorkflowBlockTypes.PrintPage &&
|
||||||
|
isBlockOfType(definitionBlock, WorkflowBlockTypes.PrintPage) ? (
|
||||||
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h1 className="text-lg font-bold">Print Page Block</h1>
|
||||||
|
<PrintPageBlockParameters
|
||||||
|
format={definitionBlock.format}
|
||||||
|
landscape={definitionBlock.landscape}
|
||||||
|
printBackground={definitionBlock.print_background}
|
||||||
|
includeTimestamp={definitionBlock.include_timestamp}
|
||||||
|
customFilename={definitionBlock.custom_filename}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock &&
|
||||||
|
activeBlock.block_type === WorkflowBlockTypes.HumanInteraction ? (
|
||||||
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h1 className="text-lg font-bold">Human Interaction Block</h1>
|
||||||
|
<HumanInteractionBlockParameters
|
||||||
|
instructions={
|
||||||
|
activeBlock.instructions ??
|
||||||
|
(isBlockOfType(
|
||||||
|
definitionBlock,
|
||||||
|
WorkflowBlockTypes.HumanInteraction,
|
||||||
|
)
|
||||||
|
? definitionBlock.instructions
|
||||||
|
: null)
|
||||||
|
}
|
||||||
|
positiveDescriptor={
|
||||||
|
activeBlock.positive_descriptor ??
|
||||||
|
(isBlockOfType(
|
||||||
|
definitionBlock,
|
||||||
|
WorkflowBlockTypes.HumanInteraction,
|
||||||
|
)
|
||||||
|
? definitionBlock.positive_descriptor
|
||||||
|
: null)
|
||||||
|
}
|
||||||
|
negativeDescriptor={
|
||||||
|
activeBlock.negative_descriptor ??
|
||||||
|
(isBlockOfType(
|
||||||
|
definitionBlock,
|
||||||
|
WorkflowBlockTypes.HumanInteraction,
|
||||||
|
)
|
||||||
|
? definitionBlock.negative_descriptor
|
||||||
|
: null)
|
||||||
|
}
|
||||||
|
timeoutSeconds={
|
||||||
|
isBlockOfType(
|
||||||
|
definitionBlock,
|
||||||
|
WorkflowBlockTypes.HumanInteraction,
|
||||||
|
)
|
||||||
|
? definitionBlock.timeout_seconds
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock &&
|
||||||
|
activeBlock.block_type === WorkflowBlockTypes.Conditional ? (
|
||||||
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h1 className="text-lg font-bold">Conditional Block</h1>
|
||||||
|
<ConditionalBlockParameters
|
||||||
|
branchConditions={
|
||||||
|
isBlockOfType(definitionBlock, WorkflowBlockTypes.Conditional)
|
||||||
|
? definitionBlock.branch_conditions
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
executedBranchId={activeBlock.executed_branch_id ?? null}
|
||||||
|
executedBranchExpression={
|
||||||
|
activeBlock.executed_branch_expression ?? null
|
||||||
|
}
|
||||||
|
executedBranchResult={activeBlock.executed_branch_result ?? null}
|
||||||
|
executedBranchNextBlock={
|
||||||
|
activeBlock.executed_branch_next_block ?? null
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{activeBlock &&
|
||||||
|
activeBlock.block_type === WorkflowBlockTypes.Taskv2 &&
|
||||||
|
isBlockOfType(definitionBlock, WorkflowBlockTypes.Taskv2) ? (
|
||||||
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h1 className="text-lg font-bold">Task v2 Block</h1>
|
||||||
|
<Taskv2BlockParameters
|
||||||
|
prompt={activeBlock.prompt ?? definitionBlock.prompt ?? ""}
|
||||||
|
url={activeBlock.url ?? definitionBlock.url}
|
||||||
|
maxSteps={definitionBlock.max_steps}
|
||||||
|
totpVerificationUrl={definitionBlock.totp_verification_url}
|
||||||
|
totpIdentifier={definitionBlock.totp_identifier}
|
||||||
|
disableCache={definitionBlock.disable_cache}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
<div className="rounded bg-slate-elevation2 p-6">
|
<div className="rounded bg-slate-elevation2 p-6">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<h1 className="text-lg font-bold">Workflow Input Parameters</h1>
|
<h1 className="text-lg font-bold">Workflow Input Parameters</h1>
|
||||||
@@ -252,6 +397,36 @@ function WorkflowPostRunParameters() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{workflowRun.browser_session_id ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Browser Session ID</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={workflowRun.browser_session_id} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{workflow?.run_with ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Run With</h1>
|
||||||
|
<h2 className="text-base text-slate-400">
|
||||||
|
Execution mode for this workflow
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<Input value={workflow.run_with} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{workflowRun.max_screenshot_scrolls != null ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Max Screenshot Scrolls</h1>
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
value={workflowRun.max_screenshot_scrolls.toString()}
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{workflowRun.task_v2 ? (
|
{workflowRun.task_v2 ? (
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
import { AutoResizingTextarea } from "@/components/AutoResizingTextarea/AutoResizingTextarea";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Switch } from "@/components/ui/switch";
|
||||||
|
import type { BranchCondition } from "@/routes/workflows/types/workflowTypes";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
branchConditions: Array<BranchCondition> | null;
|
||||||
|
executedBranchId: string | null;
|
||||||
|
executedBranchExpression: string | null;
|
||||||
|
executedBranchResult: boolean | null;
|
||||||
|
executedBranchNextBlock: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
function ConditionalBlockParameters({
|
||||||
|
branchConditions,
|
||||||
|
executedBranchId,
|
||||||
|
executedBranchExpression,
|
||||||
|
executedBranchResult,
|
||||||
|
executedBranchNextBlock,
|
||||||
|
}: Props) {
|
||||||
|
return (
|
||||||
|
<div className="space-y-4">
|
||||||
|
{executedBranchExpression ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Executed Expression</h1>
|
||||||
|
<h2 className="text-base text-slate-400">
|
||||||
|
The branch expression that was evaluated
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<AutoResizingTextarea value={executedBranchExpression} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{typeof executedBranchResult === "boolean" ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Branch Result</h1>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full items-center gap-3">
|
||||||
|
<Switch checked={executedBranchResult} disabled />
|
||||||
|
<span className="text-sm text-slate-400">
|
||||||
|
{executedBranchResult ? "True" : "False"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{executedBranchNextBlock ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Next Block</h1>
|
||||||
|
<h2 className="text-base text-slate-400">
|
||||||
|
The block that was executed after the condition
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<Input value={executedBranchNextBlock} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{executedBranchId ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Executed Branch ID</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={executedBranchId} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{branchConditions && branchConditions.length > 0 ? (
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h2 className="text-base font-semibold text-slate-300">
|
||||||
|
Branch Conditions
|
||||||
|
</h2>
|
||||||
|
{branchConditions.map((condition) => (
|
||||||
|
<div
|
||||||
|
key={condition.id}
|
||||||
|
className="space-y-2 rounded border border-slate-700/40 bg-slate-elevation3 p-3"
|
||||||
|
>
|
||||||
|
{condition.description ? (
|
||||||
|
<p className="text-sm text-slate-400">
|
||||||
|
{condition.description}
|
||||||
|
</p>
|
||||||
|
) : null}
|
||||||
|
{condition.criteria?.expression ? (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-sm font-medium">Expression:</span>
|
||||||
|
<code className="text-sm text-slate-300">
|
||||||
|
{condition.criteria.expression}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{condition.next_block_label ? (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-sm font-medium">Next Block:</span>
|
||||||
|
<span className="text-sm text-slate-300">
|
||||||
|
{condition.next_block_label}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{condition.is_default ? (
|
||||||
|
<span className="inline-block rounded bg-slate-700 px-2 py-0.5 text-xs">
|
||||||
|
Default
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { ConditionalBlockParameters };
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
import { AutoResizingTextarea } from "@/components/AutoResizingTextarea/AutoResizingTextarea";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Switch } from "@/components/ui/switch";
|
||||||
|
import { CodeEditor } from "@/routes/workflows/components/CodeEditor";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
method: string;
|
||||||
|
url: string | null;
|
||||||
|
headers: Record<string, string> | null;
|
||||||
|
body: Record<string, unknown> | null;
|
||||||
|
files: Record<string, string> | null;
|
||||||
|
timeout: number;
|
||||||
|
followRedirects: boolean;
|
||||||
|
downloadFilename: string | null;
|
||||||
|
saveResponseAsFile: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
function HttpRequestBlockParameters({
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
headers,
|
||||||
|
body,
|
||||||
|
files,
|
||||||
|
timeout,
|
||||||
|
followRedirects,
|
||||||
|
downloadFilename,
|
||||||
|
saveResponseAsFile,
|
||||||
|
}: Props) {
|
||||||
|
return (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Method</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={method} readOnly />
|
||||||
|
</div>
|
||||||
|
{url ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">URL</h1>
|
||||||
|
</div>
|
||||||
|
<AutoResizingTextarea value={url} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{headers && Object.keys(headers).length > 0 ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Headers</h1>
|
||||||
|
</div>
|
||||||
|
<CodeEditor
|
||||||
|
className="w-full"
|
||||||
|
language="json"
|
||||||
|
value={JSON.stringify(headers, null, 2)}
|
||||||
|
readOnly
|
||||||
|
minHeight="96px"
|
||||||
|
maxHeight="200px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{body && Object.keys(body).length > 0 ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Body</h1>
|
||||||
|
</div>
|
||||||
|
<CodeEditor
|
||||||
|
className="w-full"
|
||||||
|
language="json"
|
||||||
|
value={JSON.stringify(body, null, 2)}
|
||||||
|
readOnly
|
||||||
|
minHeight="96px"
|
||||||
|
maxHeight="200px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{files && Object.keys(files).length > 0 ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Files</h1>
|
||||||
|
<h2 className="text-base text-slate-400">
|
||||||
|
File fields and their paths/URLs
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<CodeEditor
|
||||||
|
className="w-full"
|
||||||
|
language="json"
|
||||||
|
value={JSON.stringify(files, null, 2)}
|
||||||
|
readOnly
|
||||||
|
minHeight="96px"
|
||||||
|
maxHeight="200px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Timeout</h1>
|
||||||
|
<h2 className="text-base text-slate-400">In seconds</h2>
|
||||||
|
</div>
|
||||||
|
<Input value={timeout.toString()} readOnly />
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Follow Redirects</h1>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full items-center gap-3">
|
||||||
|
<Switch checked={followRedirects} disabled />
|
||||||
|
<span className="text-sm text-slate-400">
|
||||||
|
{followRedirects ? "Enabled" : "Disabled"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{downloadFilename ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Download Filename</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={downloadFilename} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{saveResponseAsFile ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Save Response as File</h1>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full items-center gap-3">
|
||||||
|
<Switch checked={true} disabled />
|
||||||
|
<span className="text-sm text-slate-400">Enabled</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { HttpRequestBlockParameters };
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import { AutoResizingTextarea } from "@/components/AutoResizingTextarea/AutoResizingTextarea";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
instructions: string | null;
|
||||||
|
positiveDescriptor: string | null;
|
||||||
|
negativeDescriptor: string | null;
|
||||||
|
timeoutSeconds: number | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
function HumanInteractionBlockParameters({
|
||||||
|
instructions,
|
||||||
|
positiveDescriptor,
|
||||||
|
negativeDescriptor,
|
||||||
|
timeoutSeconds,
|
||||||
|
}: Props) {
|
||||||
|
return (
|
||||||
|
<div className="space-y-4">
|
||||||
|
{instructions ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Instructions</h1>
|
||||||
|
<h2 className="text-base text-slate-400">
|
||||||
|
Instructions for the human interaction
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<AutoResizingTextarea value={instructions} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{positiveDescriptor ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Positive Descriptor</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={positiveDescriptor} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{negativeDescriptor ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Negative Descriptor</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={negativeDescriptor} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{typeof timeoutSeconds === "number" ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Timeout</h1>
|
||||||
|
<h2 className="text-base text-slate-400">In seconds</h2>
|
||||||
|
</div>
|
||||||
|
<Input value={timeoutSeconds.toString()} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { HumanInteractionBlockParameters };
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Switch } from "@/components/ui/switch";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
format: string;
|
||||||
|
landscape: boolean;
|
||||||
|
printBackground: boolean;
|
||||||
|
includeTimestamp: boolean;
|
||||||
|
customFilename: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
function PrintPageBlockParameters({
|
||||||
|
format,
|
||||||
|
landscape,
|
||||||
|
printBackground,
|
||||||
|
includeTimestamp,
|
||||||
|
customFilename,
|
||||||
|
}: Props) {
|
||||||
|
return (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Format</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={format} readOnly />
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Landscape</h1>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full items-center gap-3">
|
||||||
|
<Switch checked={landscape} disabled />
|
||||||
|
<span className="text-sm text-slate-400">
|
||||||
|
{landscape ? "Enabled" : "Disabled"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Print Background</h1>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full items-center gap-3">
|
||||||
|
<Switch checked={printBackground} disabled />
|
||||||
|
<span className="text-sm text-slate-400">
|
||||||
|
{printBackground ? "Enabled" : "Disabled"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Include Timestamp</h1>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full items-center gap-3">
|
||||||
|
<Switch checked={includeTimestamp} disabled />
|
||||||
|
<span className="text-sm text-slate-400">
|
||||||
|
{includeTimestamp ? "Enabled" : "Disabled"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{customFilename ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Custom Filename</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={customFilename} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { PrintPageBlockParameters };
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import { AutoResizingTextarea } from "@/components/AutoResizingTextarea/AutoResizingTextarea";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Switch } from "@/components/ui/switch";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
prompt: string;
|
||||||
|
url: string | null;
|
||||||
|
maxSteps: number | null;
|
||||||
|
totpVerificationUrl: string | null;
|
||||||
|
totpIdentifier: string | null;
|
||||||
|
disableCache: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
function Taskv2BlockParameters({
|
||||||
|
prompt,
|
||||||
|
url,
|
||||||
|
maxSteps,
|
||||||
|
totpVerificationUrl,
|
||||||
|
totpIdentifier,
|
||||||
|
disableCache,
|
||||||
|
}: Props) {
|
||||||
|
return (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Prompt</h1>
|
||||||
|
<h2 className="text-base text-slate-400">
|
||||||
|
The instructions for this task
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<AutoResizingTextarea value={prompt} readOnly />
|
||||||
|
</div>
|
||||||
|
{url ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">URL</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={url} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{typeof maxSteps === "number" ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Max Steps</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={maxSteps.toString()} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{totpVerificationUrl ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">TOTP Verification URL</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={totpVerificationUrl} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{totpIdentifier ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">TOTP Identifier</h1>
|
||||||
|
</div>
|
||||||
|
<Input value={totpIdentifier} readOnly />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
{disableCache ? (
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Cache Disabled</h1>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full items-center gap-3">
|
||||||
|
<Switch checked={true} disabled />
|
||||||
|
<span className="text-sm text-slate-400">
|
||||||
|
Cache is disabled for this block
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Taskv2BlockParameters };
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
waitSec: number | null | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
function WaitBlockParameters({ waitSec }: Props) {
|
||||||
|
return (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="flex gap-16">
|
||||||
|
<div className="w-80">
|
||||||
|
<h1 className="text-lg">Wait Duration</h1>
|
||||||
|
<h2 className="text-base text-slate-400">
|
||||||
|
Seconds to wait before proceeding
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
value={typeof waitSec === "number" ? `${waitSec}s` : "N/A"}
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { WaitBlockParameters };
|
||||||
Reference in New Issue
Block a user