removed chat and advanced components from side bar and flow declarations

This commit is contained in:
anovazzi1 2023-03-06 17:41:48 -03:00
commit edd987f9b2
9 changed files with 194 additions and 462 deletions

View file

@ -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 (
<div className="prompt-node relative bg-white dark:bg-gray-900 rounded-lg solid border dark:border-gray-700 flex flex-col justify-center">
<div className="w-full flex items-center justify-between gap-8 p-4 bg-gray-50 dark:bg-gray-800 dark:text-white dark:border-b-gray-700 border-b ">
<div className="flex items-center gap-4 text-lg">
<CheckCircleIcon
className="w-10 h-10 p-1 rounded"
style={{ color: nodeColors[types[data.type]] }}
/>
Boolean
</div>
<button
onClick={() => {
deleteNode(data.id);
}}
>
<TrashIcon className="text-gray-600 w-6 h-6 hover:text-red-500"></TrashIcon>
</button>
</div>
<div className="w-full flex justify-center p-5 h-full">
<ToggleComponent enabled={enabled} disabled={false} setEnabled={(x) => {setEnabled(x); data.value = x}} />
</div>
<Handle
type="source"
position={Position.Right}
id={data.type}
isValidConnection={(connection) => 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]],
}}
></Handle>
</div>
);
}

View file

@ -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 (
<div
className="prompt-node relative rounded-lg solid border flex justify-center align-center py-3 px-6 bg-gray-50 dark:bg-gray-800 dark:border-gray-700"
style={{ color: nodeColors[types[data.type]] }}
>
<Tooltip title="Prefix: str">
<Handle
type="target"
isValidConnection={(connection) =>
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]],
}}
></Handle>
</Tooltip>
<Tooltip title={"Message: str"}>
<Handle
type="source"
isValidConnection={(connection) =>
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]],
}}
></Handle>
</Tooltip>
<div
className="flex gap-3 text-lg font-medium items-center"
style={{ color: nodeColors[types[data.type]] }}
>
<Bars3CenterLeftIcon className="h-8 w-8 mt-1" />
Input
</div>
</div>
);
}

View file

@ -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 (
<div className="prompt-node relative rounded-lg solid border flex justify-center align-center py-3 px-6 bg-gray-50 dark:bg-gray-800 dark:border-gray-700" style={{color: nodeColors[types[data.type]]}}>
<Tooltip title="Message: str">
<Handle
type="target"
isValidConnection={(connection) => 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]],
}}
></Handle>
</Tooltip>
<div className="flex gap-3 text-lg font-medium items-center" style={{color: nodeColors[types[data.type]]}}>
Output
<Bars3CenterLeftIcon className="h-8 w-8 mt-1" />
</div>
</div>
);
}

View file

@ -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 (
<div className="prompt-node relative bg-white dark:bg-gray-900 w-96 rounded-lg solid border dark:border-gray-700 flex flex-col justify-center">
<Tooltip title="Prefix: str">
<Handle
type="target"
position={Position.Left}
id={"str|Prefix|" + data.id}
isValidConnection={(connection) =>
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]],
}}
></Handle>
</Tooltip>
<div className="w-full flex items-center justify-between p-4 gap-8 bg-gray-50 dark:bg-gray-800 dark:text-white border-b dark:border-b-gray-700 ">
<div className="flex items-center gap-4 text-lg">
<Bars3CenterLeftIcon
className="w-10 h-10 p-1 rounded"
style={{ color: nodeColors[types[data.type]] }}
/>
String
</div>
<button
onClick={() => {
deleteNode(data.id)
}}
>
<TrashIcon className="text-gray-600 w-6 h-6 hover:text-red-500"></TrashIcon>
</button>
</div>
<div className="w-full p-5 h-full">
<InputComponent
disabled={false}
value=""
onChange={(e) => {
data.value = e;
}}
/>
</div>
<Handle
type="source"
position={Position.Right}
id={data.type}
isValidConnection={(connection) => 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]],
}}
></Handle>
</div>
);
}

View file

@ -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`} } flex-shrink-0 flex overflow-hidden flex-col border-r dark:border-r-gray-700 transition-all duration-500`}
> >
<div className="w-60 dark:bg-gray-800 border dark:border-gray-700 overflow-y-auto scrollbar-hide h-full flex flex-col items-start"> <div className="w-60 dark:bg-gray-800 border dark:border-gray-700 overflow-y-auto scrollbar-hide h-full flex flex-col items-start">
<div className="flex pt-4 px-4 justify-between align-middle w-full"> <div className="flex pt-1 px-4 justify-between align-middle w-full">
<span className="text-gray-900 dark:text-white text-lg ml-2 font-semibold"> <span className="text-gray-900 dark:text-white text-lg ml-2 font-medium ">
{extraNavigation.title} {extraNavigation.title}
</span> </span>
</div> </div>

