diff --git a/langflow/frontend/src/CustomNodes/BooleanNode/index.tsx b/langflow/frontend/src/CustomNodes/BooleanNode/index.tsx deleted file mode 100644 index c22a9b972..000000000 --- a/langflow/frontend/src/CustomNodes/BooleanNode/index.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { CheckCircleIcon, TrashIcon } from "@heroicons/react/24/outline"; -import { Handle, Position } from "reactflow"; -import { isValidConnection, nodeColors } from "../../utils"; -import ToggleComponent from "../../components/toggleComponent"; -import { useContext, useState } from "react"; -import { typesContext } from "../../contexts/typesContext"; -import { NodeDataType } from "../../types/flow"; - -export default function BooleanNode({ data }:{data:NodeDataType}) { - const [enabled, setEnabled] = useState(false); - const {types, deleteNode, reactFlowInstance} = useContext(typesContext); - return ( -
-
-
- - Boolean -
- -
-
- {setEnabled(x); data.value = x}} /> -
- isValidConnection(connection,reactFlowInstance)} - className={"-mr-0.5 w-3 h-3 rounded-full border-2 bg-white dark:bg-gray-800"} - style={{ - borderColor: nodeColors[types[data.type]], - }} - > -
- ); -} diff --git a/langflow/frontend/src/CustomNodes/ChatInputNode/index.tsx b/langflow/frontend/src/CustomNodes/ChatInputNode/index.tsx deleted file mode 100644 index d579a2c07..000000000 --- a/langflow/frontend/src/CustomNodes/ChatInputNode/index.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { - Bars3CenterLeftIcon, -} from "@heroicons/react/24/outline"; -import { isValidConnection, nodeColors } from "../../utils"; -import { Handle, Position } from "reactflow"; -import Tooltip from "../../components/TooltipComponent"; -import { typesContext } from "../../contexts/typesContext"; -import { useContext } from "react"; -import { NodeDataType } from "../../types/flow"; - -export default function ChatInputNode({ data }:{data:NodeDataType}) { - const { types,reactFlowInstance } = useContext(typesContext); - return ( -
- - - isValidConnection(connection,reactFlowInstance) - } - position={Position.Left} - id={"str|Prefix|" + data.id} - className={"-ml-0.5 w-3 h-3 rounded-full border-2 bg-white dark:bg-gray-800"} - style={{ - borderColor: nodeColors[types[data.type]], - }} - > - - - - isValidConnection(connection,reactFlowInstance) - } - position={Position.Right} - id={"str|str|" + data.id} - className={"-mr-0.5 w-3 h-3 rounded-full border-2 bg-white dark:bg-gray-800"} - style={{ - borderColor: nodeColors[types[data.type]], - }} - > - -
- - Input -
-
- ); -} diff --git a/langflow/frontend/src/CustomNodes/ChatOutputNode/index.tsx b/langflow/frontend/src/CustomNodes/ChatOutputNode/index.tsx deleted file mode 100644 index ef3a435ca..000000000 --- a/langflow/frontend/src/CustomNodes/ChatOutputNode/index.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Bars3CenterLeftIcon } from "@heroicons/react/24/outline"; -import { Handle, Position } from "reactflow"; -import { isValidConnection, nodeColors } from "../../utils"; -import Tooltip from "../../components/TooltipComponent"; -import { useContext } from "react"; -import { typesContext } from "../../contexts/typesContext"; -import { NodeDataType } from "../../types/flow"; - -export default function ChatOutputNode({ data }:{data:NodeDataType}) { - const {types,reactFlowInstance} = useContext(typesContext); - return ( -
- - isValidConnection(connection,reactFlowInstance)} - position={Position.Left} - id={"str|output|"+data.id} - className={"-ml-0.5 w-3 h-3 rounded-full border-2 bg-white dark:bg-gray-800" - } - style={{ - borderColor: nodeColors[types[data.type]], - }} - > - - -
- Output - -
-
- ); -} diff --git a/langflow/frontend/src/CustomNodes/InputNode/index.tsx b/langflow/frontend/src/CustomNodes/InputNode/index.tsx deleted file mode 100644 index 60afbc6b6..000000000 --- a/langflow/frontend/src/CustomNodes/InputNode/index.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { Bars3CenterLeftIcon, TrashIcon } from "@heroicons/react/24/outline"; -import InputComponent from "../../components/inputComponent"; -import { - isValidConnection, - nodeColors, -} from "../../utils"; -import { Handle, Position } from "reactflow"; -import { useContext } from "react"; -import Tooltip from "../../components/TooltipComponent"; -import { typesContext } from "../../contexts/typesContext"; -import { NodeDataType } from "../../types/flow"; - -export default function InputNode({ data }:{data:NodeDataType}) { - console.log(data) - const {types, deleteNode,reactFlowInstance} = useContext(typesContext); - return ( -
- - - isValidConnection(connection,reactFlowInstance) - } - className={"-ml-0.5 w-3 h-3 rounded-full border-2 bg-white dark:bg-gray-800"} - style={{ - borderColor: nodeColors[types[data.type]], - }} - > - - -
-
- - String -
- -
-
- - { - data.value = e; - }} - /> -
- isValidConnection(connection,reactFlowInstance)} - className={"-mr-0.5 w-3 h-3 rounded-full border-2 bg-white dark:bg-gray-800"} - style={{ - borderColor: nodeColors[types[data.type]], - }} - > -
- ); -} diff --git a/langflow/frontend/src/components/ExtraSidebarComponent/index.tsx b/langflow/frontend/src/components/ExtraSidebarComponent/index.tsx index 7a112fd29..0dc42bfb4 100644 --- a/langflow/frontend/src/components/ExtraSidebarComponent/index.tsx +++ b/langflow/frontend/src/components/ExtraSidebarComponent/index.tsx @@ -21,8 +21,8 @@ export default function ExtraSidebar() { } flex-shrink-0 flex overflow-hidden flex-col border-r dark:border-r-gray-700 transition-all duration-500`} >
-
- +
+ {extraNavigation.title}
diff --git a/langflow/frontend/src/components/HeaderComponent/index.tsx b/langflow/frontend/src/components/HeaderComponent/index.tsx index 40611e9c4..2bd902426 100644 --- a/langflow/frontend/src/components/HeaderComponent/index.tsx +++ b/langflow/frontend/src/components/HeaderComponent/index.tsx @@ -15,6 +15,7 @@ export default function Header(){ const {layerProps,renderLayer, triggerProps} = useLayer({ isOpen, placement: "left-start", + auto:true, onOutsideClick:()=>setIsOpen(false), preferX: "left", triggerOffset: 10, diff --git a/langflow/frontend/src/components/chatComponent/index.tsx b/langflow/frontend/src/components/chatComponent/index.tsx index 99c7c1d20..ec4475112 100644 --- a/langflow/frontend/src/components/chatComponent/index.tsx +++ b/langflow/frontend/src/components/chatComponent/index.tsx @@ -1,8 +1,8 @@ import { Transition } from "@headlessui/react"; import { - Bars3CenterLeftIcon, - PaperAirplaneIcon, - XMarkIcon, + Bars3CenterLeftIcon, + PaperAirplaneIcon, + XMarkIcon, } from "@heroicons/react/24/outline"; import { useContext, useEffect, useRef, useState } from "react"; import { sendAll } from "../../controllers/NodesServices"; @@ -13,170 +13,190 @@ import { ChatType } from "../../types/chat"; const _ = require("lodash"); -export default function Chat({flow, reactFlowInstance }:ChatType) { - const {updateFlow} = useContext(TabsContext) - const [saveChat,setSaveChat] = useState(false) - const [open, setOpen] = useState(true); - const [chatValue, setChatValue] = useState(""); - const [chatHistory, setChatHistory] = useState(flow.chat); - const {setErrorData} = useContext(alertContext); - const addChatHistory = (message:string, isSend:boolean) => { - setChatHistory((old) => { - let newChat = _.cloneDeep(old); - newChat.push({ message, isSend }); - return newChat; - }); - setSaveChat(chat=>!chat) - }; - useEffect(()=>{ - updateFlow({..._.cloneDeep(flow),chat:chatHistory}) - // eslint-disable-next-line react-hooks/exhaustive-deps - },[saveChat]) - useEffect(()=>{ - setChatHistory(flow.chat) - },[flow]) - useEffect(()=>{ - if(ref.current) - ref.current.scrollIntoView({behavior: 'smooth'}); - }, [chatHistory]) - function validateNodes(){ - if(reactFlowInstance.getNodes().some((n) => (n.data.node && Object.keys(n.data.node.template).some((t: any) => ((n.data.node.template[t].required && n.data.node.template[t].value === "") && (n.data.node.template[t].required && !reactFlowInstance.getEdges().some((e) => (e.sourceHandle.split('|')[1] === t && e.sourceHandle.split('|')[2] === n.id)))))))){ - return false; - } - return true; - } - function validateChatNodes(){ - if(!reactFlowInstance.getNodes().some((n)=> (n.type === 'chatOutputNode'))){ - return false; - } - return true; - } - const ref = useRef(null); +export default function Chat({ flow, reactFlowInstance }: ChatType) { + const { updateFlow } = useContext(TabsContext); + const [saveChat, setSaveChat] = useState(false); + const [open, setOpen] = useState(true); + const [chatValue, setChatValue] = useState(""); + const [chatHistory, setChatHistory] = useState(flow.chat); + const { setErrorData } = useContext(alertContext); + const addChatHistory = (message: string, isSend: boolean) => { + setChatHistory((old) => { + let newChat = _.cloneDeep(old); + newChat.push({ message, isSend }); + return newChat; + }); + setSaveChat((chat) => !chat); + }; + useEffect(() => { + updateFlow({ ..._.cloneDeep(flow), chat: chatHistory }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [saveChat]); + useEffect(() => { + setChatHistory(flow.chat); + }, [flow]); + useEffect(() => { + if (ref.current) ref.current.scrollIntoView({ behavior: "smooth" }); + }, [chatHistory]); + function validateNodes() { + if ( + reactFlowInstance + .getNodes() + .some( + (n) => + n.data.node && + Object.keys(n.data.node.template).some( + (t: any) => + n.data.node.template[t].required && + n.data.node.template[t].value === "" && + n.data.node.template[t].required && + !reactFlowInstance + .getEdges() + .some( + (e) => + e.sourceHandle.split("|")[1] === t && + e.sourceHandle.split("|")[2] === n.id + ) + ) + ) + ) { + return false; + } + return true; + } + const ref = useRef(null); - function sendMessage(){ - if(chatValue !== ""){ - if(validateNodes()){ - if(validateChatNodes()){ - let message = chatValue; - setChatValue(""); - addChatHistory(message, true); - console.log({...reactFlowInstance.toObject(),message,chatHistory}) - sendAll({...reactFlowInstance.toObject(),message,chatHistory}).then((r) => {addChatHistory(r.data.result, false);}); - } else { - setErrorData({title: 'Error sending message', list:['Chat nodes are missing.']}) - } - - } else { - setErrorData({title: 'Error sending message', list:['There are required fields not filled yet.']}) - } - } else { - setErrorData({title: 'Error sending message', list:['The message cannot be empty.']}) - } - } + function sendMessage() { + if (chatValue !== "") { + if (validateNodes()) { + let message = chatValue; + setChatValue(""); + addChatHistory(message, true); + console.log({ ...reactFlowInstance.toObject(), message, chatHistory }); + sendAll({ ...reactFlowInstance.toObject(), message, chatHistory }).then( + (r) => { + addChatHistory(r.data.result, false); + } + ); + } else { + setErrorData({ + title: "Error sending message", + list: ["There are required fields not filled yet."], + }); + } + } else { + setErrorData({ + title: "Error sending message", + list: ["The message cannot be empty."], + }); + } + } - return ( - <> - -
-
-
-
- - Chat -
- -
-
- {chatHistory.map((c, i) => ( -
- {!c.isSend ? ( -
-
- {c.message} -
-
- ) : ( -
-
- {c.message} -
-
- )} -
- ))} -
-
-
-
- { - if(event.key==='Enter'){ - sendMessage() - } - }} - type="text" - value={chatValue} - onChange={(e) => { - setChatValue(e.target.value); - }} - className="form-input block w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white pr-10 sm:text-sm" - placeholder="Send a message..." - /> -
- -
-
-
-
-
-
- -
-
- -
-
-
- - ); + return ( + <> + +
+
+
{ + setOpen(false); + }} className="flex justify-between cursor-pointer items-center px-5 py-2 border-b dark:border-b-gray-700"> +
+ + Chat +
+
+
+ {chatHistory.map((c, i) => ( +
+ {!c.isSend ? ( +
+
+ {c.message} +
+
+ ) : ( +
+
+ {c.message} +
+
+ )} +
+ ))} +
+
+
+
+ { + if (event.key === "Enter") { + sendMessage(); + } + }} + type="text" + value={chatValue} + onChange={(e) => { + setChatValue(e.target.value); + }} + className="form-input block w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white pr-10 sm:text-sm" + placeholder="Send a message..." + /> +
+ +
+
+
+
+
+
+ +
+
+ +
+
+
+ + ); } diff --git a/langflow/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/langflow/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index a0569e2e5..58400ebba 100644 --- a/langflow/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/langflow/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -16,12 +16,6 @@ export default function ExtraSidebar() { useEffect(() => { async function getTypes():Promise{ - // Define an object with initial values for the types. - const initialValue:{[char: string]: string} = { - str: "advanced", - bool: "advanced", - chatOutput: "chat", - } // Make an asynchronous API call to retrieve all data. let result = await getAll(); @@ -41,8 +35,7 @@ export default function ExtraSidebar() { }); }); return acc; - }, - initialValue + },{} ) ); } @@ -58,7 +51,7 @@ export default function ExtraSidebar() { } return ( -
+
{Object.keys(data).map((d:keyof APIObjectType, i) => ( ))} - -
-
-
- onDragStart(event, { - type: "chatOutput", - }) - } - > -
- Chat Output - -
-
-
-
-
- -
-
-
- onDragStart(event, { - type: "str", - }) - } - > -
- String - -
-
-
-
-
- onDragStart(event, { - type: "bool", - }) - } - > -
- Boolean - -
-
-
-
-
); } diff --git a/langflow/frontend/src/pages/FlowPage/index.tsx b/langflow/frontend/src/pages/FlowPage/index.tsx index 15a4adee8..d6cbbaa68 100644 --- a/langflow/frontend/src/pages/FlowPage/index.tsx +++ b/langflow/frontend/src/pages/FlowPage/index.tsx @@ -14,10 +14,6 @@ import { locationContext } from "../../contexts/locationContext"; import ExtraSidebar from "./components/extraSidebarComponent"; import Chat from "../../components/chatComponent"; import GenericNode from "../../CustomNodes/GenericNode"; -import ChatInputNode from "../../CustomNodes/ChatInputNode"; -import ChatOutputNode from "../../CustomNodes/ChatOutputNode"; -import InputNode from "../../CustomNodes/InputNode"; -import BooleanNode from "../../CustomNodes/BooleanNode"; import { alertContext } from "../../contexts/alertContext"; import { TabsContext } from "../../contexts/tabsContext"; import { typesContext } from "../../contexts/typesContext"; @@ -31,10 +27,6 @@ import { APIClassType } from "../../types/api"; const nodeTypes = { genericNode: GenericNode, - inputNode: InputNode, - chatInputNode: ChatInputNode, - chatOutputNode: ChatOutputNode, - booleanNode: BooleanNode, }; var _ = require("lodash"); @@ -74,7 +66,7 @@ export default function FlowPage({ flow }:{flow:FlowType}) { //set extra sidebar useEffect(() => { setExtraComponent(); - setExtraNavigation({ title: "Componets" }); + setExtraNavigation({ title: "Components" }); }, [setExtraComponent, setExtraNavigation]); const onEdgesChangeMod = useCallback( @@ -139,14 +131,7 @@ export default function FlowPage({ flow }:{flow:FlowType}) { // Create a new node object const newNode:NodeType = { id: newId, - type: - data.type === "str" - ? "inputNode" - : data.type === "chatOutput" - ? "chatOutputNode" - : data.type === "bool" - ? "booleanNode" - : "genericNode", + type: "genericNode", position, data: { ...data,