Removed SSE Store and fixed node building not appearing at node

This commit is contained in:
Lucas Oliveira 2024-01-08 15:31:18 -03:00
commit 221776c2d4
14 changed files with 138 additions and 161 deletions

View file

@ -16,7 +16,6 @@ import { classNames, cn, getFieldTitle } from "../../utils/utils";
import ParameterComponent from "./components/parameterComponent"; import ParameterComponent from "./components/parameterComponent";
import { useTypesStore } from "../../stores/typesStore"; import { useTypesStore } from "../../stores/typesStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { useSSEStore } from "../../stores/sseStore";
export default function GenericNode({ export default function GenericNode({
data, data,
@ -80,8 +79,8 @@ export default function GenericNode({
}, [data, data.node]); }, [data, data.node]);
// State for outline color // State for outline color
const sseData = useSSEStore((state) => state.sseData); const sseData = useFlowStore((state) => state.sseData);
const isBuilding = useSSEStore((state) => state.isBuilding); const isBuilding = useFlowStore((state) => state.isBuilding);
useEffect(() => { useEffect(() => {
setNodeDescription(data.node!.description); setNodeDescription(data.node!.description);

View file

@ -1,18 +1,16 @@
import { Transition } from "@headlessui/react"; import { Transition } from "@headlessui/react";
import { useContext, useState } from "react"; import { useState } from "react";
import Loading from "../../../components/ui/loading"; import Loading from "../../../components/ui/loading";
import { postBuildInit } from "../../../controllers/API"; import { postBuildInit } from "../../../controllers/API";
import { FlowType } from "../../../types/flow"; import { FlowType } from "../../../types/flow";
import useAlertStore from "../../../stores/alertStore"; import useAlertStore from "../../../stores/alertStore";
import useFlowStore from "../../../stores/flowStore"; import useFlowStore from "../../../stores/flowStore";
import useFlowsManagerStore from "../../../stores/flowsManagerStore";
import { parsedDataType } from "../../../types/components"; import { parsedDataType } from "../../../types/components";
import { FlowState } from "../../../types/tabs";
import { validateNodes } from "../../../utils/reactflowUtils"; import { validateNodes } from "../../../utils/reactflowUtils";
import RadialProgressComponent from "../../RadialProgress"; import RadialProgressComponent from "../../RadialProgress";
import IconComponent from "../../genericIconComponent"; import IconComponent from "../../genericIconComponent";
import { useSSEStore } from "../../../stores/sseStore"; import { stat } from "fs";
export default function BuildTrigger({ export default function BuildTrigger({
open, open,
@ -24,20 +22,17 @@ export default function BuildTrigger({
setIsBuilt: any; setIsBuilt: any;
isBuilt: boolean; isBuilt: boolean;
}): JSX.Element { }): JSX.Element {
const updateSSEData = useSSEStore((state) => state.updateSSEData); const updateSSEData = useFlowStore((state) => state.updateSSEData);
const isBuilding = useSSEStore((state) => state.isBuilding); const isBuilding = useFlowStore((state) => state.isBuilding);
const setIsBuilding = useSSEStore((state) => state.setIsBuilding); const setIsBuilding = useFlowStore((state) => state.setIsBuilding);
const sseData = useSSEStore((state) => state.sseData);
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 setSuccessData = useAlertStore((state) => state.setSuccessData);
const setCurrentFlowState = useFlowsManagerStore( const setFlowState = useFlowStore(
(state) => state.setCurrentFlowState (state) => state.setFlowState
); );
const saveFlow = useFlowsManagerStore((state) => state.saveFlow);
const [isIconTouched, setIsIconTouched] = useState(false);
const eventClick = isBuilding ? "pointer-events-none" : ""; const eventClick = isBuilding ? "pointer-events-none" : "";
const [progress, setProgress] = useState(0); const [progress, setProgress] = useState(0);
@ -82,7 +77,6 @@ export default function BuildTrigger({
} }
async function streamNodeData(flow: FlowType) { async function streamNodeData(flow: FlowType) {
// Step 1: Make a POST request to send the flow data and receive a unique session ID // Step 1: Make a POST request to send the flow data and receive a unique session ID
const id = saveFlow(flow, true);
const response = await postBuildInit(flow); const response = await postBuildInit(flow);
const { flowId } = response.data; const { flowId } = response.data;
// Step 2: Use the session ID to establish an SSE connection using EventSource // Step 2: Use the session ID to establish an SSE connection using EventSource
@ -105,7 +99,7 @@ export default function BuildTrigger({
// If the event is a log, log it // If the event is a log, log it
setSuccessData({ title: parsedData.log }); setSuccessData({ title: parsedData.log });
} else if (parsedData.input_keys !== undefined) { } else if (parsedData.input_keys !== undefined) {
setCurrentFlowState(parsedData); setFlowState(parsedData);
} else { } else {
// Otherwise, process the data // Otherwise, process the data
const isValid = processStreamResult(parsedData); const isValid = processStreamResult(parsedData);
@ -151,14 +145,6 @@ export default function BuildTrigger({
} }
} }
const handleMouseEnter = () => {
setIsIconTouched(true);
};
const handleMouseLeave = () => {
setIsIconTouched(false);
};
return ( return (
<Transition <Transition
show={!open} show={!open}
@ -176,8 +162,6 @@ export default function BuildTrigger({
onClick={() => { onClick={() => {
handleBuild(flow); handleBuild(flow);
}} }}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
> >
<button> <button>
<div className="round-button-div"> <div className="round-button-div">

View file

@ -13,10 +13,9 @@ import useFlowsManagerStore from "../../stores/flowsManagerStore";
export default function Chat({ flow }: ChatType): JSX.Element { export default function Chat({ flow }: ChatType): JSX.Element {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [canOpen, setCanOpen] = useState(false);
const isBuilt = useFlowStore((state) => state.isBuilt); const isBuilt = useFlowStore((state) => state.isBuilt);
const setIsBuilt = useFlowStore((state) => state.setIsBuilt); const setIsBuilt = useFlowStore((state) => state.setIsBuilt);
const currentFlowState = useFlowsManagerStore((state) => state.currentFlowState); const flowState = useFlowStore((state) => state.flowState);
useEffect(() => { useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => { const handleKeyDown = (event: KeyboardEvent) => {
if ( if (
@ -57,17 +56,8 @@ export default function Chat({ flow }: ChatType): JSX.Element {
) { ) {
setIsBuilt(false); setIsBuilt(false);
} }
if (
currentFlowState &&
currentFlowState.input_keys !== null
) {
setCanOpen(true);
} else {
setCanOpen(false);
}
prevNodesRef.current = currentNodes; prevNodesRef.current = currentNodes;
}, [currentFlowState, flow.id]); }, [flowState, flow.id]);
return ( return (
<> <>
@ -79,8 +69,8 @@ export default function Chat({ flow }: ChatType): JSX.Element {
isBuilt={isBuilt} isBuilt={isBuilt}
/> />
{isBuilt && {isBuilt &&
currentFlowState && flowState &&
canOpen && ( !!flowState?.input_keys && (
<FormModal <FormModal
key={flow.id} key={flow.id}
flow={flow} flow={flow}
@ -89,7 +79,7 @@ export default function Chat({ flow }: ChatType): JSX.Element {
/> />
)} )}
<ChatTrigger <ChatTrigger
canOpen={canOpen} canOpen={!!flowState?.input_keys}
open={open} open={open}
setOpen={setOpen} setOpen={setOpen}
isBuilt={isBuilt} isBuilt={isBuilt}

View file

@ -31,6 +31,7 @@ import {
tabsArray, tabsArray,
} from "../../utils/utils"; } from "../../utils/utils";
import BaseModal from "../baseModal"; import BaseModal from "../baseModal";
import useFlowStore from "../../stores/flowStore";
const ApiModal = forwardRef( const ApiModal = forwardRef(
( (
@ -49,18 +50,18 @@ const ApiModal = forwardRef(
const tweak = useRef<tweakType>([]); const tweak = useRef<tweakType>([]);
const tweaksList = useRef<string[]>([]); const tweaksList = useRef<string[]>([]);
const [getTweak, setTweak] = useState<tweakType>([]); const [getTweak, setTweak] = useState<tweakType>([]);
const currentFlowState = useFlowsManagerStore( const flowState = useFlowStore(
(state) => state.currentFlowState (state) => state.flowState
); );
const pythonApiCode = getPythonApiCode( const pythonApiCode = getPythonApiCode(
flow, flow,
autoLogin, autoLogin,
tweak.current, tweak.current,
currentFlowState flowState
); );
const curl_code = getCurlCode(flow, autoLogin, tweak.current, currentFlowState); const curl_code = getCurlCode(flow, autoLogin, tweak.current, flowState);
const pythonCode = getPythonCode(flow, tweak.current, currentFlowState); const pythonCode = getPythonCode(flow, tweak.current, flowState);
const widgetCode = getWidgetCode(flow, autoLogin, currentFlowState); const widgetCode = getWidgetCode(flow, autoLogin, flowState);
const tweaksCode = buildTweaks(flow); const tweaksCode = buildTweaks(flow);
const codesArray = [ const codesArray = [
curl_code, curl_code,
@ -171,11 +172,11 @@ const ApiModal = forwardRef(
flow, flow,
autoLogin, autoLogin,
tweak.current, tweak.current,
currentFlowState flowState
); );
const curl_code = getCurlCode(flow, autoLogin, tweak.current, currentFlowState); const curl_code = getCurlCode(flow, autoLogin, tweak.current, flowState);
const pythonCode = getPythonCode(flow, tweak.current, currentFlowState); const pythonCode = getPythonCode(flow, tweak.current, flowState);
const widgetCode = getWidgetCode(flow, autoLogin, currentFlowState); const widgetCode = getWidgetCode(flow, autoLogin, flowState);
tabs![0].code = curl_code; tabs![0].code = curl_code;
tabs![1].code = pythonApiCode; tabs![1].code = pythonApiCode;

View file

@ -40,19 +40,19 @@ export default function FormModal({
}): JSX.Element { }): JSX.Element {
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 currentFlowState = useFlowsManagerStore( const flowState = useFlowStore(
(state) => state.currentFlowState (state) => state.flowState
); );
const setCurrentFlowState = useFlowsManagerStore( const setFlowState = useFlowStore(
(state) => state.setCurrentFlowState (state) => state.setFlowState
); );
const [chatValue, setChatValue] = useState(() => { const [chatValue, setChatValue] = useState(() => {
try { try {
if (!currentFlowState) { if (!flowState) {
throw new Error("currentFlowState is undefined"); throw new Error("flowState is undefined");
} }
const inputKeys = currentFlowState.input_keys; const inputKeys = flowState.input_keys;
const handleKeys = currentFlowState.handle_keys; const handleKeys = flowState.handle_keys;
const keyToUse = Object.keys(inputKeys!).find( const keyToUse = Object.keys(inputKeys!).find(
(key) => !handleKeys?.some((j) => j === key) && inputKeys![key] === "" (key) => !handleKeys?.some((j) => j === key) && inputKeys![key] === ""
@ -67,7 +67,7 @@ export default function FormModal({
}); });
const [chatHistory, setChatHistory] = useState<ChatMessageType[]>([]); const [chatHistory, setChatHistory] = useState<ChatMessageType[]>([]);
const template = useRef(currentFlowState?.template ?? undefined); const template = useRef(flowState?.template ?? undefined);
const { accessToken } = useContext(AuthContext); const { accessToken } = useContext(AuthContext);
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
const ws = useRef<WebSocket | null>(null); const ws = useRef<WebSocket | null>(null);
@ -76,11 +76,11 @@ export default function FormModal({
const messagesRef = useRef<HTMLDivElement | null>(null); const messagesRef = useRef<HTMLDivElement | null>(null);
const [chatKey, setChatKey] = useState(() => { const [chatKey, setChatKey] = useState(() => {
if (currentFlowState?.input_keys) { if (flowState?.input_keys) {
return Object.keys(currentFlowState.input_keys!).find( return Object.keys(flowState.input_keys!).find(
(key) => (key) =>
!currentFlowState.handle_keys!.some((j) => j === key) && !flowState.handle_keys!.some((j) => j === key) &&
currentFlowState.input_keys![key] === "" flowState.input_keys![key] === ""
); );
} }
// TODO: return a sensible default // TODO: return a sensible default
@ -386,7 +386,7 @@ export default function FormModal({
let nodeValidationErrors = validateNodes(nodes, edges); let nodeValidationErrors = validateNodes(nodes, edges);
if (nodeValidationErrors.length === 0) { if (nodeValidationErrors.length === 0) {
setLockChat(true); setLockChat(true);
let inputs = currentFlowState?.input_keys; let inputs = flowState?.input_keys;
setChatValue(""); setChatValue("");
const message = inputs; const message = inputs;
addChatHistory(message!, true, chatKey!, template.current); addChatHistory(message!, true, chatKey!, template.current);
@ -398,8 +398,8 @@ export default function FormModal({
description: flow.description, description: flow.description,
chatKey: chatKey!, chatKey: chatKey!,
}); });
if (currentFlowState && chatKey) { if (flowState && chatKey) {
setCurrentFlowState((old: FlowState | undefined) => { setFlowState((old: FlowState | undefined) => {
let newFlowState = cloneDeep(old!); let newFlowState = cloneDeep(old!);
newFlowState.input_keys![chatKey] = ""; newFlowState.input_keys![chatKey] = "";
return newFlowState; return newFlowState;
@ -414,7 +414,7 @@ export default function FormModal({
} }
function clearChat(): void { function clearChat(): void {
setChatHistory([]); setChatHistory([]);
template.current = currentFlowState?.template; template.current = flowState?.template;
ws.current?.send(JSON.stringify({ clear_history: true })); ws.current?.send(JSON.stringify({ clear_history: true }));
if (lockChat) setLockChat(false); if (lockChat) setLockChat(false);
} }
@ -422,7 +422,7 @@ export default function FormModal({
function handleOnCheckedChange(checked: boolean, i: string) { function handleOnCheckedChange(checked: boolean, i: string) {
if (checked === true) { if (checked === true) {
setChatKey(i); setChatKey(i);
setChatValue(currentFlowState?.input_keys![i] ?? ""); setChatValue(flowState?.input_keys![i] ?? "");
} else { } else {
setChatKey(null!); setChatKey(null!);
setChatValue(""); setChatValue("");
@ -431,7 +431,7 @@ export default function FormModal({
return ( return (
<Dialog open={open} onOpenChange={setOpen}> <Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger hidden></DialogTrigger> <DialogTrigger hidden></DialogTrigger>
{currentFlowState && currentFlowState && ( {flowState && flowState && (
<DialogContent className="min-w-[80vw]"> <DialogContent className="min-w-[80vw]">
<DialogHeader> <DialogHeader>
<DialogTitle className="flex items-center"> <DialogTitle className="flex items-center">
@ -467,8 +467,8 @@ export default function FormModal({
</div> </div>
</div> </div>
{currentFlowState?.input_keys {flowState?.input_keys
? Object.keys(currentFlowState?.input_keys!).map( ? Object.keys(flowState?.input_keys!).map(
(key, index) => ( (key, index) => (
<div className="file-component-accordion-div" key={index}> <div className="file-component-accordion-div" key={index}>
<AccordionComponent <AccordionComponent
@ -490,7 +490,7 @@ export default function FormModal({
handleOnCheckedChange(value, key) handleOnCheckedChange(value, key)
} }
size="small" size="small"
disabled={currentFlowState.handle_keys!.some( disabled={flowState.handle_keys!.some(
(t) => t === key (t) => t === key
)} )}
/> />
@ -501,7 +501,7 @@ export default function FormModal({
keyValue={key} keyValue={key}
> >
<div className="file-component-tab-column"> <div className="file-component-tab-column">
{currentFlowState?.handle_keys!.some( {flowState?.handle_keys!.some(
(t) => t === key (t) => t === key
) && ( ) && (
<div className="font-normal text-muted-foreground "> <div className="font-normal text-muted-foreground ">
@ -511,11 +511,11 @@ export default function FormModal({
<Textarea <Textarea
className="custom-scroll" className="custom-scroll"
value={ value={
currentFlowState?.input_keys![key] flowState?.input_keys![key]
} }
onChange={(e) => { onChange={(e) => {
if (currentFlowState) { if (flowState) {
setCurrentFlowState( setFlowState(
(old: FlowState | undefined) => { (old: FlowState | undefined) => {
let newFlowState = cloneDeep(old!); let newFlowState = cloneDeep(old!);
newFlowState.input_keys![ newFlowState.input_keys![
@ -535,7 +535,7 @@ export default function FormModal({
) )
) )
: null} : null}
{currentFlowState?.memory_keys!.map((key, index) => ( {flowState?.memory_keys!.map((key, index) => (
<div className="file-component-accordion-div" key={index}> <div className="file-component-accordion-div" key={index}>
<AccordionComponent <AccordionComponent
trigger={ trigger={
@ -627,8 +627,8 @@ export default function FormModal({
sendMessage={sendMessage} sendMessage={sendMessage}
setChatValue={(value) => { setChatValue={(value) => {
setChatValue(value); setChatValue(value);
if (currentFlowState && chatKey) { if (flowState && chatKey) {
setCurrentFlowState( setFlowState(
(old: FlowState | undefined) => { (old: FlowState | undefined) => {
let newFlowState = cloneDeep(old!); let newFlowState = cloneDeep(old!);
newFlowState.input_keys![ newFlowState.input_keys![

View file

@ -72,6 +72,7 @@ export default function Page({
const redo = useFlowsManagerStore((state) => state.redo); const redo = useFlowsManagerStore((state) => state.redo);
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
const paste = useFlowStore((state) => state.paste); const paste = useFlowStore((state) => state.paste);
const resetFlow = useFlowStore((state) => state.resetFlow);
const lastCopiedSelection = useFlowStore( const lastCopiedSelection = useFlowStore(
(state) => state.lastCopiedSelection (state) => state.lastCopiedSelection
); );
@ -174,13 +175,11 @@ export default function Page({
useEffect(() => { useEffect(() => {
setLoading(true); setLoading(true);
if (reactFlowInstance) { if (reactFlowInstance) {
useFlowStore.setState({ resetFlow({
nodes: flow?.data?.nodes ?? [], nodes: flow?.data?.nodes ?? [],
edges: flow?.data?.edges ?? [], edges: flow?.data?.edges ?? [],
}); viewport: flow?.data?.viewport ?? { zoom: 1, x: 0, y: 0 },
reactFlowInstance.setViewport( })
flow?.data?.viewport ?? { zoom: 1, x: 0, y: 0 }
);
} }
// Clear the previous timeout // Clear the previous timeout

View file

@ -28,16 +28,51 @@ import useFlowsManagerStore from "./flowsManagerStore";
// this is our useStore hook that we can use in our components to get parts of the store and call actions // this is our useStore hook that we can use in our components to get parts of the store and call actions
const useFlowStore = create<FlowStoreType>((set, get) => ({ const useFlowStore = create<FlowStoreType>((set, get) => ({
reactFlowInstance: null, sseData: {},
setReactFlowInstance: (newState) => { flowState: undefined,
set({ reactFlowInstance: newState });
},
nodes: [], nodes: [],
edges: [], edges: [],
isBuilt: false, isBuilding: false,
isBuilt: false,
reactFlowInstance: null,
lastCopiedSelection: null,
resetFlow: ({ nodes, edges, viewport }) => {
set({
nodes,
edges,
flowState: undefined,
sseData: {},
isBuilt: false,
});
get().reactFlowInstance!.setViewport(viewport);
},
updateSSEData: (sseData) => {
set((state) => ({ sseData: { ...state.sseData, ...sseData } }));
},
setIsBuilding: (isBuilding) => {
set({ isBuilding });
},
setIsBuilt: (isBuilt) => { setIsBuilt: (isBuilt) => {
set({ isBuilt }); set({ isBuilt });
}, },
setFlowState: (flowState) => {
const newFlowState =
typeof flowState === "function"
? flowState(get().flowState)
: flowState;
if(newFlowState !== get().flowState){
set(() => ({
flowState: newFlowState,
}));
}
},
setReactFlowInstance: (newState) => {
set({ reactFlowInstance: newState });
},
onNodesChange: (changes: NodeChange[]) => { onNodesChange: (changes: NodeChange[]) => {
set({ set({
nodes: applyNodeChanges(changes, get().nodes), nodes: applyNodeChanges(changes, get().nodes),
@ -52,29 +87,30 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
let newChange = typeof change === "function" ? change(get().nodes) : change; let newChange = typeof change === "function" ? change(get().nodes) : change;
let newEdges = cleanEdges(newChange, get().edges); let newEdges = cleanEdges(newChange, get().edges);
set({ edges: newEdges }); set({ edges: newEdges, nodes: newChange, flowState: undefined });
set({ nodes: newChange });
useFlowsManagerStore const flowsManager = useFlowsManagerStore.getState()
.getState()
.autoSaveCurrentFlow( flowsManager.autoSaveCurrentFlow(
newChange, newChange,
newEdges, newEdges,
get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }
); );
}, },
setEdges: (change) => { setEdges: (change) => {
let newChange = typeof change === "function" ? change(get().edges) : change; let newChange = typeof change === "function" ? change(get().edges) : change;
set({ edges: newChange }); set({ edges: newChange, flowState: undefined });
useFlowsManagerStore const flowsManager = useFlowsManagerStore.getState()
.getState()
.autoSaveCurrentFlow( flowsManager.autoSaveCurrentFlow(
get().nodes, get().nodes,
newChange, newChange,
get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }
); );
}, },
setNode: (id: string, change: Node | ((oldState: Node) => Node)) => { setNode: (id: string, change: Node | ((oldState: Node) => Node)) => {
let newChange = let newChange =
@ -204,7 +240,6 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
}); });
set({ edges: newEdges }); set({ edges: newEdges });
}, },
lastCopiedSelection: null,
setLastCopiedSelection: (newSelection) => { setLastCopiedSelection: (newSelection) => {
set({ lastCopiedSelection: newSelection }); set({ lastCopiedSelection: newSelection });
}, },

View file

@ -38,7 +38,6 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
setCurrentFlowId: (currentFlowId: string) => { setCurrentFlowId: (currentFlowId: string) => {
set((state) => ({ set((state) => ({
currentFlowId, currentFlowId,
currentFlowState: state.flowsState[state.currentFlowId],
currentFlow: state.flows.find((flow) => flow.id === currentFlowId), currentFlow: state.flows.find((flow) => flow.id === currentFlowId),
})); }));
}, },
@ -52,23 +51,6 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
currentFlow: undefined, currentFlow: undefined,
isLoading: true, isLoading: true,
setIsLoading: (isLoading: boolean) => set({ isLoading }), setIsLoading: (isLoading: boolean) => set({ isLoading }),
flowsState: {},
currentFlowState: undefined,
setCurrentFlowState: (
flowState: FlowState | ((oldState: FlowState | undefined) => FlowState)
) => {
const newFlowState =
typeof flowState === "function"
? flowState(get().currentFlowState)
: flowState;
set((state) => ({
flowsState: {
...state.flowsState,
[state.currentFlowId]: newFlowState,
},
currentFlowState: newFlowState,
}));
},
refreshFlows: () => { refreshFlows: () => {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
set({ isLoading: true }); set({ isLoading: true });

View file

@ -1,13 +0,0 @@
import { create } from "zustand";
import { SSEStoreType } from "../types/zustand/sse";
export const useSSEStore = create<SSEStoreType>((set) => ({
updateSSEData: (sseData) => {
set({ sseData });
},
sseData: {},
isBuilding: false,
setIsBuilding: (isBuilding) => {
set({ isBuilding });
},
}));

View file

@ -55,7 +55,7 @@ export type FlowsContextType = {
}; };
export type FlowsState = { export type FlowsState = {
[key: string]: FlowState; [key: string]: FlowState | undefined;
}; };
export type FlowState = { export type FlowState = {

View file

@ -5,11 +5,20 @@ import {
OnEdgesChange, OnEdgesChange,
OnNodesChange, OnNodesChange,
ReactFlowInstance, ReactFlowInstance,
Viewport,
} from "reactflow"; } from "reactflow";
import { FlowState } from "../../tabs";
export type FlowStoreType = { export type FlowStoreType = {
updateSSEData: (sseData: object) => void;
sseData: object;
isBuilding: boolean;
setIsBuilding: (isBuilding: boolean) => void;
resetFlow: (flow: {nodes: Node[], edges: Edge[], viewport: Viewport}) => void;
reactFlowInstance: ReactFlowInstance | null; reactFlowInstance: ReactFlowInstance | null;
setReactFlowInstance: (newState: ReactFlowInstance) => void; setReactFlowInstance: (newState: ReactFlowInstance) => void;
flowState: FlowState | undefined;
setFlowState: (state: FlowState | undefined | ((oldState: FlowState | undefined) => FlowState)) => void;
nodes: Node[]; nodes: Node[];
edges: Edge[]; edges: Edge[];
onNodesChange: OnNodesChange; onNodesChange: OnNodesChange;

View file

@ -10,9 +10,6 @@ export type FlowsManagerStoreType = {
setCurrentFlowId: (currentFlowId: string) => void; setCurrentFlowId: (currentFlowId: string) => void;
isLoading: boolean; isLoading: boolean;
setIsLoading: (isLoading: boolean) => void; setIsLoading: (isLoading: boolean) => void;
flowsState: FlowsState;
currentFlowState: FlowState | undefined;
setCurrentFlowState: (state: FlowState | ((oldState: FlowState | undefined) => FlowState)) => void;
refreshFlows: () => Promise<void>; refreshFlows: () => Promise<void>;
saveFlow: (flow: FlowType, silent?: boolean) => Promise<void>; saveFlow: (flow: FlowType, silent?: boolean) => Promise<void>;
autoSaveCurrentFlow: (nodes: Node[], edges: Edge[], viewport: Viewport) => void; autoSaveCurrentFlow: (nodes: Node[], edges: Edge[], viewport: Viewport) => void;

View file

@ -1,6 +0,0 @@
export type SSEStoreType = {
updateSSEData: (sseData: object) => void,
sseData: object,
isBuilding: boolean,
setIsBuilding: (isBuilding: boolean) => void,
}

View file

@ -217,11 +217,11 @@ export function groupByFamily(
})); }));
} }
export function buildInputs(currentFlowState?: FlowState): string { export function buildInputs(flowState?: FlowState): string {
return currentFlowState && return flowState &&
currentFlowState.input_keys && flowState.input_keys &&
Object.keys(currentFlowState.input_keys!).length > 0 Object.keys(flowState.input_keys!).length > 0
? JSON.stringify(currentFlowState.input_keys) ? JSON.stringify(flowState.input_keys)
: '{"input": "message"}'; : '{"input": "message"}';
} }
@ -296,15 +296,15 @@ export function buildTweakObject(tweak: tweakType) {
* @param {FlowsState} tabsState - The current tabs state. * @param {FlowsState} tabsState - The current tabs state.
* @returns {string} - The chat input field * @returns {string} - The chat input field
*/ */
export function getChatInputField(flow: FlowType, currentFlowState?: FlowState) { export function getChatInputField(flow: FlowType, flowState?: FlowState) {
let chat_input_field = "text"; let chat_input_field = "text";
if ( if (
currentFlowState && flowState &&
currentFlowState.input_keys flowState.input_keys
) { ) {
chat_input_field = Object.keys( chat_input_field = Object.keys(
currentFlowState.input_keys! flowState.input_keys!
)[0]; )[0];
} }
return chat_input_field; return chat_input_field;
@ -319,7 +319,7 @@ export function getPythonApiCode(
flow: FlowType, flow: FlowType,
isAuth: boolean, isAuth: boolean,
tweak?: any[], tweak?: any[],
currentFlowState?: FlowState flowState?: FlowState
): string { ): string {
const flowId = flow.id; const flowId = flow.id;
@ -328,7 +328,7 @@ export function getPythonApiCode(
// node.data.id // node.data.id
// } // }
const tweaks = buildTweaks(flow); const tweaks = buildTweaks(flow);
const inputs = buildInputs(currentFlowState); const inputs = buildInputs(flowState);
return `import requests return `import requests
from typing import Optional from typing import Optional
@ -383,11 +383,11 @@ export function getCurlCode(
flow: FlowType, flow: FlowType,
isAuth: boolean, isAuth: boolean,
tweak?: any[], tweak?: any[],
currentFlowState?: FlowState flowState?: FlowState
): string { ): string {
const flowId = flow.id; const flowId = flow.id;
const tweaks = buildTweaks(flow); const tweaks = buildTweaks(flow);
const inputs = buildInputs(currentFlowState); const inputs = buildInputs(flowState);
return `curl -X POST \\ return `curl -X POST \\
${window.location.protocol}//${ ${window.location.protocol}//${
@ -411,11 +411,11 @@ export function getCurlCode(
export function getPythonCode( export function getPythonCode(
flow: FlowType, flow: FlowType,
tweak?: any[], tweak?: any[],
currentFlowState?: FlowState flowState?: FlowState
): string { ): string {
const flowName = flow.name; const flowName = flow.name;
const tweaks = buildTweaks(flow); const tweaks = buildTweaks(flow);
const inputs = buildInputs(currentFlowState); const inputs = buildInputs(flowState);
return `from langflow import load_flow_from_json return `from langflow import load_flow_from_json
TWEAKS = ${ TWEAKS = ${
tweak && tweak.length > 0 tweak && tweak.length > 0
@ -436,12 +436,12 @@ flow(inputs)`;
export function getWidgetCode( export function getWidgetCode(
flow: FlowType, flow: FlowType,
isAuth: boolean, isAuth: boolean,
currentFlowState?: FlowState flowState?: FlowState
): string { ): string {
const flowId = flow.id; const flowId = flow.id;
const flowName = flow.name; const flowName = flow.name;
const inputs = buildInputs(currentFlowState); const inputs = buildInputs(flowState);
let chat_input_field = getChatInputField(flow, currentFlowState); let chat_input_field = getChatInputField(flow, flowState);
return `<script src="https://cdn.jsdelivr.net/gh/logspace-ai/langflow-embedded-chat@main/dist/build/static/js/bundle.min.js"></script> return `<script src="https://cdn.jsdelivr.net/gh/logspace-ai/langflow-embedded-chat@main/dist/build/static/js/bundle.min.js"></script>
@ -452,7 +452,7 @@ chat_input_field: Input key that you want the chat to send the user message with
window_title="${flowName}" window_title="${flowName}"
flow_id="${flowId}" flow_id="${flowId}"
${ ${
currentFlowState flowState
? `chat_inputs='${inputs}' ? `chat_inputs='${inputs}'
chat_input_field="${chat_input_field}" chat_input_field="${chat_input_field}"
` `