diff --git a/src/frontend/src/components/IOview/index.tsx b/src/frontend/src/components/IOview/index.tsx index 2e7cc0aa9..f0c2defc1 100644 --- a/src/frontend/src/components/IOview/index.tsx +++ b/src/frontend/src/components/IOview/index.tsx @@ -1,7 +1,11 @@ +import { cloneDeep } from "lodash"; import { useEffect, useState } from "react"; import { CHAT_FORM_DIALOG_SUBTITLE } from "../../constants/constants"; import BaseModal from "../../modals/baseModal"; +import useAlertStore from "../../stores/alertStore"; import useFlowStore from "../../stores/flowStore"; +import { NodeType } from "../../types/flow"; +import { validateNodes } from "../../utils/reactflowUtils"; import { cn } from "../../utils/utils"; import AccordionComponent from "../AccordionComponent"; import IOInputField from "../IOInputField"; @@ -26,9 +30,13 @@ export default function IOView({ children, open, setOpen }): JSX.Element { node.type !== "ChatInput" && node.type !== "ChatOutput" ); - const haveChat = useFlowStore((state) => state.outputs).some( - (output) => output.type === "ChatOutput" || output.type === "ChatInput" - ); + const haveChat = + useFlowStore((state) => state.outputs).some( + (output) => output.type === "ChatOutput" + ) || + useFlowStore((state) => state.inputs).some( + (input) => input.type === "ChatInput" + ); const [selectedTab, setSelectedTab] = useState( inputs.length > 0 ? 1 : outputs.length > 0 ? 2 : 0 ); @@ -36,6 +44,48 @@ export default function IOView({ children, open, setOpen }): JSX.Element { { type: string; id: string } | undefined >(undefined); + const { getNode, setNode, buildFlow, getFlow } = useFlowStore(); + const { setErrorData } = useAlertStore(); + const setIsBuilding = useFlowStore((state) => state.setIsBuilding); + const [lockChat, setLockChat] = useState(false); + const [chatValue, setChatValue] = useState(""); + const isBuilding = useFlowStore((state) => state.isBuilding); + + async function sendMessage(count = 1): Promise { + if (isBuilding) return; + const { nodes, edges } = getFlow(); + let nodeValidationErrors = validateNodes(nodes, edges); + if (nodeValidationErrors.length === 0) { + setIsBuilding(true); + setLockChat(true); + setChatValue(""); + const chatInputId = inputs + .map((obj) => obj.id) + .find((inputId) => inputId.includes("ChatInput")); + const chatInput: NodeType = getNode(chatInputId!) as NodeType; + if (chatInput) { + let newNode = cloneDeep(chatInput); + newNode.data.node!.template["message"].value = chatValue; + setNode(chatInputId!, newNode); + } + for (let i = 0; i < count; i++) { + await buildFlow().catch((err) => { + console.error(err); + setLockChat(false); + }); + } + setLockChat(false); + + //set chat message in the flow and run build + //@ts-ignore + } else { + setErrorData({ + title: "Oops! Looks like you missed some required information:", + list: nodeValidationErrors, + }); + } + } + useEffect(() => { setSelectedViewField(undefined); setSelectedTab(inputs.length > 0 ? 1 : outputs.length > 0 ? 2 : 0); @@ -60,178 +110,194 @@ export default function IOView({ children, open, setOpen }): JSX.Element { -
- {selectedTab !== 0 && ( -
- { - setSelectedTab(Number(value)); - }} +
+
+ {selectedTab !== 0 && ( +
-
- - {inputs.length > 0 && ( - Inputs - )} - {outputs.length > 0 && ( - Outputs - )} - -
- - { + setSelectedTab(Number(value)); + }} > -
- - Text Inputs +
+ + {inputs.length > 0 && ( + Inputs + )} + {outputs.length > 0 && ( + Outputs + )} +
- {nodes - .filter((node) => - inputs.some((input) => input.id === node.id) - ) - .map((node, index) => { - const input = inputs.find( - (input) => input.id === node.id - )!; - return ( -
- - - {input.id} - - {haveChat && ( -
{ - event.stopPropagation(); - setSelectedViewField(input); - }} - > - -
- )} -
- } - key={index} - keyValue={input.id} - > -
-
- {input && ( - - )} -
-
- -
- ); - })} -
- -
- - Prompt Outputs -
- {nodes - .filter((node) => - outputs.some((output) => output.id === node.id) - ) - .map((node, index) => { - const output = outputs.find( - (output) => output.id === node.id - )!; - return ( -
- - - {output.id} - - {haveChat && ( -
{ - event.stopPropagation(); - setSelectedViewField(output); - }} - > - -
- )} -
- } - key={index} - keyValue={output.id} - > -
-
- {output && ( - - )} -
-
- -
- ); - })} - - -
- )} - {haveChat ? ( - selectedViewField ? ( - inputs.some((input) => input.id === selectedViewField.id) ? ( - + +
+ + Text Inputs +
+ {nodes + .filter((node) => + inputs.some((input) => input.id === node.id) + ) + .map((node, index) => { + const input = inputs.find( + (input) => input.id === node.id + )!; + return ( +
+ + + {input.id} + + {haveChat && ( +
{ + event.stopPropagation(); + setSelectedViewField(input); + }} + > + +
+ )} +
+ } + key={index} + keyValue={input.id} + > +
+
+ {input && ( + + )} +
+
+ +
+ ); + })} + + +
+ + Prompt Outputs +
+ {nodes + .filter((node) => + outputs.some((output) => output.id === node.id) + ) + .map((node, index) => { + const output = outputs.find( + (output) => output.id === node.id + )!; + return ( +
+ + + {output.id} + + {haveChat && ( +
{ + event.stopPropagation(); + setSelectedViewField(output); + }} + > + +
+ )} +
+ } + key={index} + keyValue={output.id} + > +
+
+ {output && ( + + )} +
+
+ +
+ ); + })} + + +
+ )} + + {haveChat ? ( + selectedViewField ? ( + inputs.some((input) => input.id === selectedViewField.id) ? ( + + ) : ( + + ) ) : ( - ) ) : ( - - ) - ) : ( -
-
+ {!haveChat && ( +
+
)} diff --git a/src/frontend/src/components/newChatView/index.tsx b/src/frontend/src/components/newChatView/index.tsx index d069ea97c..38a633444 100644 --- a/src/frontend/src/components/newChatView/index.tsx +++ b/src/frontend/src/components/newChatView/index.tsx @@ -1,4 +1,4 @@ -import _, { cloneDeep } from "lodash"; +import _ from "lodash"; import { useEffect, useRef, useState } from "react"; import IconComponent from "../../components/genericIconComponent"; import { deleteFlowPool } from "../../controllers/API"; @@ -11,30 +11,21 @@ import { ChatOutputType, FlowPoolObjectType, } from "../../types/chat"; -import { NodeType } from "../../types/flow"; -import { validateNodes } from "../../utils/reactflowUtils"; import { classNames } from "../../utils/utils"; import ChatInput from "./chatInput"; import ChatMessage from "./chatMessage"; -export default function NewChatView(): JSX.Element { - const [chatValue, setChatValue] = useState(""); - const { - flowPool, - outputs, - inputs, - getNode, - setNode, - buildFlow, - getFlow, - CleanFlowPool, - } = useFlowStore(); - const { setErrorData, setNoticeData } = useAlertStore(); +export default function NewChatView({ + sendMessage, + chatValue, + setChatValue, + lockChat, + setLockChat, +}): JSX.Element { + const { flowPool, outputs, inputs, CleanFlowPool } = useFlowStore(); + const { setNoticeData } = useAlertStore(); const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId); - const setIsBuilding = useFlowStore((state) => state.setIsBuilding); - const [lockChat, setLockChat] = useState(false); const messagesRef = useRef(null); - const isBuilding = useFlowStore((state) => state.isBuilding); const [chatHistory, setChatHistory] = useState([]); const inputTypes = inputs.map((obj) => obj.type); @@ -115,40 +106,6 @@ export default function NewChatView(): JSX.Element { } }, []); - async function sendMessage(count = 1): Promise { - if (isBuilding) return; - const { nodes, edges } = getFlow(); - let nodeValidationErrors = validateNodes(nodes, edges); - if (nodeValidationErrors.length === 0) { - setIsBuilding(true); - setLockChat(true); - setChatValue(""); - const chatInputId = inputIds.find((inputId) => - inputId.includes("ChatInput") - ); - const chatInput: NodeType = getNode(chatInputId!) as NodeType; - if (chatInput) { - let newNode = cloneDeep(chatInput); - newNode.data.node!.template["message"].value = chatValue; - setNode(chatInputId!, newNode); - } - for (let i = 0; i < count; i++) { - await buildFlow().catch((err) => { - console.error(err); - setLockChat(false); - }); - } - setLockChat(false); - - //set chat message in the flow and run build - //@ts-ignore - } else { - setErrorData({ - title: "Oops! Looks like you missed some required information:", - list: nodeValidationErrors, - }); - } - } function clearChat(): void { setChatHistory([]); deleteFlowPool(currentFlowId).then((_) => {