Merge branch 'dev' into zustand/io/migration

This commit is contained in:
Lucas Oliveira 2024-01-31 11:54:25 +01:00
commit 89cb0f9e22
7 changed files with 51 additions and 176 deletions

View file

@ -57,7 +57,6 @@ export default function ParameterComponent({
proxy,
showNode,
index = "",
isMinimized,
}: ParameterComponentType): JSX.Element {
const ref = useRef<HTMLDivElement>(null);
const refHtml = useRef<HTMLDivElement & ReactNode>(null);
@ -289,7 +288,7 @@ export default function ParameterComponent({
className={classNames(
left ? "my-12 -ml-0.5 " : " my-12 -mr-0.5 ",
"h-3 w-3 rounded-full border-2 bg-background",
isMinimized ? "mt-0" : ""
!showNode ? "mt-0" : ""
)}
style={{
borderColor: color,

View file

@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { NodeToolbar, useUpdateNodeInternals } from "reactflow";
import { NodeToolbar } from "reactflow";
import ShadTooltip from "../../components/ShadTooltipComponent";
import Tooltip from "../../components/TooltipComponent";
import IconComponent from "../../components/genericIconComponent";
@ -43,15 +43,12 @@ export default function GenericNode({
);
const [validationStatus, setValidationStatus] =
useState<validationStatusType | null>(null);
const [handles, setHandles] = useState<boolean[] | []>([]);
const [isMinimized, setIsMinimized] = useState<boolean>(false);
let numberOfInputs: boolean[] = [];
const updateNodeInternals = useUpdateNodeInternals();
const [handles, setHandles] = useState<number>(0);
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
function countHandles(): void {
numberOfInputs = Object.keys(data.node!.template)
let count = Object.keys(data.node!.template)
.filter((templateField) => templateField.charAt(0) !== "_")
.map((templateCamp) => {
const { template } = data.node!;
@ -59,24 +56,20 @@ export default function GenericNode({
if (!template[templateCamp].show) return false;
switch (template[templateCamp].type) {
case "str":
return false;
case "bool":
return false;
case "float":
return false;
case "code":
return false;
case "prompt":
return false;
case "file":
return false;
case "int":
return false;
default:
return true;
}
});
setHandles(numberOfInputs);
})
.reduce((total, value) => total + (value ? 1 : 0), 0);
setHandles(count);
}
useEffect(() => {
@ -119,10 +112,6 @@ export default function GenericNode({
const nameEditable = data.node?.flow || data.type === "CustomComponent";
useEffect(() => {
updateNodeInternals(data.id);
}, [isMinimized]);
return (
<>
<NodeToolbar>
@ -141,7 +130,6 @@ export default function GenericNode({
}}
numberOfHandles={handles}
showNode={showNode}
setIsMinimized={setIsMinimized}
></NodeToolbarComponent>
</NodeToolbar>
@ -295,7 +283,6 @@ export default function GenericNode({
}
proxy={data.node?.template[templateField].proxy}
showNode={showNode}
isMinimized={isMinimized}
/>
)
)}
@ -322,7 +309,6 @@ export default function GenericNode({
type={data.node?.base_classes.join("|")}
left={false}
showNode={showNode}
isMinimized={isMinimized}
/>
</>
)}
@ -563,7 +549,6 @@ export default function GenericNode({
}
proxy={data.node?.template[templateField].proxy}
showNode={showNode}
isMinimized={isMinimized}
/>
) : (
<></>
@ -607,7 +592,6 @@ export default function GenericNode({
type={data.node?.base_classes.join("|")}
left={false}
showNode={showNode}
isMinimized={isMinimized}
/>
)}
</>

View file

@ -146,6 +146,7 @@ export default function CodeAreaModal({
<BaseModal.Content>
<Input
value={code}
readOnly
className="absolute left-[500%] top-[500%]"
id="codeValue"
/>

View file

@ -32,7 +32,6 @@ export default function NodeToolbarComponent({
setShowNode,
numberOfHandles,
showNode,
setIsMinimized,
}: nodeToolbarPropsType): JSX.Element {
const nodeLength = Object.keys(data.node!.template).filter(
(templateField) =>
@ -54,15 +53,7 @@ export default function NodeToolbarComponent({
const hasApiKey = useStoreStore((state) => state.hasApiKey);
const validApiKey = useStoreStore((state) => state.validApiKey);
function canMinimize() {
let countHandles: number = 0;
numberOfHandles.forEach((bool) => {
if (bool) countHandles += 1;
});
if (countHandles > 1) return false;
return true;
}
const isMinimal = canMinimize();
const isMinimal = numberOfHandles <= 1;
const isGroup = data.node?.flow ? true : false;
const paste = useFlowStore((state) => state.paste);
@ -77,7 +68,6 @@ export default function NodeToolbarComponent({
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
const [showModalAdvanced, setShowModalAdvanced] = useState(false);
const [showconfirmShare, setShowconfirmShare] = useState(false);
const [selectedValue, setSelectedValue] = useState("");
const [showOverrideModal, setShowOverrideModal] = useState(false);
const [flowComponent, setFlowComponent] = useState<FlowType>();
@ -98,10 +88,6 @@ export default function NodeToolbarComponent({
showconfirmShare,
]);
useEffect(() => {
setIsMinimized(!showNode);
}, [showNode]);
const handleSelectChange = (event) => {
switch (event) {
case "advanced":
@ -112,7 +98,7 @@ export default function NodeToolbarComponent({
setShowNode(data.showNode ?? true ? false : true);
break;
case "Download":
downloadNode(createFlowComponent(cloneDeep(data), version));
downloadNode(flowComponent!);
break;
case "SaveAll":
saveComponent(cloneDeep(data), false);
@ -124,8 +110,7 @@ export default function NodeToolbarComponent({
break;
case "ungroup":
takeSnapshot();
updateFlowPosition(position, data.node?.flow!);
expandGroupNode(data, nodes, edges, setNodes, setEdges);
expandGroupNode(data.id, updateFlowPosition(position, data.node?.flow!), data.node!.template, nodes, edges, setNodes, setEdges);
break;
case "override":
setShowOverrideModal(true);
@ -196,7 +181,7 @@ export default function NodeToolbarComponent({
</ShadTooltip>
)}
<Select onValueChange={handleSelectChange} value={selectedValue}>
<Select onValueChange={handleSelectChange}>
<ShadTooltip content="More" side="top">
<SelectTrigger>
<div>

View file

@ -24,6 +24,7 @@ import useAlertStore from "./alertStore";
import { useDarkStore } from "./darkStore";
import useFlowStore from "./flowStore";
import { useTypesStore } from "./typesStore";
import { cloneDeep } from "lodash";
let saveTimeoutId: NodeJS.Timeout | null = null;
@ -328,13 +329,16 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
takeSnapshot: () => {
const currentFlowId = get().currentFlowId;
// push the current graph to the past state
const newState = useFlowStore.getState();
const flowStore = useFlowStore.getState();
const newState = {nodes: cloneDeep(flowStore.nodes), edges: cloneDeep(flowStore.edges)};
const pastLength = past[currentFlowId]?.length ?? 0;
if (
pastLength > 0 &&
JSON.stringify(past[currentFlowId][pastLength - 1]) !==
JSON.stringify(past[currentFlowId][pastLength - 1]) ===
JSON.stringify(newState)
) {
)
return;
if (pastLength > 0) {
past[currentFlowId] = past[currentFlowId].slice(
pastLength - defaultOptions.maxHistorySize + 1,
pastLength

View file

@ -53,7 +53,6 @@ export type ParameterComponentType = {
showNode?: boolean;
index?: string;
onCloseModal?: (close: boolean) => void;
isMinimized?: boolean;
};
export type InputListComponentType = {
value: string[];
@ -479,9 +478,8 @@ export type nodeToolbarPropsType = {
deleteNode: (idx: string) => void;
position: XYPosition;
setShowNode: (boolean: any) => void;
numberOfHandles: boolean[] | [];
numberOfHandles: number;
showNode: boolean;
setIsMinimized: (boolean: boolean) => void;
};
export type parsedDataType = {

View file

@ -1,4 +1,4 @@
import _, { cloneDeep } from "lodash";
import { cloneDeep } from "lodash";
import {
Connection,
Edge,
@ -45,7 +45,7 @@ import {
const uid = new ShortUniqueId({ length: 5 });
export function cleanEdges(nodes: Node[], edges: Edge[]) {
let newEdges = _.cloneDeep(edges);
let newEdges = cloneDeep(edges);
edges.forEach((edge) => {
// check if the source and target node still exists
const sourceNode = nodes.find((node) => node.id === edge.source);
@ -88,7 +88,7 @@ export function cleanEdges(nodes: Node[], edges: Edge[]) {
}
export function unselectAllNodes({ updateNodes, data }: unselectAllNodesType) {
let newNodes = _.cloneDeep(data);
let newNodes = cloneDeep(data);
newNodes.forEach((node: Node) => {
node.selected = false;
});
@ -129,7 +129,7 @@ export function isValidConnection(
}
export function removeApiKeys(flow: FlowType): FlowType {
let cleanFLow = _.cloneDeep(flow);
let cleanFLow = cloneDeep(flow);
cleanFLow.data!.nodes.forEach((node) => {
for (const key in node.data.node.template) {
if (node.data.node.template[key].password) {
@ -144,7 +144,7 @@ export function updateTemplate(
reference: APITemplateType,
objectToUpdate: APITemplateType
): APITemplateType {
let clonedObject: APITemplateType = _.cloneDeep(reference);
let clonedObject: APITemplateType = cloneDeep(reference);
// Loop through each key in the reference object
for (const key in clonedObject) {
@ -349,7 +349,7 @@ export function updateEdgesHandleIds({
edges,
nodes,
}: updateEdgesHandleIdsType): Edge[] {
let newEdges = _.cloneDeep(edges);
let newEdges = cloneDeep(edges);
newEdges.forEach((edge) => {
const sourceNodeId = edge.source;
const targetNodeId = edge.target;
@ -653,10 +653,13 @@ export function updateFlowPosition(NewPosition: XYPosition, flow: FlowType) {
x: NewPosition.x - middlePoint.x,
y: NewPosition.y - middlePoint.y,
};
flow.data!.nodes.forEach((node) => {
node.position.x += deltaPosition.x;
node.position.y += deltaPosition.y;
});
return {...flow, data: {...flow.data!, nodes: flow.data!.nodes.map((node) => ({
...node,
position: {
x: node.position.x + deltaPosition.x,
y: node.position.y + deltaPosition.y,
},
}))}};
}
export function concatFlows(
@ -759,7 +762,7 @@ export function mergeNodeTemplates({
*/
let template: APITemplateType = {};
nodes.forEach((node) => {
let nodeTemplate = _.cloneDeep(node.data.node!.template);
let nodeTemplate = cloneDeep(node.data.node!.template);
Object.keys(nodeTemplate)
.filter((field_name) => field_name.charAt(0) !== "_")
.forEach((key) => {
@ -844,9 +847,9 @@ export function generateNodeFromFlow(
getNodeId: (type: string) => string
): NodeType {
const { nodes } = flow.data!;
const outputNode = _.cloneDeep(findLastNode(flow.data!));
const outputNode = cloneDeep(findLastNode(flow.data!));
const position = getMiddlePoint(nodes);
let data = _.cloneDeep(flow);
let data = cloneDeep(flow);
const id = getNodeId(outputNode?.data.type!);
const newGroupNode: NodeType = {
data: {
@ -907,94 +910,6 @@ export function connectedInputNodesOnHandle(
return connectedNodes;
}
export function ungroupNode(
groupNode: NodeDataType,
BaseFlow: ReactFlowJsonObject
) {
const { template, flow } = groupNode.node!;
const gNodes: NodeType[] = flow!.data!.nodes;
const gEdges = flow!.data!.edges;
//redirect edges to correct proxy node
let updatedEdges: Edge[] = [];
BaseFlow.edges.forEach((edge) => {
let newEdge = _.cloneDeep(edge);
if (newEdge.target === groupNode.id) {
const targetHandle: targetHandleType = newEdge.data.targetHandle;
if (targetHandle.proxy) {
let type = targetHandle.type;
let field = targetHandle.proxy.field;
let proxyId = targetHandle.proxy.id;
let inputTypes = targetHandle.inputTypes;
let node: NodeType = gNodes.find((n) => n.id === proxyId)!;
if (node) {
newEdge.target = proxyId;
let newTargetHandle: targetHandleType = {
fieldName: field,
type,
id: proxyId,
inputTypes: inputTypes,
};
if (node.data.node?.flow) {
newTargetHandle.proxy = {
field: node.data.node.template[field].proxy?.field!,
id: node.data.node.template[field].proxy?.id!,
};
}
newEdge.data.targetHandle = newTargetHandle;
newEdge.targetHandle = scapedJSONStringfy(newTargetHandle);
}
}
}
if (newEdge.source === groupNode.id) {
const lastNode = _.cloneDeep(findLastNode(flow!.data!));
newEdge.source = lastNode!.id;
let newSourceHandle: sourceHandleType = scapeJSONParse(
newEdge.sourceHandle!
);
newSourceHandle.id = lastNode!.id;
newEdge.data.sourceHandle = newSourceHandle;
newEdge.sourceHandle = scapedJSONStringfy(newSourceHandle);
}
if (edge.target === groupNode.id || edge.source === groupNode.id) {
updatedEdges.push(newEdge);
}
});
//update template values
Object.keys(template).forEach((key) => {
let { field, id } = template[key].proxy!;
let nodeIndex = gNodes.findIndex((n) => n.id === id);
if (nodeIndex !== -1) {
let display_name: string | undefined;
let show = gNodes[nodeIndex].data.node!.template[field].show;
let advanced = gNodes[nodeIndex].data.node!.template[field].advanced;
if (gNodes[nodeIndex].data.node!.template[field].display_name) {
display_name =
gNodes[nodeIndex].data.node!.template[field].display_name;
} else {
display_name = gNodes[nodeIndex].data.node!.template[field].name;
}
gNodes[nodeIndex].data.node!.template[field] = template[key];
gNodes[nodeIndex].data.node!.template[field].show = show;
gNodes[nodeIndex].data.node!.template[field].advanced = advanced;
gNodes[nodeIndex].data.node!.template[field].display_name = display_name;
}
});
const nodes = [
...BaseFlow.nodes.filter((n) => n.id !== groupNode.id),
...gNodes,
];
const edges = [
...BaseFlow.edges.filter(
(e) => e.target !== groupNode.id && e.source !== groupNode.id
),
...gEdges,
...updatedEdges,
];
BaseFlow.nodes = nodes;
BaseFlow.edges = edges;
}
function updateProxyIdsOnTemplate(
template: APITemplateType,
idsMap: { [key: string]: string }
@ -1031,24 +946,25 @@ export function processFlowEdges(flow: FlowType) {
}
export function expandGroupNode(
groupNode: NodeDataType,
id: string,
flow: FlowType,
template: APITemplateType,
nodes: Node[],
edges: Edge[],
setNodes: (update: Node[] | ((oldState: Node[]) => Node[])) => void,
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void
setEdges: (update: Edge[] | ((oldState: Edge[]) => Edge[])) => void,
) {
const { template, flow } = _.cloneDeep(groupNode.node!);
const idsMap = updateIds(flow!.data!);
updateProxyIdsOnTemplate(template, idsMap);
let flowEdges = edges;
updateEdgesIds(flowEdges, idsMap);
const gNodes: NodeType[] = flow?.data?.nodes!;
const gEdges = flow!.data!.edges;
const gNodes: NodeType[] = cloneDeep(flow?.data?.nodes!);
const gEdges = cloneDeep(flow!.data!.edges);
//redirect edges to correct proxy node
let updatedEdges: Edge[] = [];
flowEdges.forEach((edge) => {
let newEdge = _.cloneDeep(edge);
if (newEdge.target === groupNode.id) {
let newEdge = cloneDeep(edge);
if (newEdge.target === id) {
const targetHandle: targetHandleType = newEdge.data.targetHandle;
if (targetHandle.proxy) {
let type = targetHandle.type;
@ -1075,8 +991,8 @@ export function expandGroupNode(
}
}
}
if (newEdge.source === groupNode.id) {
const lastNode = _.cloneDeep(findLastNode(flow!.data!));
if (newEdge.source === id) {
const lastNode = cloneDeep(findLastNode(flow!.data!));
newEdge.source = lastNode!.id;
let newSourceHandle: sourceHandleType = scapeJSONParse(
newEdge.sourceHandle!
@ -1085,7 +1001,7 @@ export function expandGroupNode(
newEdge.data.sourceHandle = newSourceHandle;
newEdge.sourceHandle = scapedJSONStringfy(newSourceHandle);
}
if (edge.target === groupNode.id || edge.source === groupNode.id) {
if (edge.target === id || edge.source === id) {
updatedEdges.push(newEdge);
}
});
@ -1122,12 +1038,12 @@ export function expandGroupNode(
});
const filteredNodes = [
...nodes.filter((n) => n.id !== groupNode.id),
...nodes.filter((n) => n.id !== id),
...gNodes,
];
const filteredEdges = [
...edges.filter(
(e) => e.target !== groupNode.id && e.source !== groupNode.id
(e) => e.target !== id && e.source !== id
),
...gEdges,
...updatedEdges,
@ -1136,17 +1052,6 @@ export function expandGroupNode(
setEdges(filteredEdges);
}
export function processFlow(FlowObject: ReactFlowJsonObject) {
let clonedFLow = _.cloneDeep(FlowObject);
clonedFLow.nodes.forEach((node: NodeType) => {
if (node.data.node?.flow) {
processFlow(node.data.node!.flow!.data!);
ungroupNode(node.data, clonedFLow);
}
});
return clonedFLow;
}
export function getGroupStatus(
flow: FlowType,
ssData: { [key: string]: { valid: boolean; params: string } }
@ -1170,13 +1075,12 @@ export function createFlowComponent(
nodeData: NodeDataType,
version: string
): FlowType {
nodeData.node!.official = false;
const flowNode: FlowType = {
data: {
edges: [],
nodes: [
{
data: nodeData,
data: {...nodeData, node: {...nodeData.node, official: false}},
id: nodeData.id,
position: { x: 0, y: 0 },
type: "genericNode",