enable code view for taskv2 block (#3443)
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Flippable } from "@/components/Flippable";
|
||||||
import { HelpTooltip } from "@/components/HelpTooltip";
|
import { HelpTooltip } from "@/components/HelpTooltip";
|
||||||
import { WorkflowBlockInputTextarea } from "@/components/WorkflowBlockInputTextarea";
|
import { WorkflowBlockInputTextarea } from "@/components/WorkflowBlockInputTextarea";
|
||||||
import {
|
import {
|
||||||
@@ -10,7 +12,6 @@ import { Input } from "@/components/ui/input";
|
|||||||
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 { Handle, NodeProps, Position, useReactFlow } from "@xyflow/react";
|
import { Handle, NodeProps, Position, useReactFlow } from "@xyflow/react";
|
||||||
import { useState } from "react";
|
|
||||||
import { helpTooltips, placeholders } from "../../helpContent";
|
import { helpTooltips, placeholders } from "../../helpContent";
|
||||||
import { useIsFirstBlockInWorkflow } from "../../hooks/useIsFirstNodeInWorkflow";
|
import { useIsFirstBlockInWorkflow } from "../../hooks/useIsFirstNodeInWorkflow";
|
||||||
import { MAX_STEPS_DEFAULT, type Taskv2Node } from "./types";
|
import { MAX_STEPS_DEFAULT, type Taskv2Node } from "./types";
|
||||||
@@ -22,6 +23,8 @@ import { useParams } from "react-router-dom";
|
|||||||
import { statusIsRunningOrQueued } from "@/routes/tasks/types";
|
import { statusIsRunningOrQueued } from "@/routes/tasks/types";
|
||||||
import { useWorkflowRunQuery } from "@/routes/workflows/hooks/useWorkflowRunQuery";
|
import { useWorkflowRunQuery } from "@/routes/workflows/hooks/useWorkflowRunQuery";
|
||||||
import { useRerender } from "@/hooks/useRerender";
|
import { useRerender } from "@/hooks/useRerender";
|
||||||
|
import { BlockCodeEditor } from "@/routes/workflows/components/BlockCodeEditor";
|
||||||
|
import { useBlockScriptStore } from "@/store/BlockScriptStore";
|
||||||
|
|
||||||
function Taskv2Node({ id, data, type }: NodeProps<Taskv2Node>) {
|
function Taskv2Node({ id, data, type }: NodeProps<Taskv2Node>) {
|
||||||
const { editable, label } = data;
|
const { editable, label } = data;
|
||||||
@@ -34,6 +37,9 @@ function Taskv2Node({ id, data, type }: NodeProps<Taskv2Node>) {
|
|||||||
const thisBlockIsPlaying =
|
const thisBlockIsPlaying =
|
||||||
workflowRunIsRunningOrQueued && thisBlockIsTargetted;
|
workflowRunIsRunningOrQueued && thisBlockIsTargetted;
|
||||||
const { updateNodeData } = useReactFlow();
|
const { updateNodeData } = useReactFlow();
|
||||||
|
const [facing, setFacing] = useState<"front" | "back">("front");
|
||||||
|
const blockScriptStore = useBlockScriptStore();
|
||||||
|
const script = blockScriptStore.scripts[label];
|
||||||
const isFirstWorkflowBlock = useIsFirstBlockInWorkflow({ id });
|
const isFirstWorkflowBlock = useIsFirstBlockInWorkflow({ id });
|
||||||
const rerender = useRerender({ prefix: "accordian" });
|
const rerender = useRerender({ prefix: "accordian" });
|
||||||
|
|
||||||
@@ -54,151 +60,161 @@ function Taskv2Node({ id, data, type }: NodeProps<Taskv2Node>) {
|
|||||||
updateNodeData(id, { [key]: value });
|
updateNodeData(id, { [key]: value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setFacing(data.showCode ? "back" : "front");
|
||||||
|
}, [data.showCode]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Flippable facing={facing} preserveFrontsideHeight={true}>
|
||||||
<Handle
|
<div>
|
||||||
type="source"
|
<Handle
|
||||||
position={Position.Bottom}
|
type="source"
|
||||||
id="a"
|
position={Position.Bottom}
|
||||||
className="opacity-0"
|
id="a"
|
||||||
/>
|
className="opacity-0"
|
||||||
<Handle
|
|
||||||
type="target"
|
|
||||||
position={Position.Top}
|
|
||||||
id="b"
|
|
||||||
className="opacity-0"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"transform-origin-center w-[30rem] space-y-4 rounded-lg bg-slate-elevation3 px-6 py-4 transition-all",
|
|
||||||
{
|
|
||||||
"pointer-events-none": thisBlockIsPlaying,
|
|
||||||
"bg-slate-950 outline outline-2 outline-slate-300":
|
|
||||||
thisBlockIsTargetted,
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<NodeHeader
|
|
||||||
blockLabel={label}
|
|
||||||
editable={editable}
|
|
||||||
nodeId={id}
|
|
||||||
totpIdentifier={inputs.totpIdentifier}
|
|
||||||
totpUrl={inputs.totpVerificationUrl}
|
|
||||||
type="task_v2" // sic: the naming is not consistent
|
|
||||||
/>
|
/>
|
||||||
<div className="space-y-4">
|
<Handle
|
||||||
<div className="space-y-2">
|
type="target"
|
||||||
<div className="flex justify-between">
|
position={Position.Top}
|
||||||
<Label className="text-xs text-slate-300">Prompt</Label>
|
id="b"
|
||||||
{isFirstWorkflowBlock ? (
|
className="opacity-0"
|
||||||
<div className="flex justify-end text-xs text-slate-400">
|
/>
|
||||||
Tip: Use the {"+"} button to add parameters!
|
<div
|
||||||
</div>
|
className={cn(
|
||||||
) : null}
|
"transform-origin-center w-[30rem] space-y-4 rounded-lg bg-slate-elevation3 px-6 py-4 transition-all",
|
||||||
</div>
|
{
|
||||||
<WorkflowBlockInputTextarea
|
"pointer-events-none": thisBlockIsPlaying,
|
||||||
nodeId={id}
|
"bg-slate-950 outline outline-2 outline-slate-300":
|
||||||
onChange={(value) => {
|
thisBlockIsTargetted,
|
||||||
handleChange("prompt", value);
|
},
|
||||||
}}
|
)}
|
||||||
value={inputs.prompt}
|
|
||||||
placeholder={placeholders[type]["prompt"]}
|
|
||||||
className="nopan text-xs"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Label className="text-xs text-slate-300">URL</Label>
|
|
||||||
<WorkflowBlockInputTextarea
|
|
||||||
canWriteTitle={true}
|
|
||||||
nodeId={id}
|
|
||||||
onChange={(value) => {
|
|
||||||
handleChange("url", value);
|
|
||||||
}}
|
|
||||||
value={inputs.url}
|
|
||||||
placeholder={placeholders[type]["url"]}
|
|
||||||
className="nopan text-xs"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Separator />
|
|
||||||
<Accordion
|
|
||||||
type="single"
|
|
||||||
collapsible
|
|
||||||
onValueChange={() => rerender.bump()}
|
|
||||||
>
|
>
|
||||||
<AccordionItem value="advanced" className="border-b-0">
|
<NodeHeader
|
||||||
<AccordionTrigger className="py-0">
|
blockLabel={label}
|
||||||
Advanced Settings
|
editable={editable}
|
||||||
</AccordionTrigger>
|
nodeId={id}
|
||||||
<AccordionContent key={rerender.key} className="pl-6 pr-1 pt-4">
|
totpIdentifier={inputs.totpIdentifier}
|
||||||
<div className="space-y-4">
|
totpUrl={inputs.totpVerificationUrl}
|
||||||
<ModelSelector
|
type="task_v2" // sic: the naming is not consistent
|
||||||
className="nopan w-52 text-xs"
|
/>
|
||||||
value={inputs.model}
|
<div className="space-y-4">
|
||||||
onChange={(value) => {
|
<div className="space-y-2">
|
||||||
handleChange("model", value);
|
<div className="flex justify-between">
|
||||||
}}
|
<Label className="text-xs text-slate-300">Prompt</Label>
|
||||||
/>
|
{isFirstWorkflowBlock ? (
|
||||||
<div className="space-y-2">
|
<div className="flex justify-end text-xs text-slate-400">
|
||||||
<div className="flex gap-2">
|
Tip: Use the {"+"} button to add parameters!
|
||||||
<Label className="text-xs text-slate-300">Max Steps</Label>
|
|
||||||
<HelpTooltip content={helpTooltips[type]["maxSteps"]} />
|
|
||||||
</div>
|
</div>
|
||||||
<Input
|
) : null}
|
||||||
type="number"
|
|
||||||
placeholder="10"
|
|
||||||
className="nopan text-xs"
|
|
||||||
value={data.maxSteps ?? MAX_STEPS_DEFAULT}
|
|
||||||
onChange={(event) => {
|
|
||||||
handleChange("maxSteps", Number(event.target.value));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Label className="text-xs text-slate-300">
|
|
||||||
2FA Identifier
|
|
||||||
</Label>
|
|
||||||
<HelpTooltip
|
|
||||||
content={helpTooltips[type]["totpIdentifier"]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<WorkflowBlockInputTextarea
|
|
||||||
nodeId={id}
|
|
||||||
onChange={(value) => {
|
|
||||||
handleChange("totpIdentifier", value);
|
|
||||||
}}
|
|
||||||
value={inputs.totpIdentifier ?? ""}
|
|
||||||
placeholder={placeholders["navigation"]["totpIdentifier"]}
|
|
||||||
className="nopan text-xs"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Label className="text-xs text-slate-300">
|
|
||||||
2FA Verification URL
|
|
||||||
</Label>
|
|
||||||
<HelpTooltip
|
|
||||||
content={helpTooltips["task"]["totpVerificationUrl"]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<WorkflowBlockInputTextarea
|
|
||||||
nodeId={id}
|
|
||||||
onChange={(value) => {
|
|
||||||
handleChange("totpVerificationUrl", value);
|
|
||||||
}}
|
|
||||||
value={inputs.totpVerificationUrl ?? ""}
|
|
||||||
placeholder={placeholders["task"]["totpVerificationUrl"]}
|
|
||||||
className="nopan text-xs"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</AccordionContent>
|
<WorkflowBlockInputTextarea
|
||||||
</AccordionItem>
|
nodeId={id}
|
||||||
</Accordion>
|
onChange={(value) => {
|
||||||
<NodeTabs blockLabel={label} />
|
handleChange("prompt", value);
|
||||||
|
}}
|
||||||
|
value={inputs.prompt}
|
||||||
|
placeholder={placeholders[type]["prompt"]}
|
||||||
|
className="nopan text-xs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label className="text-xs text-slate-300">URL</Label>
|
||||||
|
<WorkflowBlockInputTextarea
|
||||||
|
canWriteTitle={true}
|
||||||
|
nodeId={id}
|
||||||
|
onChange={(value) => {
|
||||||
|
handleChange("url", value);
|
||||||
|
}}
|
||||||
|
value={inputs.url}
|
||||||
|
placeholder={placeholders[type]["url"]}
|
||||||
|
className="nopan text-xs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Separator />
|
||||||
|
<Accordion
|
||||||
|
type="single"
|
||||||
|
collapsible
|
||||||
|
onValueChange={() => rerender.bump()}
|
||||||
|
>
|
||||||
|
<AccordionItem value="advanced" className="border-b-0">
|
||||||
|
<AccordionTrigger className="py-0">
|
||||||
|
Advanced Settings
|
||||||
|
</AccordionTrigger>
|
||||||
|
<AccordionContent key={rerender.key} className="pl-6 pr-1 pt-4">
|
||||||
|
<div className="space-y-4">
|
||||||
|
<ModelSelector
|
||||||
|
className="nopan w-52 text-xs"
|
||||||
|
value={inputs.model}
|
||||||
|
onChange={(value) => {
|
||||||
|
handleChange("model", value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Label className="text-xs text-slate-300">
|
||||||
|
Max Steps
|
||||||
|
</Label>
|
||||||
|
<HelpTooltip content={helpTooltips[type]["maxSteps"]} />
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
placeholder="10"
|
||||||
|
className="nopan text-xs"
|
||||||
|
value={data.maxSteps ?? MAX_STEPS_DEFAULT}
|
||||||
|
onChange={(event) => {
|
||||||
|
handleChange("maxSteps", Number(event.target.value));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Label className="text-xs text-slate-300">
|
||||||
|
2FA Identifier
|
||||||
|
</Label>
|
||||||
|
<HelpTooltip
|
||||||
|
content={helpTooltips[type]["totpIdentifier"]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<WorkflowBlockInputTextarea
|
||||||
|
nodeId={id}
|
||||||
|
onChange={(value) => {
|
||||||
|
handleChange("totpIdentifier", value);
|
||||||
|
}}
|
||||||
|
value={inputs.totpIdentifier ?? ""}
|
||||||
|
placeholder={placeholders["navigation"]["totpIdentifier"]}
|
||||||
|
className="nopan text-xs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Label className="text-xs text-slate-300">
|
||||||
|
2FA Verification URL
|
||||||
|
</Label>
|
||||||
|
<HelpTooltip
|
||||||
|
content={helpTooltips["task"]["totpVerificationUrl"]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<WorkflowBlockInputTextarea
|
||||||
|
nodeId={id}
|
||||||
|
onChange={(value) => {
|
||||||
|
handleChange("totpVerificationUrl", value);
|
||||||
|
}}
|
||||||
|
value={inputs.totpVerificationUrl ?? ""}
|
||||||
|
placeholder={placeholders["task"]["totpVerificationUrl"]}
|
||||||
|
className="nopan text-xs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
|
<NodeTabs blockLabel={label} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<BlockCodeEditor blockLabel={label} blockType="task_v2" script={script} />
|
||||||
|
</Flippable>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -247,6 +247,7 @@ export const scriptableWorkflowBlockTypes: Set<WorkflowBlockType> = new Set([
|
|||||||
"login",
|
"login",
|
||||||
"navigation",
|
"navigation",
|
||||||
"task",
|
"task",
|
||||||
|
"task_v2",
|
||||||
"validation",
|
"validation",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user