From 62bcfdeaa9cc63bac38650020226309f3c79935d Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Wed, 19 Jul 2023 11:03:44 -0300 Subject: [PATCH 1/2] Fixed bug where prompt modal not saving, but there is no Clean Edges now --- .../components/parameterComponent/index.tsx | 10 ------- .../src/components/promptComponent/index.tsx | 28 ++----------------- .../src/modals/genericModal/index.tsx | 2 +- 3 files changed, 4 insertions(+), 36 deletions(-) diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 88d9e41da..85bf26683 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -17,7 +17,6 @@ import { MAX_LENGTH_TO_SCROLL_TOOLTIP } from "../../../../constants"; import { TabsContext } from "../../../../contexts/tabsContext"; import { typesContext } from "../../../../contexts/typesContext"; import { ParameterComponentType } from "../../../../types/components"; -import { cleanEdges } from "../../../../util/reactflowUtils"; import { classNames, getRandomKeyByssmm, @@ -312,15 +311,6 @@ export default function ParameterComponent({ field_name={name} setNodeClass={(nodeClass) => { data.node = nodeClass; - if (reactFlowInstance) { - cleanEdges({ - flow: { - edges: reactFlowInstance.getEdges(), - nodes: reactFlowInstance.getNodes(), - }, - updateEdge: (edge) => reactFlowInstance.setEdges(edge), - }); - } }} nodeClass={data.node} disabled={disabled} diff --git a/src/frontend/src/components/promptComponent/index.tsx b/src/frontend/src/components/promptComponent/index.tsx index 3d24af0f7..dbf2c7251 100644 --- a/src/frontend/src/components/promptComponent/index.tsx +++ b/src/frontend/src/components/promptComponent/index.tsx @@ -1,4 +1,4 @@ -import { useContext, useEffect, useState } from "react"; +import { useContext, useEffect } from "react"; import GenericModal from "../../modals/genericModal"; import { TextAreaComponentType } from "../../types/components"; @@ -15,17 +15,14 @@ export default function PromptAreaComponent({ disabled, editNode = false, }: TextAreaComponentType) { - const [myValue, setMyValue] = useState(value); const { reactFlowInstance } = useContext(typesContext); useEffect(() => { if (disabled) { - setMyValue(""); onChange(""); } }, [disabled, onChange]); useEffect(() => { - setMyValue(value); if (value !== "" && !editNode) { postValidatePrompt(field_name, value, nodeClass).then((apiReturn) => { if (apiReturn.data) { @@ -36,33 +33,14 @@ export default function PromptAreaComponent({ } }, [value, reactFlowInstance]); - // useEffect(() => { - // if (value !== "" && myValue !== value && reactFlowInstance) { - // // only executed once - // setMyValue(value); - // postValidatePrompt(field_name, value, nodeClass) - // .then((apiReturn) => { - // if (apiReturn.data) { - // setNodeClass(apiReturn.data.frontend_node); - // // need to update reactFlowInstance to re-render the nodes. - // reactFlowInstance.setEdges( - // _.cloneDeep(reactFlowInstance.getEdges()) - // ); - // } - // }) - // .catch((error) => {}); - // } - // }, [reactFlowInstance, field_name, myValue, nodeClass, setNodeClass, value]); - return (
{ - setMyValue(t); onChange(t); }} nodeClass={nodeClass} @@ -77,7 +55,7 @@ export default function PromptAreaComponent({ " input-primary text-muted-foreground " } > - {myValue !== "" ? myValue : "Type your prompt here"} + {value !== "" ? value : "Type your prompt here"} {!editNode && ( { if (apiReturn.data) { - setNodeClass(apiReturn.data?.frontend_node); let inputVariables = apiReturn.data.input_variables ?? []; if (inputVariables && inputVariables.length === 0) { setIsEdit(true); @@ -140,6 +139,7 @@ export default function GenericModal({ setSuccessData({ title: "Prompt is ready", }); + setNodeClass(apiReturn.data?.frontend_node); setModalOpen(closeModal); setValue(inputValue); } From 8f6e8f9e91b417b03bb71f7ef7b353ffcea3cbe7 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Thu, 20 Jul 2023 10:12:29 -0300 Subject: [PATCH 2/2] Fixed bug that has been fixed at CustomComponents --- .../src/CustomNodes/GenericNode/index.tsx | 27 ++++++++++++++++--- .../components/textAreaComponent/index.tsx | 2 +- .../components/PageComponent/index.tsx | 2 +- src/frontend/src/util/reactflowUtils.ts | 8 +++++- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index 364f91d01..aad22e6ce 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -1,13 +1,16 @@ +import { cloneDeep } from "lodash"; import { Zap } from "lucide-react"; import { useContext, useEffect, useRef, useState } from "react"; -import { NodeToolbar } from "reactflow"; +import { NodeToolbar, useUpdateNodeInternals } from "reactflow"; import ShadTooltip from "../../components/ShadTooltipComponent"; import Tooltip from "../../components/TooltipComponent"; import { useSSE } from "../../contexts/SSEContext"; import { alertContext } from "../../contexts/alertContext"; +import { TabsContext } from "../../contexts/tabsContext"; import { typesContext } from "../../contexts/typesContext"; import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent"; import { NodeDataType } from "../../types/flow"; +import { cleanEdges } from "../../util/reactflowUtils"; import { classNames, nodeColors, @@ -25,6 +28,8 @@ export default function GenericNode({ }) { const [data, setData] = useState(olddata); const { setErrorData } = useContext(alertContext); + const { updateFlow, flows, tabId } = useContext(TabsContext); + const updateNodeInternals = useUpdateNodeInternals(); const showError = useRef(true); const { types, deleteNode, reactFlowInstance } = useContext(typesContext); // any to avoid type conflict @@ -33,10 +38,26 @@ export default function GenericNode({ const [validationStatus, setValidationStatus] = useState(null); // State for outline color const { sseData, isBuilding } = useSSE(); - const refHtml = useRef(null); useEffect(() => { olddata.node = data.node; - }, [data, reactFlowInstance]); + let myFlow = flows.find((flow) => flow.id === tabId); + if (reactFlowInstance && myFlow) { + let flow = cloneDeep(myFlow); + flow.data = reactFlowInstance.toObject(); + cleanEdges({ + flow: { + edges: flow.data.edges, + nodes: flow.data.nodes, + }, + updateEdge: (edge) => { + flow.data.edges = edge; + reactFlowInstance.setEdges(edge); + updateNodeInternals(data.id); + }, + }); + updateFlow(flow); + } + }, [data]); // New useEffect to watch for changes in sseData and update validation status useEffect(() => { diff --git a/src/frontend/src/components/textAreaComponent/index.tsx b/src/frontend/src/components/textAreaComponent/index.tsx index 10e725905..6dc602889 100644 --- a/src/frontend/src/components/textAreaComponent/index.tsx +++ b/src/frontend/src/components/textAreaComponent/index.tsx @@ -17,7 +17,7 @@ export default function TextAreaComponent({ if (disabled) { onChange(""); } - }, [disabled, onChange]); + }, [disabled]); return (
diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index a6ac0f4df..02af0beac 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -125,7 +125,7 @@ export default function Page({ flow }: { flow: FlowType }) { updateFlow(flow); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [nodes, edges]); + }, [edges]); //update flow when tabs change useEffect(() => { setNodes(flow?.data?.nodes ?? []); diff --git a/src/frontend/src/util/reactflowUtils.ts b/src/frontend/src/util/reactflowUtils.ts index da04cc75c..77e8e0cdd 100644 --- a/src/frontend/src/util/reactflowUtils.ts +++ b/src/frontend/src/util/reactflowUtils.ts @@ -6,12 +6,14 @@ export function cleanEdges({ updateEdge, }: cleanEdgesType) { let newEdges = _.cloneDeep(edges); + let changed = false; edges.forEach((edge) => { // check if the source and target node still exists const sourceNode = nodes.find((node) => node.id === edge.source); const targetNode = nodes.find((node) => node.id === edge.target); if (!sourceNode || !targetNode) { newEdges = newEdges.filter((e) => e.id !== edge.id); + changed = true; } // check if the source and target handle still exists if (sourceNode && targetNode) { @@ -28,6 +30,7 @@ export function cleanEdges({ targetNode.data.id; if (id !== targetHandle) { newEdges = newEdges.filter((e) => e.id !== edge.id); + changed = true; } } if (sourceHandle) { @@ -38,9 +41,12 @@ export function cleanEdges({ ].join("|"); if (id !== sourceHandle) { newEdges = newEdges.filter((e) => e.id !== edge.id); + changed = true; } } } }); - updateEdge(newEdges); + if (changed) { + updateEdge(newEdges); + } }