update group to work with new outputs

This commit is contained in:
anovazzi1 2024-06-06 15:23:58 -03:00
commit 8ac7b4b27a
3 changed files with 112 additions and 78 deletions

View file

@ -110,7 +110,7 @@ export default function Page({
getRandomName(), getRandomName(),
); );
const newGroupNode = generateNodeFromFlow(newFlow, getNodeId); const newGroupNode = generateNodeFromFlow(newFlow, getNodeId);
const newEdges = reconnectEdges(newGroupNode, removedEdges); // const newEdges = reconnectEdges(newGroupNode, removedEdges);
setNodes([ setNodes([
...clonedNodes.filter( ...clonedNodes.filter(
(oldNodes) => (oldNodes) =>
@ -120,17 +120,17 @@ export default function Page({
), ),
newGroupNode, newGroupNode,
]); ]);
setEdges([ // setEdges([
...clonedEdges.filter( // ...clonedEdges.filter(
(oldEdge) => // (oldEdge) =>
!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,
]); // ]);
} else { } else {
setErrorData({ setErrorData({
title: INVALID_SELECTION_ERROR_ALERT, title: INVALID_SELECTION_ERROR_ALERT,

View file

@ -13,7 +13,7 @@ export type CustomFieldsType = {
}; };
export type APIClassType = { export type APIClassType = {
base_classes: Array<string>; base_classes?: Array<string>;
description: string; description: string;
template: APITemplateType; template: APITemplateType;
display_name: string; display_name: string;
@ -67,6 +67,8 @@ export type OutputFieldType = {
types: Array<string>; types: Array<string>;
selected?: string; selected?: string;
name: string; name: string;
displayName?: string;
proxy?: { id: string; name: string };
}; };
export type sendAllProps = { export type sendAllProps = {
nodes: Node[]; nodes: Node[];

View file

@ -24,6 +24,7 @@ import {
APIObjectType, APIObjectType,
APITemplateType, APITemplateType,
InputFieldType, InputFieldType,
OutputFieldType,
} from "../types/api"; } from "../types/api";
import { import {
FlowType, FlowType,
@ -78,7 +79,7 @@ export function cleanEdges(nodes: NodeType[], edges: Edge[]) {
const parsedSourceHandle = scapeJSONParse(sourceHandle); const parsedSourceHandle = scapeJSONParse(sourceHandle);
const name = parsedSourceHandle.name; const name = parsedSourceHandle.name;
const output = sourceNode.data.node!.outputs?.find( const output = sourceNode.data.node!.outputs?.find(
(output) => output.name === name (output) => output.name === name,
); );
if (output) { if (output) {
const outputTypes = const outputTypes =
@ -112,18 +113,18 @@ export function unselectAllNodes({ updateNodes, data }: unselectAllNodesType) {
export function isValidConnection( export function isValidConnection(
{ source, target, sourceHandle, targetHandle }: Connection, { source, target, sourceHandle, targetHandle }: Connection,
nodes: Node[], nodes: Node[],
edges: Edge[] edges: Edge[],
) { ) {
const targetHandleObject: targetHandleType = scapeJSONParse(targetHandle!); const targetHandleObject: targetHandleType = scapeJSONParse(targetHandle!);
const sourceHandleObject: sourceHandleType = scapeJSONParse(sourceHandle!); const sourceHandleObject: sourceHandleType = scapeJSONParse(sourceHandle!);
if ( if (
targetHandleObject.inputTypes?.some( targetHandleObject.inputTypes?.some(
(n) => n === sourceHandleObject.dataType (n) => n === sourceHandleObject.dataType,
) || ) ||
sourceHandleObject.output_types.some( sourceHandleObject.output_types.some(
(t) => (t) =>
targetHandleObject.inputTypes?.some((n) => n === t) || targetHandleObject.inputTypes?.some((n) => n === t) ||
t === targetHandleObject.type t === targetHandleObject.type,
) )
) { ) {
let targetNode = nodes.find((node) => node.id === target!)?.data?.node; let targetNode = nodes.find((node) => node.id === target!)?.data?.node;
@ -156,7 +157,7 @@ export function removeApiKeys(flow: FlowType): FlowType {
export function updateTemplate( export function updateTemplate(
reference: APITemplateType, reference: APITemplateType,
objectToUpdate: APITemplateType objectToUpdate: APITemplateType,
): APITemplateType { ): APITemplateType {
let clonedObject: APITemplateType = cloneDeep(reference); let clonedObject: APITemplateType = cloneDeep(reference);
@ -216,7 +217,7 @@ export const processDataFromFlow = (flow: FlowType, refreshIds = true) => {
export function updateIds( export function updateIds(
{ edges, nodes }: { edges: Edge[]; nodes: Node[] }, { edges, nodes }: { edges: Edge[]; nodes: Node[] },
selection?: { edges: Edge[]; nodes: Node[] } selection?: { edges: Edge[]; nodes: Node[] },
) { ) {
let idsMap = {}; let idsMap = {};
const selectionIds = selection?.nodes.map((n) => n.id); const selectionIds = selection?.nodes.map((n) => n.id);
@ -244,7 +245,7 @@ export function updateIds(
edge.source = idsMap[edge.source]; edge.source = idsMap[edge.source];
edge.target = idsMap[edge.target]; edge.target = idsMap[edge.target];
const sourceHandleObject: sourceHandleType = scapeJSONParse( const sourceHandleObject: sourceHandleType = scapeJSONParse(
edge.sourceHandle! edge.sourceHandle!,
); );
edge.sourceHandle = scapedJSONStringfy({ edge.sourceHandle = scapedJSONStringfy({
...sourceHandleObject, ...sourceHandleObject,
@ -254,7 +255,7 @@ export function updateIds(
edge.data.sourceHandle.id = edge.source; edge.data.sourceHandle.id = edge.source;
} }
const targetHandleObject: targetHandleType = scapeJSONParse( const targetHandleObject: targetHandleType = scapeJSONParse(
edge.targetHandle! edge.targetHandle!,
); );
edge.targetHandle = scapedJSONStringfy({ edge.targetHandle = scapedJSONStringfy({
...targetHandleObject, ...targetHandleObject,
@ -300,11 +301,11 @@ export function validateNode(node: NodeType, edges: Edge[]): Array<string> {
(scapeJSONParse(edge.targetHandle!) as targetHandleType).fieldName === (scapeJSONParse(edge.targetHandle!) as targetHandleType).fieldName ===
t && t &&
(scapeJSONParse(edge.targetHandle!) as targetHandleType).id === (scapeJSONParse(edge.targetHandle!) as targetHandleType).id ===
node.id node.id,
) )
) { ) {
errors.push( errors.push(
`${displayName || type} is missing ${getFieldTitle(template, t)}.` `${displayName || type} is missing ${getFieldTitle(template, t)}.`,
); );
} else if ( } else if (
template[t].type === "dict" && template[t].type === "dict" &&
@ -318,15 +319,15 @@ export function validateNode(node: NodeType, edges: Edge[]): Array<string> {
errors.push( errors.push(
`${displayName || type} (${getFieldTitle( `${displayName || type} (${getFieldTitle(
template, template,
t t,
)}) contains duplicate keys with the same values.` )}) contains duplicate keys with the same values.`,
); );
if (hasEmptyKey(template[t].value)) if (hasEmptyKey(template[t].value))
errors.push( errors.push(
`${displayName || type} (${getFieldTitle( `${displayName || type} (${getFieldTitle(
template, template,
t t,
)}) field must not be empty.` )}) field must not be empty.`,
); );
} }
return errors; return errors;
@ -335,7 +336,7 @@ export function validateNode(node: NodeType, edges: Edge[]): Array<string> {
export function validateNodes( export function validateNodes(
nodes: Node[], nodes: Node[],
edges: Edge[] edges: Edge[],
): // this returns an array of tuples with the node id and the errors ): // this returns an array of tuples with the node id and the errors
Array<{ id: string; errors: Array<string> }> { Array<{ id: string; errors: Array<string> }> {
if (nodes.length === 0) { if (nodes.length === 0) {
@ -356,7 +357,7 @@ export function updateEdges(edges: Edge[]) {
if (edges) if (edges)
edges.forEach((edge) => { edges.forEach((edge) => {
const targetHandleObject: targetHandleType = scapeJSONParse( const targetHandleObject: targetHandleType = scapeJSONParse(
edge.targetHandle! edge.targetHandle!,
); );
edge.className = "stroke-gray-900 stroke-connection"; edge.className = "stroke-gray-900 stroke-connection";
}); });
@ -406,7 +407,7 @@ export function updateEdgesHandleIds({
if (source && sourceNode) { if (source && sourceNode) {
const output_types = const output_types =
sourceNode.data.node!.output_types ?? sourceNode.data.node!.output_types ??
sourceNode.data.node!.base_classes; sourceNode.data.node!.base_classes!;
newSource = { newSource = {
id: sourceNode.data.id, id: sourceNode.data.id,
output_types, output_types,
@ -456,11 +457,11 @@ export function updateNewOutput({ nodes, edges }: updateEdgesHandleIdsType) {
if (newTargetHandle.inputTypes && newTargetHandle.inputTypes.length > 0) { if (newTargetHandle.inputTypes && newTargetHandle.inputTypes.length > 0) {
//conjuction subtraction //conjuction subtraction
intersection = newSourceHandle.output_types.filter((type) => intersection = newSourceHandle.output_types.filter((type) =>
newTargetHandle.inputTypes!.includes(type) newTargetHandle.inputTypes!.includes(type),
); );
} else { } else {
intersection = newSourceHandle.output_types.filter( intersection = newSourceHandle.output_types.filter(
(type) => type === newTargetHandle.type (type) => type === newTargetHandle.type,
); );
} }
const selected = intersection[0]; const selected = intersection[0];
@ -472,10 +473,10 @@ export function updateNewOutput({ nodes, edges }: updateEdgesHandleIdsType) {
} }
const types = const types =
sourceNode.data.node!.output_types ?? sourceNode.data.node!.output_types ??
sourceNode.data.node!.base_classes; sourceNode.data.node!.base_classes!;
if ( if (
!sourceNode.data.node!.outputs.some( !sourceNode.data.node!.outputs.some(
(output) => output.selected === selected (output) => output.selected === selected,
) )
) { ) {
sourceNode.data.node!.outputs.push({ sourceNode.data.node!.outputs.push({
@ -498,7 +499,7 @@ export function handleKeyDown(
| React.KeyboardEvent<HTMLInputElement> | React.KeyboardEvent<HTMLInputElement>
| React.KeyboardEvent<HTMLTextAreaElement>, | React.KeyboardEvent<HTMLTextAreaElement>,
inputValue: string | string[] | null, inputValue: string | string[] | null,
block: string block: string,
) { ) {
//condition to fix bug control+backspace on Windows/Linux //condition to fix bug control+backspace on Windows/Linux
if ( if (
@ -523,7 +524,7 @@ export function handleKeyDown(
} }
export function handleOnlyIntegerInput( export function handleOnlyIntegerInput(
event: React.KeyboardEvent<HTMLInputElement> event: React.KeyboardEvent<HTMLInputElement>,
) { ) {
if ( if (
event.key === "." || event.key === "." ||
@ -539,7 +540,7 @@ export function handleOnlyIntegerInput(
export function getConnectedNodes( export function getConnectedNodes(
edge: Edge, edge: Edge,
nodes: Array<NodeType> nodes: Array<NodeType>,
): Array<NodeType> { ): Array<NodeType> {
const sourceId = edge.source; const sourceId = edge.source;
const targetId = edge.target; const targetId = edge.target;
@ -640,7 +641,7 @@ export function checkOldEdgesHandles(edges: Edge[]): boolean {
!edge.sourceHandle || !edge.sourceHandle ||
!edge.targetHandle || !edge.targetHandle ||
!edge.sourceHandle.includes("{") || !edge.sourceHandle.includes("{") ||
!edge.targetHandle.includes("{") !edge.targetHandle.includes("{"),
); );
} }
@ -667,7 +668,7 @@ export function customStringify(obj: any): string {
const keys = Object.keys(obj).sort(); const keys = Object.keys(obj).sort();
const keyValuePairs = keys.map( const keyValuePairs = keys.map(
(key) => `"${key}":${customStringify(obj[key])}` (key) => `"${key}":${customStringify(obj[key])}`,
); );
return `{${keyValuePairs.join(",")}}`; return `{${keyValuePairs.join(",")}}`;
} }
@ -696,7 +697,7 @@ export function getHandleId(
source: string, source: string,
sourceHandle: string, sourceHandle: string,
target: string, target: string,
targetHandle: string targetHandle: string,
) { ) {
return ( return (
"reactflow__edge-" + source + sourceHandle + "-" + target + targetHandle "reactflow__edge-" + source + sourceHandle + "-" + target + targetHandle
@ -707,16 +708,16 @@ export function generateFlow(
selection: OnSelectionChangeParams, selection: OnSelectionChangeParams,
nodes: Node[], nodes: Node[],
edges: Edge[], edges: Edge[],
name: string name: string,
): generateFlowType { ): generateFlowType {
const newFlowData = { nodes, edges, viewport: { zoom: 1, x: 0, y: 0 } }; const newFlowData = { nodes, edges, viewport: { zoom: 1, x: 0, y: 0 } };
const uid = new ShortUniqueId({ length: 5 }); const uid = new ShortUniqueId({ length: 5 });
/* remove edges that are not connected to selected nodes on both ends /* remove edges that are not connected to selected nodes on both ends
*/ */
newFlowData.edges = selection.edges.filter( newFlowData.edges = edges.filter(
(edge) => (edge) =>
selection.nodes.some((node) => node.id === edge.target) && selection.nodes.some((node) => node.id === edge.target) &&
selection.nodes.some((node) => node.id === edge.source) selection.nodes.some((node) => node.id === edge.source),
); );
newFlowData.nodes = selection.nodes; newFlowData.nodes = selection.nodes;
@ -737,7 +738,7 @@ export function generateFlow(
(edge) => (edge) =>
(selection.nodes.some((node) => node.id === edge.target) || (selection.nodes.some((node) => node.id === edge.target) ||
selection.nodes.some((node) => node.id === edge.source)) && selection.nodes.some((node) => node.id === edge.source)) &&
newFlowData.edges.every((e) => e.id !== edge.id) newFlowData.edges.every((e) => e.id !== edge.id),
), ),
}; };
} }
@ -748,13 +749,13 @@ export function reconnectEdges(groupNode: NodeType, excludedEdges: Edge[]) {
const { nodes, edges } = groupNode.data.node!.flow!.data!; const { nodes, edges } = groupNode.data.node!.flow!.data!;
const lastNode = findLastNode(groupNode.data.node!.flow!.data!); const lastNode = findLastNode(groupNode.data.node!.flow!.data!);
newEdges = newEdges.filter( newEdges = newEdges.filter(
(e) => !(nodes.some((n) => n.id === e.source) && e.source !== lastNode?.id) (e) => !(nodes.some((n) => n.id === e.source) && e.source !== lastNode?.id),
); );
newEdges.forEach((edge) => { newEdges.forEach((edge) => {
if (lastNode && edge.source === lastNode.id) { if (lastNode && edge.source === lastNode.id) {
edge.source = groupNode.id; edge.source = groupNode.id;
let newSourceHandle: sourceHandleType = scapeJSONParse( let newSourceHandle: sourceHandleType = scapeJSONParse(
edge.sourceHandle! edge.sourceHandle!,
); );
newSourceHandle.id = groupNode.id; newSourceHandle.id = groupNode.id;
edge.sourceHandle = scapedJSONStringfy(newSourceHandle); edge.sourceHandle = scapedJSONStringfy(newSourceHandle);
@ -781,7 +782,7 @@ export function reconnectEdges(groupNode: NodeType, excludedEdges: Edge[]) {
export function filterFlow( export function filterFlow(
selection: OnSelectionChangeParams, selection: OnSelectionChangeParams,
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void, setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void,
) { ) {
setNodes((nodes) => nodes.filter((node) => !selection.nodes.includes(node))); setNodes((nodes) => nodes.filter((node) => !selection.nodes.includes(node)));
setEdges((edges) => edges.filter((edge) => !selection.edges.includes(edge))); setEdges((edges) => edges.filter((edge) => !selection.edges.includes(edge)));
@ -819,7 +820,7 @@ export function updateFlowPosition(NewPosition: XYPosition, flow: FlowType) {
export function concatFlows( export function concatFlows(
flow: FlowType, flow: FlowType,
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void, setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void,
) { ) {
const { nodes, edges } = flow.data!; const { nodes, edges } = flow.data!;
setNodes((old) => [...old, ...nodes]); setNodes((old) => [...old, ...nodes]);
@ -828,7 +829,7 @@ export function concatFlows(
export function validateSelection( export function validateSelection(
selection: OnSelectionChangeParams, selection: OnSelectionChangeParams,
edges: Edge[] edges: Edge[],
): Array<string> { ): Array<string> {
const clonedSelection = cloneDeep(selection); const clonedSelection = cloneDeep(selection);
const clonedEdges = cloneDeep(edges); const clonedEdges = cloneDeep(edges);
@ -842,7 +843,7 @@ export function validateSelection(
let nodesSet = new Set(clonedSelection.nodes.map((n) => n.id)); let nodesSet = new Set(clonedSelection.nodes.map((n) => n.id));
// then filter the edges that are connected to the nodes in the set // then filter the edges that are connected to the nodes in the set
let connectedEdges = clonedSelection.edges.filter( let connectedEdges = clonedSelection.edges.filter(
(e) => nodesSet.has(e.source) && nodesSet.has(e.target) (e) => nodesSet.has(e.source) && nodesSet.has(e.target),
); );
// add the edges to the selection // add the edges to the selection
clonedSelection.edges = connectedEdges; clonedSelection.edges = connectedEdges;
@ -856,17 +857,17 @@ export function validateSelection(
clonedSelection.nodes.some( clonedSelection.nodes.some(
(node) => (node) =>
isInputNode(node.data as NodeDataType) || isInputNode(node.data as NodeDataType) ||
isOutputNode(node.data as NodeDataType) isOutputNode(node.data as NodeDataType),
) )
) { ) {
errorsArray.push( errorsArray.push(
"Please select only nodes that are not input or output nodes" "Please select only nodes that are not input or output nodes",
); );
} }
//check if there are two or more nodes with free outputs //check if there are two or more nodes with free outputs
if ( if (
clonedSelection.nodes.filter( clonedSelection.nodes.filter(
(n) => !clonedSelection.edges.some((e) => e.source === n.id) (n) => !clonedSelection.edges.some((e) => e.source === n.id),
).length > 1 ).length > 1
) { ) {
errorsArray.push("Please select only one node with free outputs"); errorsArray.push("Please select only one node with free outputs");
@ -877,7 +878,7 @@ export function validateSelection(
clonedSelection.nodes.some( clonedSelection.nodes.some(
(node) => (node) =>
!clonedSelection.edges.some((edge) => edge.target === node.id) && !clonedSelection.edges.some((edge) => edge.target === node.id) &&
!clonedSelection.edges.some((edge) => edge.source === node.id) !clonedSelection.edges.some((edge) => edge.source === node.id),
) )
) { ) {
errorsArray.push("Please select only nodes that are connected"); errorsArray.push("Please select only nodes that are connected");
@ -922,7 +923,7 @@ export function mergeNodeTemplates({
Object.keys(nodeTemplate) Object.keys(nodeTemplate)
.filter((field_name) => field_name.charAt(0) !== "_") .filter((field_name) => field_name.charAt(0) !== "_")
.forEach((key) => { .forEach((key) => {
if (!isHandleConnected(edges, key, nodeTemplate[key], node.id)) { if (!isTargetHandleConnected(edges, key, nodeTemplate[key], node.id)) {
template[key + "_" + node.id] = nodeTemplate[key]; template[key + "_" + node.id] = nodeTemplate[key];
template[key + "_" + node.id].proxy = { id: node.id, field: key }; template[key + "_" + node.id].proxy = { id: node.id, field: key };
if (node.type === "groupNode") { if (node.type === "groupNode") {
@ -934,19 +935,19 @@ export function mergeNodeTemplates({
nodeTemplate[key].display_name nodeTemplate[key].display_name
? nodeTemplate[key].display_name ? nodeTemplate[key].display_name
: nodeTemplate[key].name : nodeTemplate[key].name
? toTitleCase(nodeTemplate[key].name) ? toTitleCase(nodeTemplate[key].name)
: toTitleCase(key); : toTitleCase(key);
} }
} }
}); });
}); });
return template; return template;
} }
function isHandleConnected( function isTargetHandleConnected(
edges: Edge[], edges: Edge[],
key: string, key: string,
field: InputFieldType, field: InputFieldType,
nodeId: string nodeId: string,
) { ) {
/* /*
this function receives a flow and a handleId and check if there is a connection with this handle this function receives a flow and a handleId and check if there is a connection with this handle
@ -962,7 +963,7 @@ function isHandleConnected(
id: nodeId, id: nodeId,
proxy: { id: field.proxy!.id, field: field.proxy!.field }, proxy: { id: field.proxy!.id, field: field.proxy!.field },
inputTypes: field.input_types, inputTypes: field.input_types,
} as targetHandleType) } as targetHandleType),
) )
) { ) {
return true; return true;
@ -977,7 +978,7 @@ function isHandleConnected(
fieldName: key, fieldName: key,
id: nodeId, id: nodeId,
inputTypes: field.input_types, inputTypes: field.input_types,
} as targetHandleType) } as targetHandleType),
) )
) { ) {
return true; return true;
@ -1000,25 +1001,24 @@ export function generateNodeTemplate(Flow: FlowType) {
export function generateNodeFromFlow( export function generateNodeFromFlow(
flow: FlowType, flow: FlowType,
getNodeId: (type: string) => string getNodeId: (type: string) => string,
): NodeType { ): NodeType {
const { nodes } = flow.data!; const { nodes } = flow.data!;
const outputNode = cloneDeep(findLastNode(flow.data!)); const outputNode = cloneDeep(findLastNode(flow.data!));
const position = getMiddlePoint(nodes); const position = getMiddlePoint(nodes);
let data = cloneDeep(flow); let data = cloneDeep(flow);
const id = getNodeId(outputNode?.data.type!); const id = getNodeId("groupComponent");
const newGroupNode: NodeType = { const newGroupNode: NodeType = {
data: { data: {
id, id,
type: outputNode?.data.type!, type: "GroupNode",
node: { node: {
output_types: outputNode!.data.node!.output_types,
display_name: "Group", display_name: "Group",
documentation: "", documentation: "",
base_classes: outputNode!.data.node!.base_classes,
description: "", description: "",
template: generateNodeTemplate(data), template: generateNodeTemplate(data),
flow: data, flow: data,
outputs: generateNodeOutputs(data),
}, },
}, },
id, id,
@ -1028,10 +1028,42 @@ export function generateNodeFromFlow(
return newGroupNode; return newGroupNode;
} }
function generateNodeOutputs(flow: FlowType) {
const { nodes, edges } = flow.data!;
const outputs: Array<OutputFieldType> = [];
nodes.forEach((node: NodeType) => {
if (node.data.node?.outputs) {
const nodeOutputs = node.data.node.outputs;
nodeOutputs.forEach((output) => {
//filter outputs that are not connected
console.log(output);
console.log(edges);
if (
!edges.some(
(edge) =>
edge.source === node.id &&
(edge.data.sourceHandle as sourceHandleType).name === output.name,
)
) {
outputs.push(
cloneDeep({
...output,
proxy: { id: node.id, name: output.name },
name: node.id + "_" + output.name,
displayName: output.displayName,
}),
);
}
});
}
});
return outputs;
}
export function connectedInputNodesOnHandle( export function connectedInputNodesOnHandle(
nodeId: string, nodeId: string,
handleId: string, handleId: string,
{ nodes, edges }: { nodes: NodeType[]; edges: Edge[] } { nodes, edges }: { nodes: NodeType[]; edges: Edge[] },
) { ) {
const connectedNodes: Array<{ name: string; id: string; isGroup: boolean }> = const connectedNodes: Array<{ name: string; id: string; isGroup: boolean }> =
[]; [];
@ -1068,7 +1100,7 @@ export function connectedInputNodesOnHandle(
export function updateProxyIdsOnTemplate( export function updateProxyIdsOnTemplate(
template: APITemplateType, template: APITemplateType,
idsMap: { [key: string]: string } idsMap: { [key: string]: string },
) { ) {
Object.keys(template).forEach((key) => { Object.keys(template).forEach((key) => {
if (template[key].proxy && idsMap[template[key].proxy!.id]) { if (template[key].proxy && idsMap[template[key].proxy!.id]) {
@ -1079,7 +1111,7 @@ export function updateProxyIdsOnTemplate(
export function updateEdgesIds( export function updateEdgesIds(
edges: Edge[], edges: Edge[],
idsMap: { [key: string]: string } idsMap: { [key: string]: string },
) { ) {
edges.forEach((edge) => { edges.forEach((edge) => {
let targetHandle: targetHandleType = edge.data.targetHandle; let targetHandle: targetHandleType = edge.data.targetHandle;
@ -1120,7 +1152,7 @@ export function expandGroupNode(
nodes: Node[], nodes: Node[],
edges: Edge[], edges: Edge[],
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void, setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void,
) { ) {
const idsMap = updateIds(flow!.data!); const idsMap = updateIds(flow!.data!);
updateProxyIdsOnTemplate(template, idsMap); updateProxyIdsOnTemplate(template, idsMap);
@ -1163,7 +1195,7 @@ export function expandGroupNode(
const lastNode = cloneDeep(findLastNode(flow!.data!)); const lastNode = cloneDeep(findLastNode(flow!.data!));
newEdge.source = lastNode!.id; newEdge.source = lastNode!.id;
let newSourceHandle: sourceHandleType = scapeJSONParse( let newSourceHandle: sourceHandleType = scapeJSONParse(
newEdge.sourceHandle! newEdge.sourceHandle!,
); );
newSourceHandle.id = lastNode!.id; newSourceHandle.id = lastNode!.id;
newEdge.data.sourceHandle = newSourceHandle; newEdge.data.sourceHandle = newSourceHandle;
@ -1220,7 +1252,7 @@ export function expandGroupNode(
export function getGroupStatus( export function getGroupStatus(
flow: FlowType, flow: FlowType,
ssData: { [key: string]: { valid: boolean; params: string } } ssData: { [key: string]: { valid: boolean; params: string } },
) { ) {
let status = { valid: true, params: SUCCESS_BUILD }; let status = { valid: true, params: SUCCESS_BUILD };
const { nodes } = flow.data!; const { nodes } = flow.data!;
@ -1239,7 +1271,7 @@ export function getGroupStatus(
export function createFlowComponent( export function createFlowComponent(
nodeData: NodeDataType, nodeData: NodeDataType,
version: string version: string,
): FlowType { ): FlowType {
const flowNode: FlowType = { const flowNode: FlowType = {
data: { data: {
@ -1275,7 +1307,7 @@ export function downloadNode(NodeFLow: FlowType) {
export function updateComponentNameAndType( export function updateComponentNameAndType(
data: any, data: any,
component: NodeDataType component: NodeDataType,
) {} ) {}
export function removeFileNameFromComponents(flow: FlowType) { export function removeFileNameFromComponents(flow: FlowType) {
@ -1349,7 +1381,7 @@ export function extractFieldsFromComponenents(data: APIObjectType) {
export function downloadFlow( export function downloadFlow(
flow: FlowType, flow: FlowType,
flowName: string, flowName: string,
flowDescription?: string flowDescription?: string,
) { ) {
let clonedFlow = cloneDeep(flow); let clonedFlow = cloneDeep(flow);
removeFileNameFromComponents(clonedFlow); removeFileNameFromComponents(clonedFlow);
@ -1359,7 +1391,7 @@ export function downloadFlow(
...clonedFlow, ...clonedFlow,
name: flowName, name: flowName,
description: flowDescription, description: flowDescription,
}) }),
)}`; )}`;
// create a link element and set its properties // create a link element and set its properties
@ -1374,7 +1406,7 @@ export function downloadFlow(
export function downloadFlows() { export function downloadFlows() {
downloadFlowsFromDatabase().then((flows) => { downloadFlowsFromDatabase().then((flows) => {
const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent( const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent(
JSON.stringify(flows) JSON.stringify(flows),
)}`; )}`;
// create a link element and set its properties // create a link element and set its properties
@ -1398,7 +1430,7 @@ export function getRandomDescription(): string {
export const createNewFlow = ( export const createNewFlow = (
flowData: ReactFlowJsonObject, flowData: ReactFlowJsonObject,
flow: FlowType, flow: FlowType,
folderId: string folderId: string,
) => { ) => {
return { return {
description: flow?.description ?? getRandomDescription(), description: flow?.description ?? getRandomDescription(),