Merge branch 'uiRevision' into dev
This commit is contained in:
commit
1d2a421813
9 changed files with 48 additions and 14 deletions
|
|
@ -4,7 +4,7 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Document</title>
|
<title>LangFLow</title>
|
||||||
</head>
|
</head>
|
||||||
<body id='body' style="width: 100%; height:100%">
|
<body id='body' style="width: 100%; height:100%">
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,9 @@ export default function ParameterComponent({
|
||||||
{title}
|
{title}
|
||||||
<span className="text-red-600">{required ? " *" : ""}</span>
|
<span className="text-red-600">{required ? " *" : ""}</span>
|
||||||
</div>
|
</div>
|
||||||
|
{left && (type === "str" || type === "bool" || type === "float") ?
|
||||||
|
<></>
|
||||||
|
:
|
||||||
<Tooltip title={tooltipTitle + (required ? " (required)" : "")}>
|
<Tooltip title={tooltipTitle + (required ? " (required)" : "")}>
|
||||||
<Handle
|
<Handle
|
||||||
type={left ? "target" : "source"}
|
type={left ? "target" : "source"}
|
||||||
|
|
@ -62,10 +65,7 @@ export default function ParameterComponent({
|
||||||
}
|
}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
left ? "-ml-0.5 " : "-mr-0.5 ",
|
left ? "-ml-0.5 " : "-mr-0.5 ",
|
||||||
"w-3 h-3 rounded-full border-2 bg-white dark:bg-gray-800",
|
"w-3 h-3 rounded-full border-2 bg-white dark:bg-gray-800"
|
||||||
left && (type === "str" || type === "bool" || type === "float")
|
|
||||||
? "hidden"
|
|
||||||
: ""
|
|
||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
borderColor: color,
|
borderColor: color,
|
||||||
|
|
@ -73,6 +73,8 @@ export default function ParameterComponent({
|
||||||
}}
|
}}
|
||||||
></Handle>
|
></Handle>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
}
|
||||||
|
|
||||||
{left === true && type === "str" ? (
|
{left === true && type === "str" ? (
|
||||||
<div className="mt-2 w-full">
|
<div className="mt-2 w-full">
|
||||||
{data.node.template[name].list ? (
|
{data.node.template[name].list ? (
|
||||||
|
|
@ -99,6 +101,7 @@ export default function ParameterComponent({
|
||||||
) : (
|
) : (
|
||||||
<InputComponent
|
<InputComponent
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
password={data.node.template[name].password ?? true}
|
||||||
value={data.node.template[name].value ?? ""}
|
value={data.node.template[name].value ?? ""}
|
||||||
onChange={(t) => {
|
onChange={(t) => {
|
||||||
data.node.template[name].value = t;
|
data.node.template[name].value = t;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import {
|
||||||
PaperAirplaneIcon,
|
PaperAirplaneIcon,
|
||||||
XMarkIcon,
|
XMarkIcon,
|
||||||
} from "@heroicons/react/24/outline";
|
} from "@heroicons/react/24/outline";
|
||||||
import { useContext, useEffect, useRef, useState } from "react";
|
import { MouseEventHandler, useContext, useEffect, useRef, useState } from "react";
|
||||||
import { sendAll } from "../../controllers/NodesServices";
|
import { sendAll } from "../../controllers/NodesServices";
|
||||||
import { alertContext } from "../../contexts/alertContext";
|
import { alertContext } from "../../contexts/alertContext";
|
||||||
import { classNames, nodeColors } from "../../utils";
|
import { classNames, nodeColors } from "../../utils";
|
||||||
|
|
@ -89,7 +89,7 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) {
|
||||||
sendAll({ ...reactFlowInstance.toObject(), message, chatHistory })
|
sendAll({ ...reactFlowInstance.toObject(), message, chatHistory })
|
||||||
.then((r) => {
|
.then((r) => {
|
||||||
console.log(r.data);
|
console.log(r.data);
|
||||||
addChatHistory(r.data.result, false,r.data.thought);
|
addChatHistory(r.data.result, false, r.data.thought);
|
||||||
setLockChat(false);
|
setLockChat(false);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
|
@ -109,6 +109,10 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function clearChat() {
|
||||||
|
setChatHistory([])
|
||||||
|
updateFlow({ ..._.cloneDeep(flow), chat: []});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -137,10 +141,18 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) {
|
||||||
/>
|
/>
|
||||||
Chat
|
Chat
|
||||||
</div>
|
</div>
|
||||||
|
<button className="hover:text-blue-500"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
clearChat();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
clear
|
||||||
|
</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) => (
|
||||||
<ChatMessage chat={c} key={i}/>
|
<ChatMessage chat={c} key={i} />
|
||||||
))}
|
))}
|
||||||
<div ref={ref}></div>
|
<div ref={ref}></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -154,7 +166,7 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) {
|
||||||
}}
|
}}
|
||||||
type="text"
|
type="text"
|
||||||
disabled={lockChat}
|
disabled={lockChat}
|
||||||
value={lockChat?"Thinking...": chatValue}
|
value={lockChat ? "Thinking..." : chatValue}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setChatValue(e.target.value);
|
setChatValue(e.target.value);
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { InputComponentType } from "../../types/components";
|
import { InputComponentType } from "../../types/components";
|
||||||
|
|
||||||
export default function InputComponent({value, onChange, disabled}: InputComponentType){
|
export default function InputComponent({value, onChange, disabled, password}: InputComponentType){
|
||||||
const [myValue, setMyValue] = useState(value ?? "");
|
const [myValue, setMyValue] = useState(value ?? "");
|
||||||
useEffect(()=> {
|
useEffect(()=> {
|
||||||
if(disabled){
|
if(disabled){
|
||||||
|
|
@ -12,7 +12,7 @@ export default function InputComponent({value, onChange, disabled}: InputCompone
|
||||||
return (
|
return (
|
||||||
<div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}>
|
<div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type={password ? "password" : "text"}
|
||||||
value={myValue}
|
value={myValue}
|
||||||
className={"block w-full form-input dark:bg-gray-900 dark:border-gray-600 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + (disabled ? " bg-gray-200 dark:bg-gray-700" : "")}
|
className={"block w-full form-input dark:bg-gray-900 dark:border-gray-600 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" + (disabled ? " bg-gray-200 dark:bg-gray-700" : "")}
|
||||||
placeholder="Type a text"
|
placeholder="Type a text"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { createContext, useEffect, useState, useRef, ReactNode } from "react";
|
import { createContext, useEffect, useState, useRef, ReactNode } from "react";
|
||||||
import { FlowType } from "../types/flow";
|
import { FlowType } from "../types/flow";
|
||||||
import { TabsContextType } from "../types/tabs";
|
import { TabsContextType } from "../types/tabs";
|
||||||
|
import { normalCaseToSnakeCase } from "../utils";
|
||||||
|
|
||||||
const TabsContextInitialValue: TabsContextType = {
|
const TabsContextInitialValue: TabsContextType = {
|
||||||
tabIndex: 0,
|
tabIndex: 0,
|
||||||
|
|
@ -61,7 +62,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
||||||
// create a link element and set its properties
|
// create a link element and set its properties
|
||||||
const link = document.createElement("a");
|
const link = document.createElement("a");
|
||||||
link.href = jsonString;
|
link.href = jsonString;
|
||||||
link.download = `${flows[tabIndex].name}.json`;
|
link.download = `${normalCaseToSnakeCase(flows[tabIndex].name)}.json`;
|
||||||
|
|
||||||
// simulate a click on the link element to trigger the download
|
// simulate a click on the link element to trigger the download
|
||||||
link.click();
|
link.click();
|
||||||
|
|
@ -124,7 +125,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
||||||
|
|
||||||
// Create a new flow with a default name if no flow is provided.
|
// Create a new flow with a default name if no flow is provided.
|
||||||
let newFlow: FlowType = {
|
let newFlow: FlowType = {
|
||||||
name: flow ? flow.name : "flow" + id,
|
name: flow ? flow.name : "New Flow " + id,
|
||||||
id: id.toString(),
|
id: id.toString(),
|
||||||
data,
|
data,
|
||||||
chat: flow ? flow.chat : [],
|
chat: flow ? flow.chat : [],
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ export function TypesProvider({ children }:{children:ReactNode}) {
|
||||||
reactFlowInstance.setNodes(
|
reactFlowInstance.setNodes(
|
||||||
reactFlowInstance.getNodes().filter((n:Node) => n.id !== idx)
|
reactFlowInstance.getNodes().filter((n:Node) => n.id !== idx)
|
||||||
);
|
);
|
||||||
|
reactFlowInstance.setEdges(reactFlowInstance.getEdges().filter((ns) => ns.source !== idx && ns.target !== idx));
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<typesContext.Provider
|
<typesContext.Provider
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,11 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
|
||||||
// Specify dependencies for useCallback
|
// Specify dependencies for useCallback
|
||||||
[incrementNodeId, reactFlowInstance, setErrorData, setNodes]
|
[incrementNodeId, reactFlowInstance, setErrorData, setNodes]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const onDelete = (mynodes) => {
|
||||||
|
setEdges(edges.filter((ns) => !nodes.some((n) => ns.source === n.id || ns.target === n.id)));
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full" ref={reactFlowWrapper}>
|
<div className="w-full h-full" ref={reactFlowWrapper}>
|
||||||
|
|
@ -174,6 +178,7 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
|
||||||
connectionLineComponent={ConnectionLineComponent}
|
connectionLineComponent={ConnectionLineComponent}
|
||||||
onDragOver={onDragOver}
|
onDragOver={onDragOver}
|
||||||
onDrop={onDrop}
|
onDrop={onDrop}
|
||||||
|
onNodesDelete={onDelete}
|
||||||
>
|
>
|
||||||
<Background className="dark:bg-gray-900"/>
|
<Background className="dark:bg-gray-900"/>
|
||||||
<Controls className="[&>button]:text-black [&>button]:dark:bg-gray-800 hover:[&>button]:dark:bg-gray-700 [&>button]:dark:text-gray-400 [&>button]:dark:fill-gray-400 [&>button]:dark:border-gray-600">
|
<Controls className="[&>button]:text-black [&>button]:dark:bg-gray-800 hover:[&>button]:dark:bg-gray-700 [&>button]:dark:text-gray-400 [&>button]:dark:fill-gray-400 [&>button]:dark:border-gray-600">
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ export type InputComponentType = {
|
||||||
value: string;
|
value: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
onChange: (value: string) => void;
|
onChange: (value: string) => void;
|
||||||
|
password: boolean;
|
||||||
};
|
};
|
||||||
export type ToggleComponentType = {
|
export type ToggleComponentType = {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
|
|
||||||
|
|
@ -286,6 +286,18 @@ export function snakeToNormalCase(str: string) {
|
||||||
.join(" ");
|
.join(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function normalCaseToSnakeCase(str:string){
|
||||||
|
return str
|
||||||
|
.split(" ")
|
||||||
|
.map((word, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
return word[0].toUpperCase() + word.slice(1).toLowerCase();
|
||||||
|
}
|
||||||
|
return word.toLowerCase();
|
||||||
|
})
|
||||||
|
.join("_");
|
||||||
|
}
|
||||||
|
|
||||||
export function roundNumber(x:number, decimals:number) {
|
export function roundNumber(x:number, decimals:number) {
|
||||||
return Math.round(x * Math.pow(10, decimals)) / Math.pow(10, decimals);
|
return Math.round(x * Math.pow(10, decimals)) / Math.pow(10, decimals);
|
||||||
}
|
}
|
||||||
|
|
@ -303,7 +315,6 @@ export function isValidConnection(
|
||||||
{ source, target, sourceHandle, targetHandle }:Connection,
|
{ source, target, sourceHandle, targetHandle }:Connection,
|
||||||
reactFlowInstance:ReactFlowInstance
|
reactFlowInstance:ReactFlowInstance
|
||||||
) {
|
) {
|
||||||
console.log(target)
|
|
||||||
if (
|
if (
|
||||||
sourceHandle.split('|')[0] === targetHandle.split("|")[0] ||
|
sourceHandle.split('|')[0] === targetHandle.split("|")[0] ||
|
||||||
sourceHandle.split('|').slice(2).some((t) => t === targetHandle.split("|")[0]) ||
|
sourceHandle.split('|').slice(2).some((t) => t === targetHandle.split("|")[0]) ||
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue