Inputs and outputs lines implemented at the generic node
This commit is contained in:
parent
d34e7890c3
commit
61e56659aa
2 changed files with 101 additions and 34 deletions
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { Handle, Position, useUpdateNodeInternals } from "reactflow";
|
||||||
|
import Tooltip from "../../../../components/TooltipComponent";
|
||||||
|
import {
|
||||||
|
isValidConnection,
|
||||||
|
nodeColors,
|
||||||
|
snakeToNormalCase,
|
||||||
|
} from "../../../../utils";
|
||||||
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
export default function ParameterComponent({
|
||||||
|
left,
|
||||||
|
id,
|
||||||
|
data,
|
||||||
|
tooltipTitle,
|
||||||
|
title,
|
||||||
|
color,
|
||||||
|
}) {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const updateNodeInternals = useUpdateNodeInternals();
|
||||||
|
const [position, setPosition] = useState(0);
|
||||||
|
useEffect(() => {
|
||||||
|
if (ref.current && ref.current.offsetTop && ref.current.clientHeight) {
|
||||||
|
setPosition(ref.current.offsetTop + (ref.current.clientHeight / 2));
|
||||||
|
updateNodeInternals(data.id);
|
||||||
|
}
|
||||||
|
}, [data.id, ref, updateNodeInternals]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
updateNodeInternals(data.id);
|
||||||
|
}, [data.id, position, updateNodeInternals])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={ref} className="w-full bg-gray-50 mt-1 px-5 py-2">
|
||||||
|
<>
|
||||||
|
<div className="text-sm truncate">{title}</div>
|
||||||
|
<Tooltip title={tooltipTitle}>
|
||||||
|
<Handle
|
||||||
|
type={left ? "source" : "target"}
|
||||||
|
position={left ? Position.Left : Position.Right}
|
||||||
|
id={id}
|
||||||
|
isValidConnection={(connection) =>
|
||||||
|
isValidConnection(data, connection)
|
||||||
|
}
|
||||||
|
className={(left ? "-ml-0.5 " : "-mr-0.5 ") +"w-3 h-3 rounded-full border-2 bg-white"}
|
||||||
|
style={{
|
||||||
|
borderColor: color,
|
||||||
|
top: position,
|
||||||
|
}}
|
||||||
|
></Handle>
|
||||||
|
</Tooltip>
|
||||||
|
</>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -6,60 +6,73 @@ import {
|
||||||
import { Handle, Position } from "reactflow";
|
import { Handle, Position } from "reactflow";
|
||||||
import Dropdown from "../../components/dropdownComponent";
|
import Dropdown from "../../components/dropdownComponent";
|
||||||
import Input from "../../components/inputComponent";
|
import Input from "../../components/inputComponent";
|
||||||
import { isValidConnection, nodeColors, nodeIcons, snakeToNormalCase } from "../../utils";
|
import {
|
||||||
|
isValidConnection,
|
||||||
|
nodeColors,
|
||||||
|
nodeIcons,
|
||||||
|
snakeToNormalCase,
|
||||||
|
} from "../../utils";
|
||||||
import Tooltip from "../../components/TooltipComponent";
|
import Tooltip from "../../components/TooltipComponent";
|
||||||
import { useEffect } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
import ParameterComponent from "./components/parameterComponent";
|
||||||
|
|
||||||
export default function GenericNode({ data }) {
|
export default function GenericNode({ data }) {
|
||||||
const Icon = nodeIcons[data.type];
|
const Icon = nodeIcons[data.type];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="prompt-node relative bg-white w-96 rounded-lg solid border flex flex-col justify-center">
|
<div className="prompt-node relative bg-white w-96 rounded-lg solid border flex flex-col justify-center">
|
||||||
<div className="w-full flex items-center justify-between p-4 gap-8 bg-gray-50 border-b ">
|
<div className="w-full flex items-center justify-between p-4 gap-8 bg-gray-50 border-b ">
|
||||||
<div className="flex items-center gap-4 text-lg">
|
<div className="w-full flex items-center truncate gap-4 text-lg">
|
||||||
<Icon
|
<Icon
|
||||||
className="w-10 h-10 p-1 text-white rounded"
|
className="w-10 h-10 p-1 text-white rounded"
|
||||||
style={{ background: nodeColors[data.type] }}
|
style={{ background: nodeColors[data.type] }}
|
||||||
/>
|
/>
|
||||||
{data.name}
|
<div className="truncate">{data.name}</div>
|
||||||
</div>
|
</div>
|
||||||
<button onClick={data.onDelete}>
|
<button onClick={data.onDelete}>
|
||||||
<TrashIcon className="w-6 h-6 hover:text-red-500"></TrashIcon>
|
<TrashIcon className="w-6 h-6 hover:text-red-500"></TrashIcon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full p-5 h-full">
|
<div className="w-full h-full py-5 pointer-events-none">
|
||||||
<div className="w-full text-gray-500 text-sm">
|
<div className="w-full text-gray-500 px-5 text-sm">
|
||||||
{data.node.description}
|
{data.node.description}
|
||||||
</div>
|
</div>
|
||||||
{Object.keys(data.node.template).map((t, idx) => (
|
<div className="px-5 py-2 mt-2 text-center">Inputs:</div>
|
||||||
<div key={idx} className="w-full mt-5">
|
<>
|
||||||
<Tooltip title={t + ": " + data.node.template[t].type + (data.node.template[t].list ? " list" : "") + (data.node.template[t].required ? " (required)" : "")}>
|
{Object.keys(data.node.template).map((t, idx) => (
|
||||||
<Handle
|
<ParameterComponent
|
||||||
type="source"
|
key={idx}
|
||||||
position={Position.Left}
|
data={data}
|
||||||
id={data.node.template[t].type + "|" + t + "|" + data.id}
|
color={
|
||||||
isValidConnection={(connection) => isValidConnection(data,connection)}
|
nodeColors[
|
||||||
className="ml-1 bg-transparent border-solid border-l-8 border-y-transparent border-y-8 border-r-0 rounded-none"
|
data.types[data.node.template[t].type] ??
|
||||||
style={{
|
data.node.template[t].type
|
||||||
borderLeftColor: (nodeColors[(data.types[data.node.template[t].type] ?? data.node.template[t].type)]) ?? "gray",
|
] ?? "gray"
|
||||||
marginTop: idx * 30 - 50 + "px",
|
}
|
||||||
}}
|
title={snakeToNormalCase(t)}
|
||||||
></Handle>
|
tooltipTitle={
|
||||||
</Tooltip>
|
t +
|
||||||
</div>
|
": " +
|
||||||
))}
|
data.node.template[t].type +
|
||||||
<div className="w-full mt-5"></div>
|
(data.node.template[t].list ? " list" : "") +
|
||||||
|
(data.node.template[t].required ? " (required)" : "")
|
||||||
|
}
|
||||||
|
id={data.node.template[t].type + "|" + t + "|" + data.id}
|
||||||
|
left={true}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
<div className="px-5 py-2 mt-2 text-center">Output:</div>
|
||||||
|
<ParameterComponent
|
||||||
|
data={data}
|
||||||
|
color={nodeColors[data.type]}
|
||||||
|
title={data.name}
|
||||||
|
tooltipTitle={"Output: " + data.name}
|
||||||
|
id={data.name}
|
||||||
|
left={false}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
</div>
|
</div>
|
||||||
<Tooltip title={"Output: " + data.name}>
|
|
||||||
<Handle
|
|
||||||
type="target"
|
|
||||||
position={Position.Right}
|
|
||||||
id={data.name}
|
|
||||||
isValidConnection={(connection) => isValidConnection(data,connection)}
|
|
||||||
className="-mr-1 bg-transparent border-solid border-l-8 border-y-transparent border-y-8 border-r-0 rounded-none"
|
|
||||||
style={{ borderLeftColor: nodeColors[data.type] }}
|
|
||||||
></Handle>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue