Fix duplicate group bug (#1859)

* fix duplicate group bug

* remove commented console.log
This commit is contained in:
anovazzi1 2024-05-14 14:46:44 -03:00 • committed by GitHub
commit 3abc7eedc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 49 additions and 52 deletions

View file

@ -51,19 +51,19 @@ export default function Page({
}): JSX.Element { }): JSX.Element {
const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow); const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow);
const autoSaveCurrentFlow = useFlowsManagerStore( const autoSaveCurrentFlow = useFlowsManagerStore(
(state) => state.autoSaveCurrentFlow (state) => state.autoSaveCurrentFlow,
); );
const types = useTypesStore((state) => state.types); const types = useTypesStore((state) => state.types);
const templates = useTypesStore((state) => state.templates); const templates = useTypesStore((state) => state.templates);
const setFilterEdge = useFlowStore((state) => state.setFilterEdge); const setFilterEdge = useFlowStore((state) => state.setFilterEdge);
const reactFlowWrapper = useRef<HTMLDivElement>(null); const reactFlowWrapper = useRef<HTMLDivElement>(null);
const [showCanvas, setSHowCanvas] = useState( const [showCanvas, setSHowCanvas] = useState(
Object.keys(templates).length > 0 && Object.keys(types).length > 0 Object.keys(templates).length > 0 && Object.keys(types).length > 0,
); );
const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance); const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance);
const setReactFlowInstance = useFlowStore( const setReactFlowInstance = useFlowStore(
(state) => state.setReactFlowInstance (state) => state.setReactFlowInstance,
); );
const nodes = useFlowStore((state) => state.nodes); const nodes = useFlowStore((state) => state.nodes);
const edges = useFlowStore((state) => state.edges); const edges = useFlowStore((state) => state.edges);
@ -80,10 +80,10 @@ export default function Page({
const paste = useFlowStore((state) => state.paste); const paste = useFlowStore((state) => state.paste);
const resetFlow = useFlowStore((state) => state.resetFlow); const resetFlow = useFlowStore((state) => state.resetFlow);
const lastCopiedSelection = useFlowStore( const lastCopiedSelection = useFlowStore(
(state) => state.lastCopiedSelection (state) => state.lastCopiedSelection,
); );
const setLastCopiedSelection = useFlowStore( const setLastCopiedSelection = useFlowStore(
(state) => state.setLastCopiedSelection (state) => state.setLastCopiedSelection,
); );
const onConnect = useFlowStore((state) => state.onConnect); const onConnect = useFlowStore((state) => state.onConnect);
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId); const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
@ -106,7 +106,7 @@ export default function Page({
clonedSelection!, clonedSelection!,
clonedNodes, clonedNodes,
clonedEdges, clonedEdges,
getRandomName() getRandomName(),
); );
const newGroupNode = generateNodeFromFlow(newFlow, getNodeId); const newGroupNode = generateNodeFromFlow(newFlow, getNodeId);
const newEdges = reconnectEdges(newGroupNode, removedEdges); const newEdges = reconnectEdges(newGroupNode, removedEdges);
@ -114,8 +114,8 @@ export default function Page({
...clonedNodes.filter( ...clonedNodes.filter(
(oldNodes) => (oldNodes) =>
!clonedSelection?.nodes.some( !clonedSelection?.nodes.some(
(selectionNode) => selectionNode.id === oldNodes.id (selectionNode) => selectionNode.id === oldNodes.id,
) ),
), ),
newGroupNode, newGroupNode,
]); ]);
@ -125,8 +125,8 @@ export default function Page({
!clonedSelection!.nodes.some( !clonedSelection!.nodes.some(
(selectionNode) => (selectionNode) =>
selectionNode.id === oldEdge.target || selectionNode.id === oldEdge.target ||
selectionNode.id === oldEdge.source selectionNode.id === oldEdge.source,
) ),
), ),
...newEdges, ...newEdges,
]); ]);
@ -141,7 +141,8 @@ export default function Page({
const setNode = useFlowStore((state) => state.setNode); const setNode = useFlowStore((state) => state.setNode);
useEffect(() => { useEffect(() => {
const onKeyDown = (event: KeyboardEvent) => { const onKeyDown = (event: KeyboardEvent) => {
const selectedNode = nodes.filter((obj) => obj.selected); const selectedNode = lastSelection?.nodes ?? [];
const selectedEdges = lastSelection?.edges ?? [];
if ( if (
selectionMenuVisible && selectionMenuVisible &&
(event.ctrlKey || event.metaKey) && (event.ctrlKey || event.metaKey) &&
@ -174,11 +175,11 @@ export default function Page({
) { ) {
event.preventDefault(); event.preventDefault();
paste( paste(
{ nodes: selectedNode, edges: [] }, { nodes: selectedNode, edges: selectedEdges },
{ {
x: position.current.x, x: position.current.x,
y: position.current.y, y: position.current.y,
} },
); );
} }
if (!isWrappedWithClass(event, "noundo")) { if (!isWrappedWithClass(event, "noundo")) {
@ -274,7 +275,7 @@ export default function Page({
useEffect(() => { useEffect(() => {
setSHowCanvas( setSHowCanvas(
Object.keys(templates).length > 0 && Object.keys(types).length > 0 Object.keys(templates).length > 0 && Object.keys(types).length > 0,
); );
}, [templates, types]); }, [templates, types]);
@ -283,7 +284,7 @@ export default function Page({
takeSnapshot(); takeSnapshot();
onConnect(params); onConnect(params);
}, },
[takeSnapshot, onConnect] [takeSnapshot, onConnect],
); );
const onNodeDragStart: NodeDragHandler = useCallback(() => { const onNodeDragStart: NodeDragHandler = useCallback(() => {
@ -324,7 +325,7 @@ export default function Page({
// Extract the data from the drag event and parse it as a JSON object // Extract the data from the drag event and parse it as a JSON object
const data: { type: string; node?: APIClassType } = JSON.parse( const data: { type: string; node?: APIClassType } = JSON.parse(
event.dataTransfer.getData("nodedata") event.dataTransfer.getData("nodedata"),
); );
const newId = getNodeId(data.type); const newId = getNodeId(data.type);
@ -340,7 +341,7 @@ export default function Page({
}; };
paste( paste(
{ nodes: [newNode], edges: [] }, { nodes: [newNode], edges: [] },
{ x: event.clientX, y: event.clientY } { x: event.clientX, y: event.clientY },
); );
} else if (event.dataTransfer.types.some((types) => types === "Files")) { } else if (event.dataTransfer.types.some((types) => types === "Files")) {
takeSnapshot(); takeSnapshot();
@ -369,7 +370,7 @@ export default function Page({
} }
}, },
// Specify dependencies for useCallback // Specify dependencies for useCallback
[getNodeId, setNodes, takeSnapshot, paste] [getNodeId, setNodes, takeSnapshot, paste],
); );
const onEdgeUpdateStart = useCallback(() => { const onEdgeUpdateStart = useCallback(() => {
@ -385,7 +386,7 @@ export default function Page({
setEdges((els) => updateEdge(oldEdge, newConnection, els)); setEdges((els) => updateEdge(oldEdge, newConnection, els));
} }
}, },
[setEdges] [setEdges],
); );
const onEdgeUpdateEnd = useCallback((_, edge: Edge): void => { const onEdgeUpdateEnd = useCallback((_, edge: Edge): void => {
@ -418,7 +419,7 @@ export default function Page({
(flow: OnSelectionChangeParams): void => { (flow: OnSelectionChangeParams): void => {
setLastSelection(flow); setLastSelection(flow);
}, },
[] [],
); );
const onPaneClick = useCallback((flow) => { const onPaneClick = useCallback((flow) => {

View file

@ -49,7 +49,7 @@ import FlowPage from "../pages/FlowPage";
// this is our useStore hook that we can use in our components to get parts of the store and call actions // this is our useStore hook that we can use in our components to get parts of the store and call actions
const useFlowStore = create<FlowStoreType>((set, get) => ({ const useFlowStore = create<FlowStoreType>((set, get) => ({
onFlowPage: false, onFlowPage: false,
setOnFlowPage:(FlowPage=>set({onFlowPage:FlowPage})), setOnFlowPage: (FlowPage) => set({ onFlowPage: FlowPage }),
flowState: undefined, flowState: undefined,
flowBuildStatus: {}, flowBuildStatus: {},
nodes: [], nodes: [],
@ -80,7 +80,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
updateFlowPool: ( updateFlowPool: (
nodeId: string, nodeId: string,
data: FlowPoolObjectType | ChatOutputType | chatInputType, data: FlowPoolObjectType | ChatOutputType | chatInputType,
buildId?: string buildId?: string,
) => { ) => {
let newFlowPool = cloneDeep({ ...get().flowPool }); let newFlowPool = cloneDeep({ ...get().flowPool });
if (!newFlowPool[nodeId]) { if (!newFlowPool[nodeId]) {
@ -152,7 +152,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
edges: applyEdgeChanges(changes, get().edges), edges: applyEdgeChanges(changes, get().edges),
}); });
}, },
setNodes: (change,skipSave=false) => { setNodes: (change, skipSave = false) => {
let newChange = typeof change === "function" ? change(get().nodes) : change; let newChange = typeof change === "function" ? change(get().nodes) : change;
let newEdges = cleanEdges(newChange, get().edges); let newEdges = cleanEdges(newChange, get().edges);
const { inputs, outputs } = getInputsAndOutputs(newChange); const { inputs, outputs } = getInputsAndOutputs(newChange);
@ -171,11 +171,11 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
flowsManager.autoSaveCurrentFlow( flowsManager.autoSaveCurrentFlow(
newChange, newChange,
newEdges, newEdges,
get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 },
); );
} }
}, },
setEdges: (change,skipSave=false) => { setEdges: (change, skipSave = false) => {
let newChange = typeof change === "function" ? change(get().edges) : change; let newChange = typeof change === "function" ? change(get().edges) : change;
set({ set({
edges: newChange, edges: newChange,
@ -187,7 +187,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
flowsManager.autoSaveCurrentFlow( flowsManager.autoSaveCurrentFlow(
get().nodes, get().nodes,
newChange, newChange,
get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 },
); );
} }
}, },
@ -205,7 +205,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
return newChange; return newChange;
} }
return node; return node;
}) }),
); );
}, },
getNode: (id: string) => { getNode: (id: string) => {
@ -216,8 +216,8 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
get().nodes.filter((node) => get().nodes.filter((node) =>
typeof nodeId === "string" typeof nodeId === "string"
? node.id !== nodeId ? node.id !== nodeId
: !nodeId.includes(node.id) : !nodeId.includes(node.id),
) ),
); );
}, },
deleteEdge: (edgeId) => { deleteEdge: (edgeId) => {
@ -225,13 +225,11 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
get().edges.filter((edge) => get().edges.filter((edge) =>
typeof edgeId === "string" typeof edgeId === "string"
? edge.id !== edgeId ? edge.id !== edgeId
: !edgeId.includes(edge.id) : !edgeId.includes(edge.id),
) ),
); );
}, },
paste: (selection, position) => { paste: (selection, position) => {
function updateGroup() {}
if ( if (
selection.nodes.some((node) => node.data.type === "ChatInput") && selection.nodes.some((node) => node.data.type === "ChatInput") &&
checkChatInput(get().nodes) checkChatInput(get().nodes)
@ -268,8 +266,6 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
let newId = getNodeId(node.data.type); let newId = getNodeId(node.data.type);
idsMap[node.id] = newId; idsMap[node.id] = newId;
updateGroupRecursion(node, selection.edges);
// Create a new node object // Create a new node object
const newNode: NodeType = { const newNode: NodeType = {
id: newId, id: newId,
@ -283,6 +279,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
id: newId, id: newId,
}, },
}; };
updateGroupRecursion(newNode, selection.edges);
// Add the new node to the list of nodes in state // Add the new node to the list of nodes in state
newNodes = newNodes newNodes = newNodes
@ -295,7 +292,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
let source = idsMap[edge.source]; let source = idsMap[edge.source];
let target = idsMap[edge.target]; let target = idsMap[edge.target];
const sourceHandleObject: sourceHandleType = scapeJSONParse( const sourceHandleObject: sourceHandleType = scapeJSONParse(
edge.sourceHandle! edge.sourceHandle!,
); );
let sourceHandle = scapedJSONStringfy({ let sourceHandle = scapedJSONStringfy({
...sourceHandleObject, ...sourceHandleObject,
@ -305,7 +302,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
edge.data.sourceHandle = sourceHandleObject; edge.data.sourceHandle = sourceHandleObject;
const targetHandleObject: targetHandleType = scapeJSONParse( const targetHandleObject: targetHandleType = scapeJSONParse(
edge.targetHandle! edge.targetHandle!,
); );
let targetHandle = scapedJSONStringfy({ let targetHandle = scapedJSONStringfy({
...targetHandleObject, ...targetHandleObject,
@ -326,7 +323,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
className: "stroke-gray-900 ", className: "stroke-gray-900 ",
selected: false, selected: false,
}, },
newEdges.map((edge) => ({ ...edge, selected: false })) newEdges.map((edge) => ({ ...edge, selected: false })),
); );
}); });
get().setEdges(newEdges); get().setEdges(newEdges);
@ -345,10 +342,10 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
}); });
const newNodes = get().nodes.filter( const newNodes = get().nodes.filter(
(node) => !nodesIdsSelected.includes(node.id) (node) => !nodesIdsSelected.includes(node.id),
); );
const newEdges = get().edges.filter( const newEdges = get().edges.filter(
(edge) => !edgesIdsSelected.includes(edge.id) (edge) => !edgesIdsSelected.includes(edge.id),
); );
set({ nodes: newNodes, edges: newEdges }); set({ nodes: newNodes, edges: newEdges });
@ -406,7 +403,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
style: { stroke: "#555" }, style: { stroke: "#555" },
className: "stroke-foreground stroke-connection", className: "stroke-foreground stroke-connection",
}, },
oldEdges oldEdges,
); );
return newEdges; return newEdges;
@ -416,7 +413,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
.autoSaveCurrentFlow( .autoSaveCurrentFlow(
get().nodes, get().nodes,
newEdges, newEdges,
get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 },
); );
}, },
unselectAll: () => { unselectAll: () => {
@ -447,7 +444,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
function validateSubgraph(nodes: string[]) { function validateSubgraph(nodes: string[]) {
const errorsObjs = validateNodes( const errorsObjs = validateNodes(
get().nodes.filter((node) => nodes.includes(node.id)), get().nodes.filter((node) => nodes.includes(node.id)),
get().edges get().edges,
); );
const errors = errorsObjs.map((obj) => obj.errors).flat(); const errors = errorsObjs.map((obj) => obj.errors).flat();
@ -466,7 +463,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
function handleBuildUpdate( function handleBuildUpdate(
vertexBuildData: VertexBuildTypeAPI, vertexBuildData: VertexBuildTypeAPI,
status: BuildStatus, status: BuildStatus,
runId: string runId: string,
) { ) {
if (vertexBuildData && vertexBuildData.inactivated_vertices) { if (vertexBuildData && vertexBuildData.inactivated_vertices) {
get().removeFromVerticesBuild(vertexBuildData.inactivated_vertices); get().removeFromVerticesBuild(vertexBuildData.inactivated_vertices);
@ -484,11 +481,11 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
// next_vertices_ids should be next_vertices_ids without the inactivated vertices // next_vertices_ids should be next_vertices_ids without the inactivated vertices
const next_vertices_ids = vertexBuildData.next_vertices_ids.filter( const next_vertices_ids = vertexBuildData.next_vertices_ids.filter(
(id) => !vertexBuildData.inactivated_vertices?.includes(id) (id) => !vertexBuildData.inactivated_vertices?.includes(id),
); );
const nextVertices: VertexLayerElementType[] = zip( const nextVertices: VertexLayerElementType[] = zip(
next_vertices_ids, next_vertices_ids,
vertexBuildData.top_level_vertices vertexBuildData.top_level_vertices,
).map(([id, reference]) => ({ id: id!, reference })); ).map(([id, reference]) => ({ id: id!, reference }));
const newLayers = [ const newLayers = [
@ -507,13 +504,13 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
}); });
get().updateBuildStatus( get().updateBuildStatus(
vertexBuildData.top_level_vertices, vertexBuildData.top_level_vertices,
BuildStatus.TO_BUILD BuildStatus.TO_BUILD,
); );
} }
get().addDataToFlowPool( get().addDataToFlowPool(
{ ...vertexBuildData, buildId: runId }, { ...vertexBuildData, buildId: runId },
vertexBuildData.id vertexBuildData.id,
); );
useFlowStore.getState().updateBuildStatus([vertexBuildData.id], status); useFlowStore.getState().updateBuildStatus([vertexBuildData.id], status);
@ -522,7 +519,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
const newFlowBuildStatus = { ...get().flowBuildStatus }; const newFlowBuildStatus = { ...get().flowBuildStatus };
// filter out the vertices that are not status // filter out the vertices that are not status
const verticesToUpdate = verticesIds?.filter( const verticesToUpdate = verticesIds?.filter(
(id) => newFlowBuildStatus[id]?.status !== BuildStatus.BUILT (id) => newFlowBuildStatus[id]?.status !== BuildStatus.BUILT,
); );
if (verticesToUpdate) { if (verticesToUpdate) {
@ -587,7 +584,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
verticesLayers: VertexLayerElementType[][]; verticesLayers: VertexLayerElementType[][];
runId: string; runId: string;
verticesToRun: string[]; verticesToRun: string[];
} | null } | null,
) => { ) => {
set({ verticesBuild: vertices }); set({ verticesBuild: vertices });
}, },
@ -612,7 +609,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
// that are going to be built // that are going to be built
verticesIds: get().verticesBuild!.verticesIds.filter( verticesIds: get().verticesBuild!.verticesIds.filter(
// keep the vertices that are not in the list of vertices to remove // keep the vertices that are not in the list of vertices to remove
(vertex) => !vertices.includes(vertex) (vertex) => !vertices.includes(vertex),
), ),
}, },
}); });

View file

@ -994,7 +994,6 @@ export function updateEdgesIds(
if (targetHandle.proxy && idsMap[targetHandle.proxy!.id]) { if (targetHandle.proxy && idsMap[targetHandle.proxy!.id]) {
targetHandle.proxy!.id = idsMap[targetHandle.proxy!.id]; targetHandle.proxy!.id = idsMap[targetHandle.proxy!.id];
} }
console.log("edge", edge);
edge.data.targetHandle = targetHandle; edge.data.targetHandle = targetHandle;
edge.targetHandle = scapedJSONStringfy(targetHandle); edge.targetHandle = scapedJSONStringfy(targetHandle);
}); });