View file

@ -15,6 +15,7 @@ export default function Header(){
const {layerProps,renderLayer, triggerProps} = useLayer({ const {layerProps,renderLayer, triggerProps} = useLayer({
isOpen, isOpen,
placement: "left-start", placement: "left-start",
auto:true,
onOutsideClick:()=>setIsOpen(false), onOutsideClick:()=>setIsOpen(false),
preferX: "left", preferX: "left",
triggerOffset: 10, triggerOffset: 10,

View file

@ -14,8 +14,8 @@ import { ChatType } from "../../types/chat";
const _ = require("lodash"); const _ = require("lodash");
export default function Chat({ flow, reactFlowInstance }: ChatType) { export default function Chat({ flow, reactFlowInstance }: ChatType) {
const {updateFlow} = useContext(TabsContext) const { updateFlow } = useContext(TabsContext);
const [saveChat,setSaveChat] = useState(false) const [saveChat, setSaveChat] = useState(false);
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
const [chatValue, setChatValue] = useState(""); const [chatValue, setChatValue] = useState("");
const [chatHistory, setChatHistory] = useState(flow.chat); const [chatHistory, setChatHistory] = useState(flow.chat);
@ -26,27 +26,40 @@ export default function Chat({flow, reactFlowInstance }:ChatType) {
newChat.push({ message, isSend }); newChat.push({ message, isSend });
return newChat; return newChat;
}); });
setSaveChat(chat=>!chat) setSaveChat((chat) => !chat);
}; };
useEffect(() => { useEffect(() => {
updateFlow({..._.cloneDeep(flow),chat:chatHistory}) updateFlow({ ..._.cloneDeep(flow), chat: chatHistory });
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
},[saveChat]) }, [saveChat]);
useEffect(() => { useEffect(() => {
setChatHistory(flow.chat) setChatHistory(flow.chat);
},[flow]) }, [flow]);
useEffect(() => { useEffect(() => {
if(ref.current) if (ref.current) ref.current.scrollIntoView({ behavior: "smooth" });
ref.current.scrollIntoView({behavior: 'smooth'}); }, [chatHistory]);
}, [chatHistory])
function validateNodes() { 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)))))))){ if (
return false; reactFlowInstance
} .getNodes()
return true; .some(
} (n) =>
function validateChatNodes(){ n.data.node &&
if(!reactFlowInstance.getNodes().some((n)=> (n.type === 'chatOutputNode'))){ 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 false;
} }
return true; return true;
@ -56,21 +69,26 @@ export default function Chat({flow, reactFlowInstance }:ChatType) {
function sendMessage() { function sendMessage() {
if (chatValue !== "") { if (chatValue !== "") {
if (validateNodes()) { if (validateNodes()) {
if(validateChatNodes()){
let message = chatValue; let message = chatValue;
setChatValue(""); setChatValue("");
addChatHistory(message, true); addChatHistory(message, true);
console.log({...reactFlowInstance.toObject(),message,chatHistory}) console.log({ ...reactFlowInstance.toObject(), message, chatHistory });
sendAll({...reactFlowInstance.toObject(),message,chatHistory}).then((r) => {addChatHistory(r.data.result, false);}); sendAll({ ...reactFlowInstance.toObject(), message, chatHistory }).then(
} else { (r) => {
setErrorData({title: 'Error sending message', list:['Chat nodes are missing.']}) addChatHistory(r.data.result, false);
} }
);
} else { } else {
setErrorData({title: 'Error sending message', list:['There are required fields not filled yet.']}) setErrorData({
title: "Error sending message",
list: ["There are required fields not filled yet."],
});
} }
} else { } else {
setErrorData({title: 'Error sending message', list:['The message cannot be empty.']}) setErrorData({
title: "Error sending message",
list: ["The message cannot be empty."],
});
} }
} }
@ -86,27 +104,28 @@ export default function Chat({flow, reactFlowInstance }:ChatType) {
leaveFrom="translate-y-0" leaveFrom="translate-y-0"
leaveTo="translate-y-96" leaveTo="translate-y-96"
> >
<div className="w-[400px] absolute bottom-0 right-6"> <div className="w-[340px] absolute bottom-0 right-6">
<div className="border dark:border-gray-700 h-full rounded-xl rounded-b-none bg-white dark:bg-gray-800 shadow"> <div className="border dark:border-gray-700 h-full rounded-xl rounded-b-none bg-white dark:bg-gray-800 shadow">
<div className="flex justify-between items-center px-5 py-3 border-b dark:border-b-gray-700"> <div onClick={() => {
<div className="flex gap-3 text-xl dark:text-white font-medium items-center"> setOpen(false);
<Bars3CenterLeftIcon className="h-8 w-8 mt-1" style={{color: nodeColors['chat']}} /> }} className="flex justify-between cursor-pointer items-center px-5 py-2 border-b dark:border-b-gray-700">
<div className="flex gap-3 text-lg dark:text-white font-medium items-center">
<Bars3CenterLeftIcon
className="h-5 w-5 mt-1"
style={{ color: nodeColors["chat"] }}
/>
Chat Chat
</div> </div>
<button
onClick={() => {
setOpen(false);
}}
>
<XMarkIcon className="h-6 w-6 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" />
</button>
</div> </div>
<div className="w-full h-[400px] flex gap-3 mb-auto overflow-y-auto scrollbar-hide flex-col bg-gray-50 dark:bg-gray-900 p-3 py-5"> <div className="w-full h-[400px] flex gap-3 mb-auto overflow-y-auto scrollbar-hide flex-col bg-gray-50 dark:bg-gray-900 p-3 py-5">
{chatHistory.map((c, i) => ( {chatHistory.map((c, i) => (
<div key={i}> <div key={i}>
{!c.isSend ? ( {!c.isSend ? (
<div className="w-full text-start"> <div className="w-full text-start">
<div style={{backgroundColor: nodeColors['chat']}} className="text-start inline-block text-white rounded-xl p-3 overflow-hidden w-fit max-w-[280px] px-5 text-sm font-normal rounded-tl-none"> <div
style={{ backgroundColor: nodeColors["chat"] }}
className="text-start inline-block text-white rounded-xl p-3 overflow-hidden w-fit max-w-[280px] px-5 text-sm font-normal rounded-tl-none"
>
{c.message} {c.message}
</div> </div>
</div> </div>
@ -125,8 +144,8 @@ export default function Chat({flow, reactFlowInstance }:ChatType) {
<div className="relative w-full mt-1 rounded-md shadow-sm"> <div className="relative w-full mt-1 rounded-md shadow-sm">
<input <input
onKeyDown={(event) => { onKeyDown={(event) => {
if(event.key==='Enter'){ if (event.key === "Enter") {
sendMessage() sendMessage();
} }
}} }}
type="text" type="text"
@ -138,9 +157,7 @@ export default function Chat({flow, reactFlowInstance }:ChatType) {
placeholder="Send a message..." placeholder="Send a message..."
/> />
<div className="absolute inset-y-0 right-0 flex items-center pr-3"> <div className="absolute inset-y-0 right-0 flex items-center pr-3">
<button <button onClick={() => sendMessage()}>
onClick={() => sendMessage()}
>
<PaperAirplaneIcon <PaperAirplaneIcon
className="h-5 w-5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" className="h-5 w-5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
aria-hidden="true" aria-hidden="true"
@ -170,7 +187,10 @@ export default function Chat({flow, reactFlowInstance }:ChatType) {
}} }}
> >
<div className="flex gap-3 text-lg font-medium items-center"> <div className="flex gap-3 text-lg font-medium items-center">
<Bars3CenterLeftIcon className="h-8 w-8 mt-1" style={{color: nodeColors['chat']}}/> <Bars3CenterLeftIcon
className="h-8 w-8 mt-1"
style={{ color: nodeColors["chat"] }}
/>
Chat Chat
</div> </div>
</button> </button>

View file

@ -16,12 +16,6 @@ export default function ExtraSidebar() {
useEffect(() => { useEffect(() => {
async function getTypes():Promise<void>{ async function getTypes():Promise<void>{
// 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. // Make an asynchronous API call to retrieve all data.
let result = await getAll(); let result = await getAll();
@ -41,8 +35,7 @@ export default function ExtraSidebar() {
}); });
}); });
return acc; return acc;
}, },{}
initialValue
) )
); );
} }
@ -58,7 +51,7 @@ export default function ExtraSidebar() {
} }
return ( return (
<div className="mt-4 w-full"> <div className="mt-1 w-full">
{Object.keys(data).map((d:keyof APIObjectType, i) => ( {Object.keys(data).map((d:keyof APIObjectType, i) => (
<DisclosureComponent <DisclosureComponent
key={i} key={i}
@ -88,69 +81,6 @@ export default function ExtraSidebar() {
</div> </div>
</DisclosureComponent> </DisclosureComponent>
))} ))}
<DisclosureComponent
button={{ title: nodeNames["chat"], Icon: nodeIcons["chat"] }}
>
<div className="p-2 flex flex-col gap-2">
<div>
<div
draggable
className={" cursor-grab border-l-8 rounded-l-md"}
style={{ borderLeftColor: nodeColors["chat"] }}
onDragStart={(event) =>
onDragStart(event, {
type: "chatOutput",
})
}
>
<div className="flex w-full justify-between text-sm px-4 py-3 items-center dark:border-gray-600 border-dashed border-gray-400 border-l-0 rounded-md rounded-l-none border-2">
<span className="text-black dark:text-white w-36 truncate">Chat Output</span>
<Bars2Icon className="w-6 h-6 text-gray-400 dark:text-gray-600" />
</div>
</div>
</div>
</div>
</DisclosureComponent>
<DisclosureComponent
button={{ title: nodeNames["advanced"], Icon: nodeIcons["advanced"] }}
>
<div className="p-2 flex flex-col gap-2">
<div>
<div
draggable
className={" cursor-grab border-l-8 rounded-l-md"}
style={{ borderLeftColor: nodeColors["advanced"] }}
onDragStart={(event) =>
onDragStart(event, {
type: "str",
})
}
>
<div className="flex w-full justify-between text-sm px-4 py-3 items-center border-dashed dark:border-gray-600 border-gray-400 border-l-0 rounded-md rounded-l-none border-2">
<span className="text-black dark:text-white w-36 truncate">String</span>
<Bars2Icon className="w-6 h-6 text-gray-400 dark:text-gray-600" />
</div>
</div>
</div>
<div>
<div
draggable
className={" cursor-grab border-l-8 rounded-l-md"}
style={{ borderLeftColor: nodeColors["advanced"] }}
onDragStart={(event) =>
onDragStart(event, {
type: "bool",
})
}
>
<div className="flex w-full justify-between text-sm px-4 py-3 items-center border-dashed dark:border-gray-600 border-gray-400 border-l-0 rounded-md rounded-l-none border-2">
<span className="text-black dark:text-white w-36 truncate">Boolean</span>
<Bars2Icon className="w-6 h-6 text-gray-400 dark:text-gray-600" />
</div>
</div>
</div>
</div>
</DisclosureComponent>
</div> </div>
); );
} }

View file

@ -14,10 +14,6 @@ import { locationContext } from "../../contexts/locationContext";
import ExtraSidebar from "./components/extraSidebarComponent"; import ExtraSidebar from "./components/extraSidebarComponent";
import Chat from "../../components/chatComponent"; import Chat from "../../components/chatComponent";
import GenericNode from "../../CustomNodes/GenericNode"; 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 { alertContext } from "../../contexts/alertContext";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { typesContext } from "../../contexts/typesContext"; import { typesContext } from "../../contexts/typesContext";
@ -31,10 +27,6 @@ import { APIClassType } from "../../types/api";
const nodeTypes = { const nodeTypes = {
genericNode: GenericNode, genericNode: GenericNode,
inputNode: InputNode,
chatInputNode: ChatInputNode,
chatOutputNode: ChatOutputNode,
booleanNode: BooleanNode,
}; };
var _ = require("lodash"); var _ = require("lodash");
@ -74,7 +66,7 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
//set extra sidebar //set extra sidebar
useEffect(() => { useEffect(() => {
setExtraComponent(<ExtraSidebar />); setExtraComponent(<ExtraSidebar />);
setExtraNavigation({ title: "Componets" }); setExtraNavigation({ title: "Components" });
}, [setExtraComponent, setExtraNavigation]); }, [setExtraComponent, setExtraNavigation]);
const onEdgesChangeMod = useCallback( const onEdgesChangeMod = useCallback(
@ -139,14 +131,7 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
// Create a new node object // Create a new node object
const newNode:NodeType = { const newNode:NodeType = {
id: newId, id: newId,
type: type: "genericNode",
data.type === "str"
? "inputNode"
: data.type === "chatOutput"
? "chatOutputNode"
: data.type === "bool"
? "booleanNode"
: "genericNode",
position, position,
data: { data: {
...data, ...data,