update group to work with new outputs
This commit is contained in:
parent
41b0660dfd
commit
8ac7b4b27a
3 changed files with 112 additions and 78 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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[];
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue