From f773255238192b92c09b9a815da16f04d0ede1ac Mon Sep 17 00:00:00 2001 From: Shuchang Zheng Date: Thu, 7 Nov 2024 14:30:03 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'skyvern-fronte?= =?UTF-8?q?nd/src/'=20with=20remote=20'skyvern-frontend/src/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > [!IMPORTANT] > Fixes loop block children order bug on save by using edges in `getWorkflowBlocks` in `workflowEditorUtils.ts`. > > - **Behavior**: > - Fixes bug in `handleSave()` in `FlowRenderer.tsx` by passing `edges` to `getWorkflowBlocks` to ensure correct order of loop block children. > - **Functions**: > - Adds `getOrderedChildrenBlocks()` in `workflowEditorUtils.ts` to determine the order of loop block children using `edges`. > - Updates `getWorkflowBlocksUtil()` in `workflowEditorUtils.ts` to use `getOrderedChildrenBlocks()` for loop blocks. > - **Misc**: > - Updates `getWorkflowBlocks()` in `workflowEditorUtils.ts` to accept `edges` parameter. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=Skyvern-AI%2Fskyvern-cloud&utm_source=github&utm_medium=referral) for db2bb9f633252c0f84feabf005fb825979621da6. It will automatically update as commits are pushed. --- .../routes/workflows/editor/FlowRenderer.tsx | 2 +- .../workflows/editor/workflowEditorUtils.ts | 64 ++++++++++++++----- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/skyvern-frontend/src/routes/workflows/editor/FlowRenderer.tsx b/skyvern-frontend/src/routes/workflows/editor/FlowRenderer.tsx index 6740e10bb..81fe4c3c4 100644 --- a/skyvern-frontend/src/routes/workflows/editor/FlowRenderer.tsx +++ b/skyvern-frontend/src/routes/workflows/editor/FlowRenderer.tsx @@ -265,7 +265,7 @@ function FlowRenderer({ }, [nodesInitialized]); async function handleSave() { - const blocks = getWorkflowBlocks(nodes); + const blocks = getWorkflowBlocks(nodes, edges); const parametersInYAMLConvertibleJSON = convertToParametersYAML(parameters); const filteredParameters = workflow.workflow_definition.parameters.filter( (parameter) => { diff --git a/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts b/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts index 7384c8a43..bab9bea5b 100644 --- a/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts +++ b/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts @@ -635,9 +635,48 @@ function getWorkflowBlock(node: WorkflowBlockNode): BlockYAML { } } -function getWorkflowBlocksUtil(nodes: Array): Array { +function getOrderedChildrenBlocks( + nodes: Array, + edges: Array, + parentId: string, +): Array { + const parentNode = nodes.find((node) => node.id === parentId); + if (!parentNode) { + return []; + } + const blockStartNode = nodes.find( + (node) => node.type === "start" && node.parentId === parentId, + ); + if (!blockStartNode) { + return []; + } + const firstChildId = edges.find( + (edge) => edge.source === blockStartNode.id, + )?.target; + const firstChild = nodes.find((node) => node.id === firstChildId); + if (!firstChild || !isWorkflowBlockNode(firstChild)) { + return []; + } + + const children: Array = []; + let currentNode: WorkflowBlockNode | undefined = firstChild; + while (currentNode) { + children.push(getWorkflowBlock(currentNode)); + const nextId = edges.find( + (edge) => edge.source === currentNode?.id, + )?.target; + const next = nodes.find((node) => node.id === nextId); + currentNode = next && isWorkflowBlockNode(next) ? next : undefined; + } + return children; +} + +function getWorkflowBlocksUtil( + nodes: Array, + edges: Array, +): Array { return nodes.flatMap((node) => { - if (node.parentId) { + if (node.parentId || node.type === "start" || node.type === "nodeAdder") { return []; } if (node.type === "loop") { @@ -647,26 +686,19 @@ function getWorkflowBlocksUtil(nodes: Array): Array { label: node.data.label, continue_on_failure: node.data.continueOnFailure, loop_over_parameter_key: node.data.loopValue, - loop_blocks: nodes - .filter((n) => n.parentId === node.id) - .map((n) => { - return getWorkflowBlock( - n as Exclude, - ); - }), + loop_blocks: getOrderedChildrenBlocks(nodes, edges, node.id), }, ]; } - return [ - getWorkflowBlock( - node as Exclude, - ), - ]; + return [getWorkflowBlock(node as Exclude)]; }); } -function getWorkflowBlocks(nodes: Array): Array { - return getWorkflowBlocksUtil(nodes.filter(isWorkflowBlockNode)); +function getWorkflowBlocks( + nodes: Array, + edges: Array, +): Array { + return getWorkflowBlocksUtil(nodes, edges); } function generateNodeLabel(existingLabels: Array) {