Fixed sidebar and added transitions on the nodes
This commit is contained in:
parent
12283981b9
commit
868356c11e
11 changed files with 239 additions and 122 deletions
|
|
@ -1,7 +1,6 @@
|
|||
import "reactflow/dist/style.css";
|
||||
import { useState, useRef, useEffect, useContext } from "react";
|
||||
import { ReactFlowProvider } from "reactflow";
|
||||
import "./CustomNodes/inputTextFolder/inputText.css";
|
||||
import "./App.css";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import ErrorAlert from "./alerts/error";
|
||||
|
|
|
|||
|
|
@ -1,17 +1,30 @@
|
|||
import { Transition } from "@headlessui/react";
|
||||
import { Handle, Position } from "reactflow";
|
||||
|
||||
export default function AgentNode({ data }) {
|
||||
console.log(data)
|
||||
console.log(data);
|
||||
return (
|
||||
<div onClick={data.delete} className="agent-node relative bg-white h-16 w-40 border rounded-sm solid border-black flex flex-col justify-center">
|
||||
<Handle type="source" position={Position.Left}></Handle>
|
||||
<label className="absolute cursor-grab text-sm -top-3 left-1 bg-white w-14 text-center">
|
||||
Agent
|
||||
</label>
|
||||
<div className="w-full h-min text-xs text-center">
|
||||
Agent data
|
||||
<Transition
|
||||
appear={true}
|
||||
show={true}
|
||||
enter="transition ease-out duration-100"
|
||||
enterFrom="transform opacity-0 scale-95"
|
||||
enterTo="transform opacity-100 scale-100"
|
||||
leave="transition ease-in duration-75"
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<div
|
||||
onClick={data.delete}
|
||||
className="agent-node relative bg-white h-16 w-40 border rounded-sm solid border-black flex flex-col justify-center"
|
||||
>
|
||||
<Handle type="source" position={Position.Left}></Handle>
|
||||
<label className="absolute cursor-grab text-sm -top-3 left-1 bg-white w-14 text-center">
|
||||
Agent
|
||||
</label>
|
||||
<div className="w-full h-min text-xs text-center">Agent data</div>
|
||||
<Handle type="target" position={Position.Right}></Handle>
|
||||
</div>
|
||||
<Handle type="target" position={Position.Right}></Handle>
|
||||
</div>
|
||||
</Transition>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,19 @@
|
|||
import { Transition } from "@headlessui/react";
|
||||
import { Handle, Position } from "reactflow";
|
||||
|
||||
export default function ChainNode({ data }) {
|
||||
console.log(data)
|
||||
return (
|
||||
<Transition
|
||||
appear={true}
|
||||
show={true}
|
||||
enter="transition ease-out duration-100"
|
||||
enterFrom="transform opacity-0 scale-95"
|
||||
enterTo="transform opacity-100 scale-100"
|
||||
leave="transition ease-in duration-75"
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<div onClick={data.delete} className="chain-node relative bg-white h-16 w-40 border rounded-sm solid border-black flex flex-col justify-center">
|
||||
<Handle type="source" position={Position.Left}></Handle>
|
||||
<label className="absolute cursor-grab text-sm -top-3 left-1 bg-white w-14 text-center">
|
||||
|
|
@ -13,5 +24,6 @@ export default function ChainNode({ data }) {
|
|||
</div>
|
||||
<Handle type="target" position={Position.Right}></Handle>
|
||||
</div>
|
||||
</Transition>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,32 @@
|
|||
import { Transition } from "@headlessui/react";
|
||||
import { Handle, Position } from "reactflow";
|
||||
|
||||
export default function ModelNode({ data }) {
|
||||
console.log(data)
|
||||
console.log(data);
|
||||
return (
|
||||
<div onClick={data.delete} className="model-node relative bg-white h-16 w-40 border rounded-sm solid border-black flex flex-col justify-center">
|
||||
<Handle type="source" position={Position.Left}></Handle>
|
||||
<label className="absolute cursor-grab text-sm -top-3 left-1 bg-white w-14 text-center">
|
||||
Model
|
||||
</label>
|
||||
<div className="w-full h-min text-xs text-center">
|
||||
{data.llm.model_name}
|
||||
<Transition
|
||||
appear={true}
|
||||
show={true}
|
||||
enter="transition ease-out duration-100"
|
||||
enterFrom="transform opacity-0 scale-95"
|
||||
enterTo="transform opacity-100 scale-100"
|
||||
leave="transition ease-in duration-75"
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<div
|
||||
onClick={data.delete}
|
||||
className="model-node relative bg-white h-16 w-40 border rounded-sm solid border-black flex flex-col justify-center"
|
||||
>
|
||||
<Handle type="source" position={Position.Left}></Handle>
|
||||
<label className="absolute cursor-grab text-sm -top-3 left-1 bg-white w-14 text-center">
|
||||
Model
|
||||
</label>
|
||||
<div className="w-full h-min text-xs text-center">
|
||||
{data.llm.model_name}
|
||||
</div>
|
||||
<Handle type="target" position={Position.Right}></Handle>
|
||||
</div>
|
||||
<Handle type="target" position={Position.Right}></Handle>
|
||||
</div>
|
||||
</Transition>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,36 @@
|
|||
import { Handle, Position } from "reactflow";
|
||||
import { useContext } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
|
||||
import { Transition } from "@headlessui/react";
|
||||
|
||||
export default function PromptNode({ data }) {
|
||||
const {openPopUp} = useContext(PopUpContext)
|
||||
const { openPopUp } = useContext(PopUpContext);
|
||||
return (
|
||||
<div
|
||||
onClick={()=>openPopUp(<div className="absolute top-1/2 left-1/2">teste</div>)}
|
||||
className="prompt-node relative bg-white h-16 w-40 border rounded-sm solid border-black flex flex-col justify-center"
|
||||
<Transition
|
||||
appear={true}
|
||||
show={true}
|
||||
enter="transition ease-out duration-100"
|
||||
enterFrom="transform opacity-0 scale-95"
|
||||
enterTo="transform opacity-100 scale-100"
|
||||
leave="transition ease-in duration-75"
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Handle type="source" position={Position.Left}></Handle>
|
||||
<label className="absolute cursor-grab text-sm -top-3 left-1 bg-white w-14 text-center">
|
||||
Prompt
|
||||
</label>
|
||||
<div className="w-full h-10 truncate bg-slate-50 text-xs">
|
||||
{data.template}
|
||||
<div
|
||||
onClick={() =>
|
||||
openPopUp(<div className="absolute top-1/2 left-1/2">teste</div>)
|
||||
}
|
||||
className="prompt-node relative bg-white h-16 w-40 border rounded-sm solid border-black flex flex-col justify-center"
|
||||
>
|
||||
<Handle type="source" position={Position.Left}></Handle>
|
||||
<label className="absolute cursor-grab text-sm -top-3 left-1 bg-white w-14 text-center">
|
||||
Prompt
|
||||
</label>
|
||||
<div className="w-full h-10 truncate bg-slate-50 text-xs">
|
||||
{data.template}
|
||||
</div>
|
||||
<Handle type="target" position={Position.Right}></Handle>
|
||||
</div>
|
||||
<Handle type="target" position={Position.Right}></Handle>
|
||||
</div>
|
||||
</Transition>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,30 @@
|
|||
import { Transition } from "@headlessui/react";
|
||||
import { Handle, Position } from "reactflow";
|
||||
|
||||
export default function ValidatorNode({ data }) {
|
||||
console.log(data)
|
||||
console.log(data);
|
||||
return (
|
||||
<div onClick={data.delete} className="validator-node relative bg-white h-16 w-40 border rounded-sm solid border-black flex flex-col justify-center">
|
||||
<Handle type="source" position={Position.Left}></Handle>
|
||||
<label className="absolute cursor-grab text-sm -top-3 left-1 bg-white w-14 text-center">
|
||||
Validator
|
||||
</label>
|
||||
<div className="w-full h-min text-xs text-center">
|
||||
validator data
|
||||
<Transition
|
||||
appear={true}
|
||||
show={true}
|
||||
enter="transition ease-out duration-100"
|
||||
enterFrom="transform opacity-0 scale-95"
|
||||
enterTo="transform opacity-100 scale-100"
|
||||
leave="transition ease-in duration-75"
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<div
|
||||
onClick={data.delete}
|
||||
className="validator-node relative bg-white h-16 w-40 border rounded-sm solid border-black flex flex-col justify-center"
|
||||
>
|
||||
<Handle type="source" position={Position.Left}></Handle>
|
||||
<label className="absolute cursor-grab text-sm -top-3 left-1 bg-white w-14 text-center">
|
||||
Validator
|
||||
</label>
|
||||
<div className="w-full h-min text-xs text-center">validator data</div>
|
||||
<Handle type="target" position={Position.Right}></Handle>
|
||||
</div>
|
||||
<Handle type="target" position={Position.Right}></Handle>
|
||||
</div>
|
||||
</Transition>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
import { useCallback } from 'react';
|
||||
import { Handle, Position } from 'reactflow';
|
||||
|
||||
|
||||
const handleStyle = {left:10};
|
||||
|
||||
export default function TextUpdaterNode({data})
|
||||
{
|
||||
const onChange = useCallback((evt)=>{
|
||||
console.log(evt.target.value)
|
||||
},[])
|
||||
|
||||
|
||||
return (
|
||||
<div className="text-updater-node">
|
||||
<Handle type='target' position={Position.Top}/>
|
||||
<div>
|
||||
<label htmlFor='text'>Text:</label>
|
||||
<input id="text" name="text" onChange={onChange}></input>
|
||||
</div>
|
||||
<Handle type='source' id='a' position={Position.Bottom} style={handleStyle}/>
|
||||
<Handle type='source' id='b' position={Position.Bottom}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
.text-updater-node {
|
||||
height: 50px;
|
||||
border: 1px solid black;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.text-updater-node label {
|
||||
display: block;
|
||||
color: #777;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import {
|
||||
CpuChipIcon,
|
||||
PlusIcon,
|
||||
ChevronRightIcon,
|
||||
ArrowPathIcon,
|
||||
BoltIcon,
|
||||
ChevronDoubleRightIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { Disclosure } from "@headlessui/react";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function DisclosureComponent({
|
||||
button: { title, Icon, Modal = null, buttons = [] },
|
||||
children,
|
||||
}) {
|
||||
return (
|
||||
<Disclosure as="div" key={title}>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<div className="select-none bg-gray-50 w-full flex justify-between items-center -mt-px px-3 py-2 border border-gray-200">
|
||||
<div className="flex gap-4">
|
||||
<Icon className="w-6 text-gray-800" />
|
||||
<span className="flex items-center text-sm text-gray-800 font-medium">
|
||||
{title}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
{buttons.map((x, index)=>(
|
||||
<button key={index} onClick={x.onClick}>
|
||||
{x.Icon}
|
||||
</button>
|
||||
))}
|
||||
<Disclosure.Button as="button">
|
||||
<ChevronRightIcon
|
||||
className={`${
|
||||
open ? "rotate-90 transform" : ""
|
||||
} h-5 w-5 text-gray-800`}
|
||||
/>
|
||||
</Disclosure.Button>
|
||||
</div>
|
||||
</div>
|
||||
<Disclosure.Panel as="div" className="-mt-px">
|
||||
{children}
|
||||
</Disclosure.Panel>
|
||||
</>
|
||||
)}
|
||||
</Disclosure>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,39 +1,85 @@
|
|||
import { Bars2Icon, CommandLineIcon, LightBulbIcon, LinkIcon, RocketLaunchIcon, ShieldCheckIcon, ViewColumnsIcon } from "@heroicons/react/24/outline";
|
||||
import { llm_chain } from "../../../../data_assets/llm_chain";
|
||||
import { prompt } from "../../../../data_assets/prompt";
|
||||
import DisclosureComponent from "../DisclosureComponent";
|
||||
|
||||
|
||||
export function ExtraSidebar(){
|
||||
|
||||
function onDragStart(event:React.DragEvent<any>,nodeType){
|
||||
let json;
|
||||
event.dataTransfer.setData('application/reactflow',nodeType)
|
||||
event.dataTransfer.effectAllowed = 'move'
|
||||
if(nodeType==="promptNode"){
|
||||
json = JSON.stringify(prompt)
|
||||
}
|
||||
if(nodeType==="modelNode"){
|
||||
json = JSON.stringify(llm_chain)
|
||||
}
|
||||
if(nodeType==="chainNode"){
|
||||
json = JSON.stringify({content:""})
|
||||
}
|
||||
if(nodeType==="agentNode"){
|
||||
json = JSON.stringify({content:""})
|
||||
}
|
||||
if(nodeType==="validatorNode"){
|
||||
json = JSON.stringify({content:""})
|
||||
}
|
||||
event.dataTransfer.setData('json',json);
|
||||
export function ExtraSidebar() {
|
||||
function onDragStart(event: React.DragEvent<any>, nodeType) {
|
||||
let json;
|
||||
event.dataTransfer.setData("application/reactflow", nodeType);
|
||||
event.dataTransfer.effectAllowed = "move";
|
||||
if (nodeType === "promptNode") {
|
||||
json = JSON.stringify(prompt);
|
||||
}
|
||||
if (nodeType === "modelNode") {
|
||||
json = JSON.stringify(llm_chain);
|
||||
}
|
||||
if (nodeType === "chainNode") {
|
||||
json = JSON.stringify({ content: "" });
|
||||
}
|
||||
if (nodeType === "agentNode") {
|
||||
json = JSON.stringify({ content: "" });
|
||||
}
|
||||
if (nodeType === "validatorNode") {
|
||||
json = JSON.stringify({ content: "" });
|
||||
}
|
||||
event.dataTransfer.setData("json", json);
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="h-full w-48 bg-slate-200 flex flex-col">
|
||||
<div draggable className="w-full text-center border border-black cursor-grab" onDragStart={(event)=>onDragStart(event,'promptNode')}> Prompt Node</div>
|
||||
<div draggable className="w-full text-center border border-black cursor-grab" onDragStart={(event)=>onDragStart(event,'modelNode')}> Model Node</div>
|
||||
<div draggable className="w-full text-center border border-black cursor-grab" onDragStart={(event)=>onDragStart(event,'chainNode')}> Chain Node</div>
|
||||
<div draggable className="w-full text-center border border-black cursor-grab" onDragStart={(event)=>onDragStart(event,'agentNode')}> Agent Node</div>
|
||||
<div draggable className="w-full text-center border border-black cursor-grab" onDragStart={(event)=>onDragStart(event,'validatorNode')}> Validator Node</div>
|
||||
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<DisclosureComponent button={{ title: "Prompts", Icon: CommandLineIcon }}>
|
||||
<div
|
||||
draggable
|
||||
className="flex justify-between text-sm p-4 items-center h-12 m-2 border-dashed border-gray-400 rounded-md border-2 cursor-grab"
|
||||
onDragStart={(event) => onDragStart(event, "promptNode")}
|
||||
>
|
||||
<span className="text-black">Prompt</span>
|
||||
<Bars2Icon className="w-6 text-gray-400" />
|
||||
</div>
|
||||
</DisclosureComponent>
|
||||
<DisclosureComponent button={{ title: "Models", Icon: LightBulbIcon }}>
|
||||
<div
|
||||
draggable
|
||||
className="flex justify-between text-sm p-4 items-center h-12 m-2 border-dashed border-gray-400 rounded-md border-2 cursor-grab"
|
||||
onDragStart={(event) => onDragStart(event, "modelNode")}
|
||||
>
|
||||
<span className="text-black">Model</span>
|
||||
<Bars2Icon className="w-6 text-gray-400" />
|
||||
</div>
|
||||
</DisclosureComponent>
|
||||
<DisclosureComponent button={{ title: "Chains", Icon: LinkIcon }}>
|
||||
<div
|
||||
draggable
|
||||
className="flex justify-between text-sm p-4 items-center h-12 m-2 border-dashed border-gray-400 rounded-md border-2 cursor-grab"
|
||||
onDragStart={(event) => onDragStart(event, "chainNode")}
|
||||
>
|
||||
<span className="text-black">Chain</span>
|
||||
<Bars2Icon className="w-6 text-gray-400" />
|
||||
</div>
|
||||
</DisclosureComponent>
|
||||
<DisclosureComponent button={{ title: "Agents", Icon: RocketLaunchIcon }}>
|
||||
<div
|
||||
draggable
|
||||
className="flex justify-between text-sm p-4 items-center h-12 m-2 border-dashed border-gray-400 rounded-md border-2 cursor-grab"
|
||||
onDragStart={(event) => onDragStart(event, "agentNode")}
|
||||
>
|
||||
<span className="text-black">Agent</span>
|
||||
<Bars2Icon className="w-6 text-gray-400" />
|
||||
</div>
|
||||
</DisclosureComponent>
|
||||
<DisclosureComponent
|
||||
button={{ title: "Validators", Icon: ShieldCheckIcon }}
|
||||
>
|
||||
<div
|
||||
draggable
|
||||
className="flex justify-between text-sm p-4 items-center h-12 m-2 border-dashed border-gray-400 rounded-md border-2 cursor-grab"
|
||||
onDragStart={(event) => onDragStart(event, "validatorNode")}
|
||||
>
|
||||
<span className="text-black">Validator</span>
|
||||
<Bars2Icon className="w-6 text-gray-400" />
|
||||
</div>
|
||||
</DisclosureComponent>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import ReactFlow, {
|
|||
useEdgesState,
|
||||
useNodesState,
|
||||
} from "reactflow";
|
||||
import TextUpdaterNode from "../../CustomNodes/inputTextFolder";
|
||||
import PromptNode from "../../CustomNodes/PromptNode";
|
||||
import ModelNode from "../../CustomNodes/ModelNode";
|
||||
import { locationContext } from "../../contexts/locationContext";
|
||||
|
|
@ -16,7 +15,6 @@ import ChainNode from "../../CustomNodes/ChainNode";
|
|||
import ValidatorNode from "../../CustomNodes/ValidatorNode";
|
||||
|
||||
const nodeTypes = {
|
||||
textUpdater: TextUpdaterNode,
|
||||
promptNode: PromptNode,
|
||||
modelNode: ModelNode,
|
||||
chainNode: ChainNode,
|
||||
|
|
@ -37,10 +35,11 @@ export default function FlowPage() {
|
|||
|
||||
const getId = () => `dndnode_${id++}`;
|
||||
|
||||
const { setExtraComponent } = useContext(locationContext);
|
||||
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
||||
|
||||
useEffect(() => {
|
||||
setExtraComponent(ExtraSidebar);
|
||||
setExtraNavigation({title: "Nodes"})
|
||||
}, []);
|
||||
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue