refactor(codeAreaComponent): change template to nodeClass and setTemplate to setNodeClass to improve semantics refactor(API): change UpdateTemplate function parameter from template to nodeClass to improve semantics refactor(codeAreaModal): change template to nodeClass and setTemplate to setNodeClass to improve semantics and fix bug refactor(types): add APIClassType to import and change APITemplateType to import in relevant files to improve semantics
268 lines
8.9 KiB
TypeScript
268 lines
8.9 KiB
TypeScript
import { Handle, Position, useUpdateNodeInternals } from "reactflow";
|
|
import {
|
|
classNames,
|
|
groupByFamily,
|
|
isValidConnection,
|
|
} from "../../../../utils";
|
|
import { useContext, useEffect, useRef, useState } from "react";
|
|
import InputComponent from "../../../../components/inputComponent";
|
|
import InputListComponent from "../../../../components/inputListComponent";
|
|
import TextAreaComponent from "../../../../components/textAreaComponent";
|
|
import { typesContext } from "../../../../contexts/typesContext";
|
|
import { ParameterComponentType } from "../../../../types/components";
|
|
import FloatComponent from "../../../../components/floatComponent";
|
|
import Dropdown from "../../../../components/dropdownComponent";
|
|
import CodeAreaComponent from "../../../../components/codeAreaComponent";
|
|
import InputFileComponent from "../../../../components/inputFileComponent";
|
|
import { TabsContext } from "../../../../contexts/tabsContext";
|
|
import IntComponent from "../../../../components/intComponent";
|
|
import PromptAreaComponent from "../../../../components/promptComponent";
|
|
import { nodeNames, nodeIcons } from "../../../../utils";
|
|
import React from "react";
|
|
import { nodeColors } from "../../../../utils";
|
|
import ShadTooltip from "../../../../components/ShadTooltipComponent";
|
|
import { PopUpContext } from "../../../../contexts/popUpContext";
|
|
import ToggleShadComponent from "../../../../components/toggleShadComponent";
|
|
|
|
export default function ParameterComponent({
|
|
left,
|
|
id,
|
|
data,
|
|
tooltipTitle,
|
|
title,
|
|
color,
|
|
type,
|
|
name = "",
|
|
required = false,
|
|
}: ParameterComponentType) {
|
|
const ref = useRef(null);
|
|
const refHtml = useRef(null);
|
|
const updateNodeInternals = useUpdateNodeInternals();
|
|
const [position, setPosition] = useState(0);
|
|
const { closePopUp } = useContext(PopUpContext);
|
|
const { setTabsState, tabId } = useContext(TabsContext);
|
|
|
|
useEffect(() => {
|
|
if (ref.current && ref.current.offsetTop && ref.current.clientHeight) {
|
|
setPosition(ref.current.offsetTop + ref.current.clientHeight / 2);
|
|
updateNodeInternals(data.id);
|
|
}
|
|
}, [data.id, ref, ref.current, ref.current?.offsetTop, updateNodeInternals]);
|
|
|
|
useEffect(() => {
|
|
updateNodeInternals(data.id);
|
|
}, [data.id, position, updateNodeInternals]);
|
|
|
|
const [enabled, setEnabled] = useState(
|
|
data.node.template[name]?.value ?? false
|
|
);
|
|
|
|
useEffect(() => {}, [closePopUp, data.node.template]);
|
|
|
|
const { reactFlowInstance } = useContext(typesContext);
|
|
let disabled =
|
|
reactFlowInstance?.getEdges().some((e) => e.targetHandle === id) ?? false;
|
|
const [myData, setMyData] = useState(useContext(typesContext).data);
|
|
|
|
const handleOnNewValue = (newValue: any) => {
|
|
data.node.template[name].value = newValue;
|
|
// Set state to pending
|
|
setTabsState((prev) => {
|
|
return {
|
|
...prev,
|
|
[tabId]: {
|
|
isPending: true,
|
|
},
|
|
};
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
const groupedObj = groupByFamily(myData, tooltipTitle);
|
|
|
|
refHtml.current = groupedObj.map((item, i) => (
|
|
<span
|
|
key={i}
|
|
className={classNames(
|
|
i > 0 ? "items-center flex mt-3" : "items-center flex"
|
|
)}
|
|
>
|
|
<div
|
|
className="h-5 w-5"
|
|
style={{
|
|
color: nodeColors[item.family],
|
|
}}
|
|
>
|
|
{React.createElement(nodeIcons[item.family])}
|
|
</div>
|
|
<span className="ps-2 text-gray-950">
|
|
{nodeNames[item.family] ?? ""}{" "}
|
|
<span className={classNames(left ? "hidden" : "")}>
|
|
{" "}
|
|
-
|
|
{item.type.split(", ").length > 2
|
|
? item.type.split(", ").map((el, i) => (
|
|
<>
|
|
<span key={i}>
|
|
{i == item.type.split(", ").length - 1
|
|
? el
|
|
: (el += `, `)}
|
|
</span>
|
|
{i % 2 == 0 && i > 0 && <br></br>}
|
|
</>
|
|
))
|
|
: item.type}
|
|
</span>
|
|
</span>
|
|
</span>
|
|
));
|
|
}, [tooltipTitle]);
|
|
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
className="w-full flex flex-wrap justify-between items-center bg-muted dark:bg-gray-800 dark:text-white mt-1 px-5 py-2"
|
|
>
|
|
<>
|
|
<div className={"text-sm truncate w-full " + (left ? "" : "text-end")}>
|
|
{title}
|
|
<span className="text-red-600">{required ? " *" : ""}</span>
|
|
</div>
|
|
{left &&
|
|
(type === "str" ||
|
|
type === "bool" ||
|
|
type === "float" ||
|
|
type === "code" ||
|
|
type === "prompt" ||
|
|
type === "file" ||
|
|
type === "int") ? (
|
|
<></>
|
|
) : (
|
|
<ShadTooltip
|
|
delayDuration={0}
|
|
content={refHtml.current}
|
|
side={left ? "left" : "right"}
|
|
open={refHtml?.current?.length > 0}
|
|
>
|
|
<Handle
|
|
type={left ? "target" : "source"}
|
|
position={left ? Position.Left : Position.Right}
|
|
id={id}
|
|
isValidConnection={(connection) =>
|
|
isValidConnection(connection, reactFlowInstance)
|
|
}
|
|
className={classNames(
|
|
left ? "-ml-0.5 " : "-mr-0.5 ",
|
|
"w-3 h-3 rounded-full border-2 bg-white dark:bg-gray-800"
|
|
)}
|
|
style={{
|
|
borderColor: color,
|
|
top: position,
|
|
}}
|
|
></Handle>
|
|
</ShadTooltip>
|
|
)}
|
|
|
|
{left === true &&
|
|
type === "str" &&
|
|
!data.node.template[name].options ? (
|
|
<div className="mt-2 w-full">
|
|
{data.node.template[name].list ? (
|
|
<InputListComponent
|
|
disabled={disabled}
|
|
value={
|
|
!data.node.template[name].value ||
|
|
data.node.template[name].value === ""
|
|
? [""]
|
|
: data.node.template[name].value
|
|
}
|
|
onChange={handleOnNewValue}
|
|
/>
|
|
) : data.node.template[name].multiline ? (
|
|
<TextAreaComponent
|
|
disabled={disabled}
|
|
value={data.node.template[name].value ?? ""}
|
|
onChange={handleOnNewValue}
|
|
/>
|
|
) : (
|
|
<InputComponent
|
|
disabled={disabled}
|
|
disableCopyPaste={true}
|
|
password={data.node.template[name].password ?? false}
|
|
value={data.node.template[name].value ?? ""}
|
|
onChange={handleOnNewValue}
|
|
/>
|
|
)}
|
|
</div>
|
|
) : left === true && type === "bool" ? (
|
|
<div className="mt-2">
|
|
<ToggleShadComponent
|
|
disabled={disabled}
|
|
enabled={enabled}
|
|
setEnabled={(t) => {
|
|
handleOnNewValue(t);
|
|
setEnabled(t);
|
|
}}
|
|
size="large"
|
|
/>
|
|
</div>
|
|
) : left === true && type === "float" ? (
|
|
<div className="mt-2 w-full">
|
|
<FloatComponent
|
|
disabled={disabled}
|
|
disableCopyPaste={true}
|
|
value={data.node.template[name].value ?? ""}
|
|
onChange={handleOnNewValue}
|
|
/>
|
|
</div>
|
|
) : left === true &&
|
|
type === "str" &&
|
|
data.node.template[name].options ? (
|
|
<div className="w-full">
|
|
<Dropdown
|
|
options={data.node.template[name].options}
|
|
onSelect={handleOnNewValue}
|
|
value={data.node.template[name].value ?? "Choose an option"}
|
|
></Dropdown>
|
|
</div>
|
|
) : left === true && type === "code" ? (
|
|
<CodeAreaComponent
|
|
setNodeClass={(nodeClass)=>{data.node = nodeClass}}
|
|
nodeClass={data.node}
|
|
disabled={disabled}
|
|
value={data.node.template[name].value ?? ""}
|
|
onChange={handleOnNewValue}
|
|
/>
|
|
) : left === true && type === "file" ? (
|
|
<InputFileComponent
|
|
disabled={disabled}
|
|
value={data.node.template[name].value ?? ""}
|
|
onChange={handleOnNewValue}
|
|
fileTypes={data.node.template[name].fileTypes}
|
|
suffixes={data.node.template[name].suffixes}
|
|
onFileChange={(t: string) => {
|
|
data.node.template[name].content = t;
|
|
}}
|
|
></InputFileComponent>
|
|
) : left === true && type === "int" ? (
|
|
<div className="mt-2 w-full">
|
|
<IntComponent
|
|
disabled={disabled}
|
|
disableCopyPaste={true}
|
|
value={data.node.template[name].value ?? ""}
|
|
onChange={handleOnNewValue}
|
|
/>
|
|
</div>
|
|
) : left === true && type === "prompt" ? (
|
|
<PromptAreaComponent
|
|
disabled={disabled}
|
|
value={data.node.template[name].value ?? ""}
|
|
onChange={handleOnNewValue}
|
|
/>
|
|
) : (
|
|
<></>
|
|
)}
|
|
</>
|
|
</div>
|
|
);
|
|
}
|