Made vertices be retrieved when opening chat or when changing anything. Added chat input in request.

This commit is contained in:
Lucas Oliveira 2024-02-28 17:20:57 +01:00
commit 04bbf4eaf0
12 changed files with 203 additions and 131 deletions

View file

@ -465,7 +465,7 @@ export default function GenericNode({
if (buildStatus === BuildStatus.BUILDING || isBuilding) if (buildStatus === BuildStatus.BUILDING || isBuilding)
return; return;
setValidationStatus(null); setValidationStatus(null);
buildFlow(data.id); buildFlow({nodeId: data.id});
}} }}
> >
<div> <div>

View file

@ -19,12 +19,12 @@ export default function IOInputField({
<Textarea <Textarea
className="w-full" className="w-full"
placeholder={"Enter text..."} placeholder={"Enter text..."}
value={node.data.node!.template["value"].value} value={node.data.node!.template["input_value"].value}
onChange={(e) => { onChange={(e) => {
e.target.value; e.target.value;
if (node) { if (node) {
let newNode = cloneDeep(node); let newNode = cloneDeep(node);
newNode.data.node!.template["value"].value = e.target.value; newNode.data.node!.template["input_value"].value = e.target.value;
setNode(node.id, newNode); setNode(node.id, newNode);
} }
}} }}
@ -49,12 +49,12 @@ export default function IOInputField({
<Textarea <Textarea
className="w-full custom-scroll" className="w-full custom-scroll"
placeholder={"Enter text..."} placeholder={"Enter text..."}
value={node.data.node!.template["value"]} value={node.data.node!.template["input_value"]}
onChange={(e) => { onChange={(e) => {
e.target.value; e.target.value;
if (node) { if (node) {
let newNode = cloneDeep(node); let newNode = cloneDeep(node);
newNode.data.node!.template["value"].value = e.target.value; newNode.data.node!.template["input_value"].value = e.target.value;
setNode(node.id, newNode); setNode(node.id, newNode);
} }
}} }}

View file

@ -30,12 +30,12 @@ export default function IOOutputView({
<Textarea <Textarea
className="w-full custom-scroll" className="w-full custom-scroll"
placeholder={"Enter text..."} placeholder={"Enter text..."}
value={node.data.node!.template["value"]} value={node.data.node!.template["input_value"]}
onChange={(e) => { onChange={(e) => {
e.target.value; e.target.value;
if (node) { if (node) {
let newNode = cloneDeep(node); let newNode = cloneDeep(node);
newNode.data.node!.template["value"].value = e.target.value; newNode.data.node!.template["input_value"].value = e.target.value;
setNode(node.id, newNode); setNode(node.id, newNode);
} }
}} }}

View file

@ -1,9 +1,13 @@
import { cloneDeep } from "lodash";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { CHAT_FORM_DIALOG_SUBTITLE, outputsModalTitle, textInputModalTitle } from "../../constants/constants"; import {
CHAT_FORM_DIALOG_SUBTITLE,
outputsModalTitle,
textInputModalTitle,
} from "../../constants/constants";
import BaseModal from "../../modals/baseModal"; import BaseModal from "../../modals/baseModal";
import useAlertStore from "../../stores/alertStore";
import useFlowStore from "../../stores/flowStore"; import useFlowStore from "../../stores/flowStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { updateVerticesOrder } from "../../utils/buildUtils";
import { cn } from "../../utils/utils"; import { cn } from "../../utils/utils";
import AccordionComponent from "../AccordionComponent"; import AccordionComponent from "../AccordionComponent";
import IOInputField from "../IOInputField"; import IOInputField from "../IOInputField";
@ -40,27 +44,47 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
{ type: string; id: string } | undefined { type: string; id: string } | undefined
>(undefined); >(undefined);
const { getNode, setNode, buildFlow, getFlow } = useFlowStore(); const buildFlow = useFlowStore((state) => state.buildFlow);
const { setErrorData } = useAlertStore();
const setIsBuilding = useFlowStore((state) => state.setIsBuilding); const setIsBuilding = useFlowStore((state) => state.setIsBuilding);
const [lockChat, setLockChat] = useState(false); const [lockChat, setLockChat] = useState(false);
const [chatValue, setChatValue] = useState(""); const [chatValue, setChatValue] = useState("");
const isBuilding = useFlowStore((state) => state.isBuilding); const isBuilding = useFlowStore((state) => state.isBuilding);
const currentFlow = useFlowsManagerStore((state) => state.currentFlow);
const verticesBuild = useFlowStore((state) => state.verticesBuild);
const updateVerticesBuild = useFlowStore(
(state) => state.updateVerticesBuild
);
async function updateVertices() {
return new Promise<void>((resolve, reject) => {
if (!verticesBuild) {
updateVerticesOrder(currentFlow!.id, null).then((orderResponse) => {
resolve();
});
}
resolve();
});
}
useEffect(() => {
updateVertices();
}, [currentFlow]);
useEffect(() => {
if (open) {
updateVerticesBuild(null);
updateVertices();
}
}, [open]);
async function sendMessage(count = 1): Promise<void> { async function sendMessage(count = 1): Promise<void> {
if (isBuilding) return; if (isBuilding) return;
const { nodes, edges } = getFlow(); await updateVertices();
setIsBuilding(true); setIsBuilding(true);
setLockChat(true); setLockChat(true);
setChatValue(""); setChatValue("");
const chatInputNode = nodes.find((node) => node.id === chatInput?.id);
if (chatInputNode) {
let newNode = cloneDeep(chatInputNode);
newNode.data.node!.template["input_value"].value = chatValue;
setNode(chatInput!.id, newNode);
}
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
await buildFlow().catch((err) => { await buildFlow({ input_value: chatValue }).catch((err) => {
console.error(err); console.error(err);
setLockChat(false); setLockChat(false);
}); });
@ -104,7 +128,7 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
<Tabs <Tabs
value={selectedTab.toString()} value={selectedTab.toString()}
className={ className={
"flex h-full flex-col overflow-y-auto custom-scroll rounded-md border bg-muted text-center" "flex h-full flex-col overflow-y-auto rounded-md border bg-muted text-center custom-scroll"
} }
onValueChange={(value) => { onValueChange={(value) => {
setSelectedTab(Number(value)); setSelectedTab(Number(value));
@ -283,7 +307,10 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
</div> </div>
)} )}
<div <div
className={cn("flex w-full h-full",selectedViewField ? "hidden" : "")} className={cn(
"flex h-full w-full",
selectedViewField ? "hidden" : ""
)}
> >
<NewChatView <NewChatView
sendMessage={sendMessage} sendMessage={sendMessage}

View file

@ -23,8 +23,6 @@ export default function BuildTrigger({
const nodes = useFlowStore((state) => state.nodes); const nodes = useFlowStore((state) => state.nodes);
const edges = useFlowStore((state) => state.edges); const edges = useFlowStore((state) => state.edges);
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setFlowState = useFlowStore((state) => state.setFlowState);
const eventClick = isBuilding ? "pointer-events-none" : ""; const eventClick = isBuilding ? "pointer-events-none" : "";
const [progress, setProgress] = useState(0); const [progress, setProgress] = useState(0);
@ -47,7 +45,7 @@ export default function BuildTrigger({
setIsBuilding(true); setIsBuilding(true);
await enforceMinimumLoadingTime(startTime, minimumLoadingTime); await enforceMinimumLoadingTime(startTime, minimumLoadingTime);
await buildFlow(); await buildFlow({});
} catch (error) { } catch (error) {
console.error("Error:", error); console.error("Error:", error);
} finally { } finally {

View file

@ -4,6 +4,7 @@ import { Textarea } from "../../../components/ui/textarea";
import { chatInputType } from "../../../types/components"; import { chatInputType } from "../../../types/components";
import { classNames } from "../../../utils/utils"; import { classNames } from "../../../utils/utils";
import { chatInputPlaceholder, chatInputPlaceholderSend } from "../../../constants/constants"; import { chatInputPlaceholder, chatInputPlaceholderSend } from "../../../constants/constants";
import useFlowsManagerStore from "../../../stores/flowsManagerStore";
export default function ChatInput({ export default function ChatInput({
lockChat, lockChat,
@ -14,20 +15,21 @@ export default function ChatInput({
noInput, noInput,
}: chatInputType): JSX.Element { }: chatInputType): JSX.Element {
const [repeat, setRepeat] = useState(1); const [repeat, setRepeat] = useState(1);
const saveLoading = useFlowsManagerStore((state) => state.saveLoading);
useEffect(() => { useEffect(() => {
if (!lockChat && inputRef.current) { if (!lockChat && inputRef.current) {
inputRef.current.focus(); inputRef.current.focus();
} }
}, [lockChat, inputRef]); }, [lockChat, inputRef]);
function handleChange(value: number) { /* function handleChange(value: number) {
console.log(value); console.log(value);
if (value > 0) { if (value > 0) {
setRepeat(value); setRepeat(value);
} else { } else {
setRepeat(1); setRepeat(1);
} }
} } */
useEffect(() => { useEffect(() => {
if (inputRef.current) { if (inputRef.current) {
@ -41,13 +43,13 @@ export default function ChatInput({
<div className="relative w-full"> <div className="relative w-full">
<Textarea <Textarea
onKeyDown={(event) => { onKeyDown={(event) => {
if (event.key === "Enter" && !lockChat && !event.shiftKey) { if (event.key === "Enter" && !lockChat && !saveLoading && !event.shiftKey) {
sendMessage(repeat); sendMessage(repeat);
} }
}} }}
rows={1} rows={1}
ref={inputRef} ref={inputRef}
disabled={lockChat || noInput} disabled={lockChat || noInput || saveLoading}
style={{ style={{
resize: "none", resize: "none",
bottom: `${inputRef?.current?.scrollHeight}px`, bottom: `${inputRef?.current?.scrollHeight}px`,
@ -58,12 +60,12 @@ export default function ChatInput({
: "hidden" : "hidden"
}`, }`,
}} }}
value={lockChat ? "Thinking..." : chatValue} value={lockChat ? "Thinking..." : (saveLoading ? "Saving..." : chatValue)}
onChange={(event): void => { onChange={(event): void => {
setChatValue(event.target.value); setChatValue(event.target.value);
}} }}
className={classNames( className={classNames(
lockChat (lockChat || saveLoading)
? " form-modal-lock-true bg-input" ? " form-modal-lock-true bg-input"
: noInput : noInput
? "form-modal-no-input bg-input" ? "form-modal-no-input bg-input"
@ -87,10 +89,10 @@ export default function ChatInput({
? "text-primary" ? "text-primary"
: "bg-chat-send text-background" : "bg-chat-send text-background"
)} )}
disabled={lockChat} disabled={lockChat || saveLoading}
onClick={(): void => sendMessage(repeat)} onClick={(): void => sendMessage(repeat)}
> >
{lockChat ? ( {lockChat || saveLoading ? (
<IconComponent <IconComponent
name="Lock" name="Lock"
className="form-modal-lock-icon" className="form-modal-lock-icon"

View file

@ -123,7 +123,7 @@ function ApiInterceptor() {
async function clearBuildVerticesState(error) { async function clearBuildVerticesState(error) {
if (error?.response?.status === 500) { if (error?.response?.status === 500) {
const vertices = useFlowStore.getState().verticesBuild; const vertices = useFlowStore.getState().verticesBuild;
useFlowStore.getState().updateBuildStatus(vertices, BuildStatus.BUILT); useFlowStore.getState().updateBuildStatus(vertices?.verticesIds ?? [], BuildStatus.BUILT);
useFlowStore.getState().setIsBuilding(false); useFlowStore.getState().setIsBuilding(false);
} }
} }

View file

@ -869,9 +869,10 @@ export async function getVerticesOrder(
export async function postBuildVertex( export async function postBuildVertex(
flowId: string, flowId: string,
vertexId: string vertexId: string,
input_value: string,
): Promise<AxiosResponse<VertexBuildTypeAPI>> { ): Promise<AxiosResponse<VertexBuildTypeAPI>> {
return await api.post(`${BASE_URL_API}build/${flowId}/vertices/${vertexId}`); return await api.post(`${BASE_URL_API}build/${flowId}/vertices/${vertexId}`, {inputs: {input_value: input_value}});
} }
export async function downloadImage({ flowId, fileName }): Promise<any> { export async function downloadImage({ flowId, fileName }): Promise<any> {

View file

@ -9,9 +9,12 @@ import {
applyNodeChanges, applyNodeChanges,
} from "reactflow"; } from "reactflow";
import { create } from "zustand"; import { create } from "zustand";
import { FLOW_BUILD_SUCCESS_ALERT, MISSED_ERROR_ALERT } from "../constants/alerts_constants"; import {
FLOW_BUILD_SUCCESS_ALERT,
MISSED_ERROR_ALERT,
} from "../constants/alerts_constants";
import { BuildStatus } from "../constants/enums"; import { BuildStatus } from "../constants/enums";
import { getFlowPool, updateFlowInDatabase } from "../controllers/API"; import { getFlowPool } from "../controllers/API";
import { VertexBuildTypeAPI } from "../types/api"; import { VertexBuildTypeAPI } from "../types/api";
import { import {
NodeDataType, NodeDataType,
@ -19,7 +22,12 @@ import {
sourceHandleType, sourceHandleType,
targetHandleType, targetHandleType,
} from "../types/flow"; } from "../types/flow";
import { ChatOutputType, FlowPoolObjectType, FlowStoreType, chatInputType } from "../types/zustand/flow"; import {
ChatOutputType,
FlowPoolObjectType,
FlowStoreType,
chatInputType,
} from "../types/zustand/flow";
import { buildVertices } from "../utils/buildUtils"; import { buildVertices } from "../utils/buildUtils";
import { import {
cleanEdges, cleanEdges,
@ -59,23 +67,25 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
} }
get().setFlowPool(newFlowPool); get().setFlowPool(newFlowPool);
}, },
updateFlowPool:(nodeId:string,data:FlowPoolObjectType| ChatOutputType | chatInputType,buildId?:string)=>{ updateFlowPool: (
nodeId: string,
data: FlowPoolObjectType | ChatOutputType | chatInputType,
buildId?: string
) => {
let newFlowPool = cloneDeep({ ...get().flowPool }); let newFlowPool = cloneDeep({ ...get().flowPool });
if (!newFlowPool[nodeId]){ if (!newFlowPool[nodeId]) {
return; return;
} } else {
else { let index = newFlowPool[nodeId].length - 1;
let index = newFlowPool[nodeId].length-1; if (buildId) {
if(buildId){ index = newFlowPool[nodeId].findIndex((flow) => flow.id === buildId);
index = newFlowPool[nodeId].findIndex((flow)=>flow.id===buildId);
} }
//check if the data is a flowpool object //check if the data is a flowpool object
if((data as FlowPoolObjectType).data?.artifacts!==undefined){ if ((data as FlowPoolObjectType).data?.artifacts !== undefined) {
newFlowPool[nodeId][index] = (data as FlowPoolObjectType); newFlowPool[nodeId][index] = data as FlowPoolObjectType;
} }
//update data artifact //update data artifact
else else {
{
newFlowPool[nodeId][index].data.artifacts = data; newFlowPool[nodeId][index].data.artifacts = data;
} }
} }
@ -394,7 +404,13 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
}); });
}); });
}, },
buildFlow: async (nodeId?: string) => { buildFlow: async ({
nodeId,
input_value,
}: {
nodeId?: string;
input_value?: string;
}) => {
get().setIsBuilding(true); get().setIsBuilding(true);
const currentFlow = useFlowsManagerStore.getState().currentFlow; const currentFlow = useFlowsManagerStore.getState().currentFlow;
const setSuccessData = useAlertStore.getState().setSuccessData; const setSuccessData = useAlertStore.getState().setSuccessData;
@ -417,25 +433,19 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
function handleBuildUpdate( function handleBuildUpdate(
vertexBuildData: VertexBuildTypeAPI, vertexBuildData: VertexBuildTypeAPI,
status: BuildStatus, status: BuildStatus,
buildId:string buildId: string
) { ) {
if (vertexBuildData && vertexBuildData.inactive_vertices) { if (vertexBuildData && vertexBuildData.inactive_vertices) {
get().removeFromVerticesBuild(vertexBuildData.inactive_vertices); get().removeFromVerticesBuild(vertexBuildData.inactive_vertices);
} }
get().addDataToFlowPool({...vertexBuildData,buildId}, vertexBuildData.id); get().addDataToFlowPool(
{ ...vertexBuildData, buildId },
vertexBuildData.id
);
useFlowStore.getState().updateBuildStatus([vertexBuildData.id], status); useFlowStore.getState().updateBuildStatus([vertexBuildData.id], status);
} }
await updateFlowInDatabase({
data: {
nodes: get().nodes,
edges: get().edges,
viewport: get().reactFlowInstance?.getViewport()!,
},
id: currentFlow!.id,
name: currentFlow!.name,
description: currentFlow!.description,
});
await buildVertices({ await buildVertices({
input_value,
flowId: currentFlow!.id, flowId: currentFlow!.id,
nodeId, nodeId,
onGetOrderSuccess: () => { onGetOrderSuccess: () => {
@ -473,16 +483,22 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
viewport: get().reactFlowInstance?.getViewport()!, viewport: get().reactFlowInstance?.getViewport()!,
}; };
}, },
updateVerticesBuild: (vertices: string[]) => { updateVerticesBuild: (
vertices: { verticesIds: string[], verticesOrder: string[][], verticesLayers: string[][], runId: string } | null
) => {
set({ verticesBuild: vertices }); set({ verticesBuild: vertices });
}, },
verticesBuild: [], verticesBuild: null,
removeFromVerticesBuild: (vertices: string[]) => { removeFromVerticesBuild: (vertices: string[]) => {
const verticesBuild = get().verticesBuild;
if (!verticesBuild) return;
set({ set({
verticesBuild: get().verticesBuild.filter( verticesBuild: {
...verticesBuild,
verticesIds: get().verticesBuild!.verticesIds.filter(
(vertex) => !vertices.includes(vertex) (vertex) => !vertices.includes(vertex)
), ),
},
}); });
}, },
updateBuildStatus: (nodeIdList: string[], status: BuildStatus) => { updateBuildStatus: (nodeIdList: string[], status: BuildStatus) => {

View file

@ -83,6 +83,7 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
if (saveTimeoutId) { if (saveTimeoutId) {
clearTimeout(saveTimeoutId); clearTimeout(saveTimeoutId);
} }
set({ saveLoading: true });
// Set up a new timeout. // Set up a new timeout.
saveTimeoutId = setTimeout(() => { saveTimeoutId = setTimeout(() => {
if (get().currentFlow) { if (get().currentFlow) {
@ -92,7 +93,7 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
); );
} }
set({ saveLoading: true }); set({ saveLoading: true });
}, 1000); // Delay of 1000ms. }, 500); // Delay of 500ms because chat message depends on it.
}, },
saveFlow: (flow: FlowType, silent?: boolean) => { saveFlow: (flow: FlowType, silent?: boolean) => {
set({ saveLoading: true }); set({ saveLoading: true });

View file

@ -86,11 +86,11 @@ export type FlowStoreType = {
getFilterEdge: any[]; getFilterEdge: any[];
onConnect: (connection: Connection) => void; onConnect: (connection: Connection) => void;
unselectAll: () => void; unselectAll: () => void;
buildFlow: (nodeId?: string) => Promise<void>; buildFlow: ({nodeId, input_value}: {nodeId?: string, input_value?: string}) => Promise<void>;
getFlow: () => { nodes: Node[]; edges: Edge[]; viewport: Viewport }; getFlow: () => { nodes: Node[]; edges: Edge[]; viewport: Viewport };
updateVerticesBuild: (vertices: string[]) => void; updateVerticesBuild: (vertices: {verticesIds: string[], verticesLayers: string[][], verticesOrder: string[][], runId: string} | null) => void;
removeFromVerticesBuild: (vertices: string[]) => void; removeFromVerticesBuild: (vertices: string[]) => void;
verticesBuild: string[]; verticesBuild: {verticesIds: string[], verticesLayers: string[][], verticesOrder: string[][], runId: string} | null;
updateBuildStatus: (nodeId: string[], status: BuildStatus) => void; updateBuildStatus: (nodeId: string[], status: BuildStatus) => void;
revertBuiltStatusFromBuilding: () => void; revertBuiltStatusFromBuilding: () => void;
flowBuildStatus: { [key: string]: BuildStatus }; flowBuildStatus: { [key: string]: BuildStatus };

View file

@ -7,9 +7,14 @@ import { VertexBuildTypeAPI } from "../types/api";
type BuildVerticesParams = { type BuildVerticesParams = {
flowId: string; // Assuming FlowType is the type for your flow flowId: string; // Assuming FlowType is the type for your flow
input_value?: any; // Replace any with the actual type if it's not any
nodeId?: string | null; // Assuming nodeId is of type string, and it's optional nodeId?: string | null; // Assuming nodeId is of type string, and it's optional
onGetOrderSuccess?: () => void; onGetOrderSuccess?: () => void;
onBuildUpdate?: (data: VertexBuildTypeAPI, status: BuildStatus,buildId:string) => void; // Replace any with the actual type if it's not any onBuildUpdate?: (
data: VertexBuildTypeAPI,
status: BuildStatus,
buildId: string
) => void; // Replace any with the actual type if it's not any
onBuildComplete?: (allNodesValid: boolean) => void; onBuildComplete?: (allNodesValid: boolean) => void;
onBuildError?: (title, list, idList: string[]) => void; onBuildError?: (title, list, idList: string[]) => void;
onBuildStart?: (idList: string[]) => void; onBuildStart?: (idList: string[]) => void;
@ -34,21 +39,13 @@ function getInactiveVertexData(vertexId: string): VertexBuildTypeAPI {
return inactiveVertexData; return inactiveVertexData;
} }
export async function buildVertices({ export async function updateVerticesOrder(flowId: string, nodeId: string | null) {
flowId, return new Promise(async (resolve, reject) => {
nodeId = null,
onGetOrderSuccess,
onBuildUpdate,
onBuildComplete,
onBuildError,
onBuildStart,
validateNodes,
}: BuildVerticesParams) {
const setErrorData = useAlertStore.getState().setErrorData; const setErrorData = useAlertStore.getState().setErrorData;
let orderResponse; let orderResponse;
try { try {
orderResponse = await getVerticesOrder(flowId, nodeId); orderResponse = await getVerticesOrder(flowId, nodeId);
} catch (error:any) { } catch (error: any) {
console.log(error); console.log(error);
setErrorData({ setErrorData({
title: "Oops! Looks like you missed something", title: "Oops! Looks like you missed something",
@ -57,18 +54,10 @@ export async function buildVertices({
useFlowStore.getState().setIsBuilding(false); useFlowStore.getState().setIsBuilding(false);
throw new Error("Invalid nodes"); throw new Error("Invalid nodes");
} }
if (onGetOrderSuccess) onGetOrderSuccess();
let verticesOrder: Array<Array<string>> = orderResponse.data.ids; let verticesOrder: Array<Array<string>> = orderResponse.data.ids;
const runId = orderResponse.data.run_id; const runId = orderResponse.data.run_id;
let vertices_layers: Array<Array<string>> = []; let verticesLayers: Array<Array<string>> = [];
let stop = false;
if (validateNodes) {
try {
validateNodes(verticesOrder.flatMap((id) => id));
} catch (e) {
return;
}
}
if (nodeId) { if (nodeId) {
for (let i = 0; i < verticesOrder.length; i += 1) { for (let i = 0; i < verticesOrder.length; i += 1) {
const innerArray = verticesOrder[i]; const innerArray = verticesOrder[i];
@ -77,40 +66,76 @@ export async function buildVertices({
// If there's a nodeId, we want to run just that component and not the entire layer // If there's a nodeId, we want to run just that component and not the entire layer
// because a layer contains dependencies for the next layer // because a layer contains dependencies for the next layer
// and we are stopping at the layer that contains the nodeId // and we are stopping at the layer that contains the nodeId
vertices_layers.push([innerArray[idIndex]]); verticesLayers.push([innerArray[idIndex]]);
break; // Stop searching after finding the first occurrence break; // Stop searching after finding the first occurrence
} }
// If the targetId is not found, include the entire inner array // If the targetId is not found, include the entire inner array
vertices_layers.push(innerArray); verticesLayers.push(innerArray);
} }
} else { } else {
vertices_layers = verticesOrder; verticesLayers = verticesOrder;
}
const verticesIds = verticesLayers.flat();
useFlowStore
.getState()
.updateVerticesBuild({ verticesLayers, verticesIds, verticesOrder, runId });
});
}
export async function buildVertices({
flowId,
input_value,
nodeId = null,
onGetOrderSuccess,
onBuildUpdate,
onBuildComplete,
onBuildError,
onBuildStart,
validateNodes,
}: BuildVerticesParams) {
const verticesBuild = useFlowStore.getState().verticesBuild;
if (!verticesBuild) {
await updateVerticesOrder(flowId, nodeId);
}
const verticesIds = verticesBuild?.verticesIds!;
const verticesLayers = verticesBuild?.verticesLayers!;
const verticesOrder = verticesBuild?.verticesOrder!;
const runId = verticesBuild?.runId!;
let stop = false;
if (onGetOrderSuccess) onGetOrderSuccess();
if (validateNodes) {
try {
validateNodes(verticesOrder.flatMap((id) => id));
} catch (e) {
return;
}
} }
const verticesIds = vertices_layers.flat();
useFlowStore.getState().updateBuildStatus(verticesIds, BuildStatus.TO_BUILD); useFlowStore.getState().updateBuildStatus(verticesIds, BuildStatus.TO_BUILD);
useFlowStore.getState().updateVerticesBuild(verticesIds);
useFlowStore.getState().setIsBuilding(true); useFlowStore.getState().setIsBuilding(true);
// Set each vertex state to building // Set each vertex state to building
const buildResults: Array<boolean> = []; const buildResults: Array<boolean> = [];
for (const layer of vertices_layers) { for (const layer of verticesLayers) {
if (onBuildStart) onBuildStart(layer); if (onBuildStart) onBuildStart(layer);
for (const id of layer) { for (const id of layer) {
// Check if id is in the list of inactive nodes // Check if id is in the list of inactive nodes
if ( if (!verticesIds.includes(id) && onBuildUpdate) {
!useFlowStore.getState().verticesBuild.includes(id) &&
onBuildUpdate
) {
// If it is, skip building and set the state to inactive // If it is, skip building and set the state to inactive
onBuildUpdate(getInactiveVertexData(id), BuildStatus.INACTIVE,runId); onBuildUpdate(getInactiveVertexData(id), BuildStatus.INACTIVE, runId);
buildResults.push(false); buildResults.push(false);
continue; continue;
} }
await buildVertex({ await buildVertex({
flowId, flowId,
id, id,
onBuildUpdate:(data: VertexBuildTypeAPI, status: BuildStatus) => {if(onBuildUpdate) onBuildUpdate(data, status,runId)}, input_value,
onBuildUpdate: (data: VertexBuildTypeAPI, status: BuildStatus) => {
if (onBuildUpdate) onBuildUpdate(data, status, runId);
},
onBuildError, onBuildError,
verticesIds, verticesIds,
buildResults, buildResults,
@ -137,6 +162,7 @@ export async function buildVertices({
async function buildVertex({ async function buildVertex({
flowId, flowId,
id, id,
input_value,
onBuildUpdate, onBuildUpdate,
onBuildError, onBuildError,
verticesIds, verticesIds,
@ -145,6 +171,7 @@ async function buildVertex({
}: { }: {
flowId: string; flowId: string;
id: string; id: string;
input_value: string;
onBuildUpdate?: (data: any, status: BuildStatus) => void; onBuildUpdate?: (data: any, status: BuildStatus) => void;
onBuildError?: (title, list, idList: string[]) => void; onBuildError?: (title, list, idList: string[]) => void;
verticesIds: string[]; verticesIds: string[];
@ -152,7 +179,7 @@ async function buildVertex({
stopBuild: () => void; stopBuild: () => void;
}) { }) {
try { try {
const buildRes = await postBuildVertex(flowId, id); const buildRes = await postBuildVertex(flowId, id, input_value);
const buildData: VertexBuildTypeAPI = buildRes.data; const buildData: VertexBuildTypeAPI = buildRes.data;
if (onBuildUpdate) { if (onBuildUpdate) {
if (!buildData.valid) { if (!buildData.valid) {