Removed SSE Store and fixed node building not appearing at node
This commit is contained in:
parent
41976f608e
commit
221776c2d4
14 changed files with 138 additions and 161 deletions
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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![
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 });
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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 });
|
||||||
|
|
|
||||||
|
|
@ -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 });
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
@ -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 = {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
export type SSEStoreType = {
|
|
||||||
updateSSEData: (sseData: object) => void,
|
|
||||||
sseData: object,
|
|
||||||
isBuilding: boolean,
|
|
||||||
setIsBuilding: (isBuilding: boolean) => void,
|
|
||||||
}
|
|
||||||
|
|
@ -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}"
|
||||||
`
|
`
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue