Skip to content

Commit

Permalink
🔄 synced local 'skyvern-frontend/src/' with remote 'skyvern-frontend/…
Browse files Browse the repository at this point in the history
…src/'

<!-- ELLIPSIS_HIDDEN -->

> [!IMPORTANT]
> Add `ActionNode` and `ValidationNode` to the workflow editor with error handling and node library updates.
>
>   - **New Features**:
>     - Add `ActionNode` and `ValidationNode` components in `ActionNode/ActionNode.tsx` and `ValidationNode/ValidationNode.tsx`.
>     - Add `ClickIcon` component in `ClickIcon.tsx` for use in `ActionNode`.
>   - **Workflow Editor**:
>     - Update `FlowRenderer.tsx` to handle `ActionNode` and `ValidationNode` types.
>     - Add error checks for `ActionNode` and `ValidationNode` in `getWorkflowErrors()`.
>     - Update `WorkflowNodeLibraryPanel.tsx` to include `ActionNode` and `ValidationNode` in the node library.
>   - **Node Types**:
>     - Define `ActionNodeData` and `ValidationNodeData` in `ActionNode/types.ts` and `ValidationNode/types.ts`.
>     - Update `nodes/index.ts` to include `ActionNode` and `ValidationNode`.
>   - **Miscellaneous**:
>     - Remove `editable` property from several node data types in `CodeBlockNode/types.ts`, `DownloadNode/types.ts`, etc.
>     - Update `workflowEditorUtils.ts` to support new node types in node creation and conversion functions.
>     - Change `className` for `QuestionMarkCircledIcon` in `HelpTooltip.tsx`.
>
> <sup>This description was created by </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=Skyvern-AI%2Fskyvern-cloud&utm_source=github&utm_medium=referral)<sup> for 0684180f9b36b3fc8d9caec0488fdb5e6c6681fc. It will automatically update as commits are pushed.</sup>

<!-- ELLIPSIS_HIDDEN -->
  • Loading branch information
wintonzheng committed Nov 22, 2024
1 parent c732b41 commit 865e10c
Show file tree
Hide file tree
Showing 12 changed files with 554 additions and 19 deletions.
2 changes: 1 addition & 1 deletion skyvern-frontend/src/components/HelpTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function HelpTooltip({ content }: Props) {
<TooltipProvider>
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>
<QuestionMarkCircledIcon className="h-4 w-4" />
<QuestionMarkCircledIcon className="size-4" />
</TooltipTrigger>
<TooltipContent className="max-w-[250px]">{content}</TooltipContent>
</Tooltip>
Expand Down
26 changes: 26 additions & 0 deletions skyvern-frontend/src/components/icons/ClickIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
type Props = {
className?: string;
};

function ClickIcon({ className }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
className={className}
>
<path
d="M9 3.5V2M5.06066 5.06066L4 4M5.06066 13L4 14.0607M13 5.06066L14.0607 4M3.5 9H2M8.5 8.5L12.6111 21.2778L15.5 18.3889L19.1111 22L22 19.1111L18.3889 15.5L21.2778 12.6111L8.5 8.5Z"
stroke="#F8FAFC"
strokeWidth="1.6"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}

export { ClickIcon };
20 changes: 11 additions & 9 deletions skyvern-frontend/src/components/ui/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
</TooltipPrimitive.Portal>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;

Expand Down
26 changes: 21 additions & 5 deletions skyvern-frontend/src/routes/workflows/editor/FlowRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import { isLoopNode, LoopNode } from "./nodes/LoopNode/types";
import { isTaskNode } from "./nodes/TaskNode/types";
import { useShouldNotifyWhenClosingTab } from "@/hooks/useShouldNotifyWhenClosingTab";
import { isValidationNode } from "./nodes/ValidationNode/types";
import { isActionNode } from "./nodes/ActionNode/types";

function convertToParametersYAML(
parameters: ParametersState,
Expand Down Expand Up @@ -459,13 +460,28 @@ function FlowRenderer({
const errors: Array<string> = [];

const workflowBlockNodes = nodes.filter(isWorkflowBlockNode);
if (workflowBlockNodes[0]!.type === "validation") {
if (
workflowBlockNodes.length > 0 &&
workflowBlockNodes[0]!.type === "validation"
) {
const label = workflowBlockNodes[0]!.data.label;
errors.push(
`${label}: Validation block can't be the first block in a workflow`,
`${label}: Validation block can't be the first block in a workflow.`,
);
}

const actionNodes = nodes.filter(isActionNode);
actionNodes.forEach((node) => {
if (node.data.navigationGoal.length === 0) {
errors.push(`${node.data.label}: Action Instruction is required.`);
}
try {
JSON.parse(node.data.errorCodeMapping);
} catch {
errors.push(`${node.data.label}: Error messages is not valid JSON.`);
}
});

// check loop node parameters
const loopNodes: Array<LoopNode> = nodes.filter(isLoopNode);
const emptyLoopNodes = loopNodes.filter(
Expand All @@ -474,7 +490,7 @@ function FlowRenderer({
if (emptyLoopNodes.length > 0) {
emptyLoopNodes.forEach((node) => {
errors.push(
`${node.data.label}: Loop value parameter must be selected`,
`${node.data.label}: Loop value parameter must be selected.`,
);
});
}
Expand All @@ -485,12 +501,12 @@ function FlowRenderer({
try {
JSON.parse(node.data.dataSchema);
} catch {
errors.push(`${node.data.label}: Data schema is not valid JSON`);
errors.push(`${node.data.label}: Data schema is not valid JSON.`);
}
try {
JSON.parse(node.data.errorCodeMapping);
} catch {
errors.push(`${node.data.label}: Error messages is not valid JSON`);
errors.push(`${node.data.label}: Error messages is not valid JSON.`);
}
});

Expand Down
Loading

0 comments on commit 865e10c

Please sign in to comment.