code format
This commit is contained in:
parent
1a8d522236
commit
fda2047fec
24 changed files with 204 additions and 119 deletions
|
|
@ -118,4 +118,4 @@
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"vite": "^4.4.9"
|
"vite": "^4.4.9"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import {
|
||||||
nodeIconsLucide,
|
nodeIconsLucide,
|
||||||
nodeNames,
|
nodeNames,
|
||||||
} from "../../../../utils/styleUtils";
|
} from "../../../../utils/styleUtils";
|
||||||
import { classNames, extractIdFromLongId, groupByFamily } from "../../../../utils/utils";
|
import { classNames, groupByFamily } from "../../../../utils/utils";
|
||||||
|
|
||||||
export default function ParameterComponent({
|
export default function ParameterComponent({
|
||||||
left,
|
left,
|
||||||
|
|
@ -48,7 +48,7 @@ export default function ParameterComponent({
|
||||||
required = false,
|
required = false,
|
||||||
optionalHandle = null,
|
optionalHandle = null,
|
||||||
info = "",
|
info = "",
|
||||||
proxy
|
proxy,
|
||||||
}: ParameterComponentType): JSX.Element {
|
}: ParameterComponentType): JSX.Element {
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
const refHtml = useRef<HTMLDivElement & ReactNode>(null);
|
const refHtml = useRef<HTMLDivElement & ReactNode>(null);
|
||||||
|
|
@ -185,10 +185,13 @@ export default function ParameterComponent({
|
||||||
(info !== "" ? " flex items-center" : "")
|
(info !== "" ? " flex items-center" : "")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{proxy ? (<ShadTooltip content={<span>{proxy.id}</span>}>
|
{proxy ? (
|
||||||
|
<ShadTooltip content={<span>{proxy.id}</span>}>
|
||||||
<span>{title}</span>
|
<span>{title}</span>
|
||||||
</ShadTooltip>):title}
|
</ShadTooltip>
|
||||||
|
) : (
|
||||||
|
title
|
||||||
|
)}
|
||||||
<span className="text-status-red">{required ? " *" : ""}</span>
|
<span className="text-status-red">{required ? " *" : ""}</span>
|
||||||
<div className="">
|
<div className="">
|
||||||
{info !== "" && (
|
{info !== "" && (
|
||||||
|
|
@ -302,7 +305,11 @@ export default function ParameterComponent({
|
||||||
) : left === true && type === "code" ? (
|
) : left === true && type === "code" ? (
|
||||||
<div className="mt-2 w-full">
|
<div className="mt-2 w-full">
|
||||||
<CodeAreaComponent
|
<CodeAreaComponent
|
||||||
readonly={data.node?.flow && data.node.template[name].dynamic?true:false}
|
readonly={
|
||||||
|
data.node?.flow && data.node.template[name].dynamic
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
}
|
||||||
dynamic={data.node?.template[name].dynamic ?? false}
|
dynamic={data.node?.template[name].dynamic ?? false}
|
||||||
setNodeClass={(nodeClass) => {
|
setNodeClass={(nodeClass) => {
|
||||||
data.node = nodeClass;
|
data.node = nodeClass;
|
||||||
|
|
@ -338,7 +345,11 @@ export default function ParameterComponent({
|
||||||
) : left === true && type === "prompt" ? (
|
) : left === true && type === "prompt" ? (
|
||||||
<div className="mt-2 w-full">
|
<div className="mt-2 w-full">
|
||||||
<PromptAreaComponent
|
<PromptAreaComponent
|
||||||
readonly={data.node?.flow && data.node.template[name].dynamic?true:false}
|
readonly={
|
||||||
|
data.node?.flow && data.node.template[name].dynamic
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
}
|
||||||
field_name={name}
|
field_name={name}
|
||||||
setNodeClass={(nodeClass) => {
|
setNodeClass={(nodeClass) => {
|
||||||
data.node = nodeClass;
|
data.node = nodeClass;
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,26 @@
|
||||||
import { cloneDeep, get } from "lodash";
|
import { cloneDeep } from "lodash";
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { NodeToolbar, XYPosition, useUpdateNodeInternals } from "reactflow";
|
import { NodeToolbar, useUpdateNodeInternals } from "reactflow";
|
||||||
import ShadTooltip from "../../components/ShadTooltipComponent";
|
import ShadTooltip from "../../components/ShadTooltipComponent";
|
||||||
import Tooltip from "../../components/TooltipComponent";
|
import Tooltip from "../../components/TooltipComponent";
|
||||||
import IconComponent from "../../components/genericIconComponent";
|
import IconComponent from "../../components/genericIconComponent";
|
||||||
|
import InputComponent from "../../components/inputComponent";
|
||||||
|
import { Textarea } from "../../components/ui/textarea";
|
||||||
import { useSSE } from "../../contexts/SSEContext";
|
import { useSSE } from "../../contexts/SSEContext";
|
||||||
import { TabsContext } from "../../contexts/tabsContext";
|
import { TabsContext } from "../../contexts/tabsContext";
|
||||||
import { typesContext } from "../../contexts/typesContext";
|
import { typesContext } from "../../contexts/typesContext";
|
||||||
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
|
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
|
||||||
import { validationStatusType } from "../../types/components";
|
import { validationStatusType } from "../../types/components";
|
||||||
import { NodeDataType } from "../../types/flow";
|
import { NodeDataType } from "../../types/flow";
|
||||||
import { cleanEdges, getGroupStatus, handleKeyDown, scapedJSONStringfy } from "../../utils/reactflowUtils";
|
import {
|
||||||
|
cleanEdges,
|
||||||
|
getGroupStatus,
|
||||||
|
handleKeyDown,
|
||||||
|
scapedJSONStringfy,
|
||||||
|
} from "../../utils/reactflowUtils";
|
||||||
import { nodeColors, nodeIconsLucide } from "../../utils/styleUtils";
|
import { nodeColors, nodeIconsLucide } from "../../utils/styleUtils";
|
||||||
import { classNames, toTitleCase } from "../../utils/utils";
|
import { classNames, toTitleCase } from "../../utils/utils";
|
||||||
import ParameterComponent from "./components/parameterComponent";
|
import ParameterComponent from "./components/parameterComponent";
|
||||||
import InputComponent from "../../components/inputComponent";
|
|
||||||
import { Textarea } from "../../components/ui/textarea";
|
|
||||||
|
|
||||||
export default function GenericNode({
|
export default function GenericNode({
|
||||||
data: olddata,
|
data: olddata,
|
||||||
|
|
@ -66,7 +71,9 @@ export default function GenericNode({
|
||||||
|
|
||||||
// New useEffect to watch for changes in sseData and update validation status
|
// New useEffect to watch for changes in sseData and update validation status
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const relevantData = data.node?.flow ? getGroupStatus(data.node.flow, sseData) : sseData[data.id];
|
const relevantData = data.node?.flow
|
||||||
|
? getGroupStatus(data.node.flow, sseData)
|
||||||
|
: sseData[data.id];
|
||||||
if (relevantData) {
|
if (relevantData) {
|
||||||
// Extract validation information from relevantData and update the validationStatus state
|
// Extract validation information from relevantData and update the validationStatus state
|
||||||
setValidationStatus(relevantData);
|
setValidationStatus(relevantData);
|
||||||
|
|
@ -105,8 +112,8 @@ export default function GenericNode({
|
||||||
iconColor={`${nodeColors[types[data.type]]}`}
|
iconColor={`${nodeColors[types[data.type]]}`}
|
||||||
/>
|
/>
|
||||||
<div className="generic-node-tooltip-div">
|
<div className="generic-node-tooltip-div">
|
||||||
{data.node?.flow && inputName ?
|
{data.node?.flow && inputName ? (
|
||||||
<div >
|
<div>
|
||||||
<InputComponent
|
<InputComponent
|
||||||
autoFocus
|
autoFocus
|
||||||
onBlur={() => {
|
onBlur={() => {
|
||||||
|
|
@ -123,13 +130,17 @@ export default function GenericNode({
|
||||||
password={false}
|
password={false}
|
||||||
blurOnEnter={true}
|
blurOnEnter={true}
|
||||||
/>
|
/>
|
||||||
</div> : <ShadTooltip content={data.node?.display_name}>
|
</div>
|
||||||
<div className="generic-node-tooltip-div text-primary" onDoubleClick={() => setInputName(true)}>
|
) : (
|
||||||
|
<ShadTooltip content={data.node?.display_name}>
|
||||||
|
<div
|
||||||
|
className="generic-node-tooltip-div text-primary"
|
||||||
|
onDoubleClick={() => setInputName(true)}
|
||||||
|
>
|
||||||
{data.node?.display_name}
|
{data.node?.display_name}
|
||||||
</div>
|
</div>
|
||||||
</ShadTooltip>
|
</ShadTooltip>
|
||||||
}
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="round-button-div">
|
<div className="round-button-div">
|
||||||
|
|
@ -151,10 +162,10 @@ export default function GenericNode({
|
||||||
<div className="max-h-96 overflow-auto">
|
<div className="max-h-96 overflow-auto">
|
||||||
{typeof validationStatus.params === "string"
|
{typeof validationStatus.params === "string"
|
||||||
? validationStatus.params
|
? validationStatus.params
|
||||||
.split("\n")
|
.split("\n")
|
||||||
.map((line: string, index: number) => (
|
.map((line: string, index: number) => (
|
||||||
<div key={index}>{line}</div>
|
<div key={index}>{line}</div>
|
||||||
))
|
))
|
||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
@ -192,7 +203,7 @@ export default function GenericNode({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="generic-node-desc">
|
<div className="generic-node-desc">
|
||||||
{data.node?.flow && inputDescription ?
|
{data.node?.flow && inputDescription ? (
|
||||||
<Textarea
|
<Textarea
|
||||||
autoFocus
|
autoFocus
|
||||||
onBlur={() => {
|
onBlur={() => {
|
||||||
|
|
@ -205,10 +216,15 @@ export default function GenericNode({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
value={nodeDescription}
|
value={nodeDescription}
|
||||||
onChange={(e)=>setNodeDescription(e.target.value)}
|
onChange={(e) => setNodeDescription(e.target.value)}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
handleKeyDown(e, nodeDescription, "");
|
handleKeyDown(e, nodeDescription, "");
|
||||||
if(e.key === "Enter" && e.shiftKey === false && e.ctrlKey === false && e.altKey === false){
|
if (
|
||||||
|
e.key === "Enter" &&
|
||||||
|
e.shiftKey === false &&
|
||||||
|
e.ctrlKey === false &&
|
||||||
|
e.altKey === false
|
||||||
|
) {
|
||||||
setInputDescription(false);
|
setInputDescription(false);
|
||||||
if (nodeDescription.trim() !== "") {
|
if (nodeDescription.trim() !== "") {
|
||||||
setNodeDescription(nodeDescription);
|
setNodeDescription(nodeDescription);
|
||||||
|
|
@ -218,9 +234,15 @@ export default function GenericNode({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/> :
|
/>
|
||||||
<div className="generic-node-desc-text" onDoubleClick={() => setInputDescription(true)}>{data.node?.description}</div>
|
) : (
|
||||||
}
|
<div
|
||||||
|
className="generic-node-desc-text"
|
||||||
|
onDoubleClick={() => setInputDescription(true)}
|
||||||
|
>
|
||||||
|
{data.node?.description}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<>
|
<>
|
||||||
{Object.keys(data.node!.template)
|
{Object.keys(data.node!.template)
|
||||||
|
|
@ -228,7 +250,7 @@ export default function GenericNode({
|
||||||
.map((templateField: string, idx) => (
|
.map((templateField: string, idx) => (
|
||||||
<div key={idx}>
|
<div key={idx}>
|
||||||
{data.node!.template[templateField].show &&
|
{data.node!.template[templateField].show &&
|
||||||
!data.node!.template[templateField].advanced ? (
|
!data.node!.template[templateField].advanced ? (
|
||||||
<ParameterComponent
|
<ParameterComponent
|
||||||
key={scapedJSONStringfy({
|
key={scapedJSONStringfy({
|
||||||
inputTypes:
|
inputTypes:
|
||||||
|
|
@ -242,7 +264,7 @@ export default function GenericNode({
|
||||||
setData={setData}
|
setData={setData}
|
||||||
color={
|
color={
|
||||||
nodeColors[
|
nodeColors[
|
||||||
types[data.node?.template[templateField].type!]
|
types[data.node?.template[templateField].type!]
|
||||||
] ??
|
] ??
|
||||||
nodeColors[data.node?.template[templateField].type!] ??
|
nodeColors[data.node?.template[templateField].type!] ??
|
||||||
nodeColors.unknown
|
nodeColors.unknown
|
||||||
|
|
@ -251,8 +273,8 @@ export default function GenericNode({
|
||||||
data.node?.template[templateField].display_name
|
data.node?.template[templateField].display_name
|
||||||
? data.node.template[templateField].display_name
|
? data.node.template[templateField].display_name
|
||||||
: data.node?.template[templateField].name
|
: data.node?.template[templateField].name
|
||||||
? toTitleCase(data.node.template[templateField].name)
|
? toTitleCase(data.node.template[templateField].name)
|
||||||
: toTitleCase(templateField)
|
: toTitleCase(templateField)
|
||||||
}
|
}
|
||||||
info={data.node?.template[templateField].info}
|
info={data.node?.template[templateField].info}
|
||||||
name={templateField}
|
name={templateField}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export default function CodeAreaComponent({
|
||||||
nodeClass,
|
nodeClass,
|
||||||
dynamic,
|
dynamic,
|
||||||
setNodeClass,
|
setNodeClass,
|
||||||
readonly=false
|
readonly = false,
|
||||||
}: CodeAreaComponentType) {
|
}: CodeAreaComponentType) {
|
||||||
const [myValue, setMyValue] = useState(
|
const [myValue, setMyValue] = useState(
|
||||||
typeof value == "string" ? value : JSON.stringify(value)
|
typeof value == "string" ? value : JSON.stringify(value)
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ export default function CodeTabsComponent({
|
||||||
key={idx} // Remember to add a unique key prop
|
key={idx} // Remember to add a unique key prop
|
||||||
>
|
>
|
||||||
{idx < 4 ? (
|
{idx < 4 ? (
|
||||||
<div className="w-full h-full flex flex-col">
|
<div className="flex h-full w-full flex-col">
|
||||||
{tab.description && (
|
{tab.description && (
|
||||||
<div
|
<div
|
||||||
className="mb-2 w-full text-left text-sm"
|
className="mb-2 w-full text-left text-sm"
|
||||||
|
|
@ -633,7 +633,14 @@ export default function CodeTabsComponent({
|
||||||
>
|
>
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<PromptAreaComponent
|
<PromptAreaComponent
|
||||||
readonly={node.data.node?.flow && node.data.node.template[templateField].dynamic? true : false}
|
readonly={
|
||||||
|
node.data.node?.flow &&
|
||||||
|
node.data.node.template[
|
||||||
|
templateField
|
||||||
|
].dynamic
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
}
|
||||||
editNode={true}
|
editNode={true}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
value={
|
value={
|
||||||
|
|
@ -689,7 +696,14 @@ export default function CodeTabsComponent({
|
||||||
>
|
>
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<CodeAreaComponent
|
<CodeAreaComponent
|
||||||
readonly={node.data.node?.flow && node.data.node.template[templateField].dynamic? true : false}
|
readonly={
|
||||||
|
node.data.node?.flow &&
|
||||||
|
node.data.node.template[
|
||||||
|
templateField
|
||||||
|
].dynamic
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
editNode={true}
|
editNode={true}
|
||||||
value={
|
value={
|
||||||
|
|
|
||||||
|
|
@ -139,9 +139,7 @@ export default function Header(): JSX.Element {
|
||||||
<button
|
<button
|
||||||
className={
|
className={
|
||||||
"h-7 w-7 rounded-full focus-visible:outline-0 " +
|
"h-7 w-7 rounded-full focus-visible:outline-0 " +
|
||||||
gradients[
|
gradients[gradientIndex]
|
||||||
gradientIndex
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { classNames } from "../../utils/utils";
|
||||||
import { Input } from "../ui/input";
|
import { Input } from "../ui/input";
|
||||||
|
|
||||||
export default function InputComponent({
|
export default function InputComponent({
|
||||||
autoFocus =false,
|
autoFocus = false,
|
||||||
onBlur,
|
onBlur,
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
|
|
@ -17,7 +17,7 @@ export default function InputComponent({
|
||||||
editNode = false,
|
editNode = false,
|
||||||
placeholder = "Type something...",
|
placeholder = "Type something...",
|
||||||
className,
|
className,
|
||||||
blurOnEnter=false
|
blurOnEnter = false,
|
||||||
}: InputComponentType): JSX.Element {
|
}: InputComponentType): JSX.Element {
|
||||||
const [pwdVisible, setPwdVisible] = useState(false);
|
const [pwdVisible, setPwdVisible] = useState(false);
|
||||||
const refInput = useRef<HTMLInputElement>(null);
|
const refInput = useRef<HTMLInputElement>(null);
|
||||||
|
|
@ -33,8 +33,8 @@ export default function InputComponent({
|
||||||
{isForm ? (
|
{isForm ? (
|
||||||
<Form.Control asChild>
|
<Form.Control asChild>
|
||||||
<Input
|
<Input
|
||||||
ref={refInput}
|
ref={refInput}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
type={password && !pwdVisible ? "password" : "text"}
|
type={password && !pwdVisible ? "password" : "text"}
|
||||||
value={value}
|
value={value}
|
||||||
|
|
@ -55,7 +55,7 @@ export default function InputComponent({
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
handleKeyDown(e, value, "");
|
handleKeyDown(e, value, "");
|
||||||
if(blurOnEnter && e.key === "Enter") refInput.current?.blur();
|
if (blurOnEnter && e.key === "Enter") refInput.current?.blur();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
|
|
@ -83,7 +83,7 @@ export default function InputComponent({
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
handleKeyDown(e, value, "");
|
handleKeyDown(e, value, "");
|
||||||
if(blurOnEnter && e.key === "Enter") refInput.current?.blur();
|
if (blurOnEnter && e.key === "Enter") refInput.current?.blur();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export default function PromptAreaComponent({
|
||||||
onChange,
|
onChange,
|
||||||
disabled,
|
disabled,
|
||||||
editNode = false,
|
editNode = false,
|
||||||
readonly=false
|
readonly = false,
|
||||||
}: TextAreaComponentType): JSX.Element {
|
}: TextAreaComponentType): JSX.Element {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ const DialogOverlay = React.forwardRef<
|
||||||
<DialogPrimitive.Overlay
|
<DialogPrimitive.Overlay
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"fixed top-0 right-0 left-0 bottom-0 overflow-auto inset-0 z-50 bg-blur-shared backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
"fixed inset-0 bottom-0 left-0 right-0 top-0 z-50 overflow-auto bg-blur-shared backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
@ -44,7 +44,7 @@ const DialogContent = React.forwardRef<
|
||||||
<DialogPrimitive.Content
|
<DialogPrimitive.Content
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"noundo nocopy flex text-start overflow-auto z-50 justify-center items-left flex-col w-full max-w-lg gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-bottom-[48%] data-[state=open]:slide-in-from-bottom-[48%] sm:rounded-lg md:w-full",
|
"noundo nocopy items-left z-50 flex w-full max-w-lg flex-col justify-center gap-4 overflow-auto border bg-background p-6 text-start shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-bottom-[48%] data-[state=open]:slide-in-from-bottom-[48%] sm:rounded-lg md:w-full",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,7 @@ export function DarkProvider({ children }) {
|
||||||
fetchStars();
|
fetchStars();
|
||||||
const min = 0;
|
const min = 0;
|
||||||
const max = 30;
|
const max = 30;
|
||||||
setGradientIndex(
|
setGradientIndex(Math.floor(Math.random() * (max - min + 1)) + min);
|
||||||
Math.floor(Math.random() * (max - min + 1)) + min
|
|
||||||
)
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ const TabsContextInitialValue: TabsContextType = {
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
flows: [],
|
flows: [],
|
||||||
removeFlow: (id: string) => {},
|
removeFlow: (id: string) => {},
|
||||||
addFlow: async (newProject:boolean,flowData?: FlowType) => "",
|
addFlow: async (newProject: boolean, flowData?: FlowType) => "",
|
||||||
updateFlow: (newFlow: FlowType) => {},
|
updateFlow: (newFlow: FlowType) => {},
|
||||||
incrementNodeId: () => uid(),
|
incrementNodeId: () => uid(),
|
||||||
downloadFlow: (flow: FlowType) => {},
|
downloadFlow: (flow: FlowType) => {},
|
||||||
|
|
@ -324,7 +324,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
||||||
// parse the text into a JSON object
|
// parse the text into a JSON object
|
||||||
let flow: FlowType = JSON.parse(text);
|
let flow: FlowType = JSON.parse(text);
|
||||||
|
|
||||||
id = await addFlow(newProject,flow);
|
id = await addFlow(newProject, flow);
|
||||||
} else {
|
} else {
|
||||||
// create a file input
|
// create a file input
|
||||||
const input = document.createElement("input");
|
const input = document.createElement("input");
|
||||||
|
|
@ -339,7 +339,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
||||||
const currentfile = (e.target as HTMLInputElement).files![0];
|
const currentfile = (e.target as HTMLInputElement).files![0];
|
||||||
let text = await currentfile.text();
|
let text = await currentfile.text();
|
||||||
let flow: FlowType = JSON.parse(text);
|
let flow: FlowType = JSON.parse(text);
|
||||||
const flowId = await addFlow(newProject,flow);
|
const flowId = await addFlow(newProject, flow);
|
||||||
resolve(flowId);
|
resolve(flowId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -486,7 +486,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
||||||
|
|
||||||
const addFlow = async (
|
const addFlow = async (
|
||||||
newProject?: Boolean,
|
newProject?: Boolean,
|
||||||
flow?: FlowType,
|
flow?: FlowType
|
||||||
): Promise<String | undefined> => {
|
): Promise<String | undefined> => {
|
||||||
if (newProject) {
|
if (newProject) {
|
||||||
let flowData = extractDataFromFlow(flow!);
|
let flowData = extractDataFromFlow(flow!);
|
||||||
|
|
|
||||||
|
|
@ -140,9 +140,9 @@ const EditNodeModal = forwardRef(
|
||||||
<TableRow key={index} className="h-10">
|
<TableRow key={index} className="h-10">
|
||||||
<TableCell className="truncate p-0 text-center text-sm text-foreground sm:px-3">
|
<TableCell className="truncate p-0 text-center text-sm text-foreground sm:px-3">
|
||||||
{myData.node?.template[templateParam].display_name
|
{myData.node?.template[templateParam].display_name
|
||||||
? myData.node.template[templateParam].display_name
|
? myData.node.template[templateParam]
|
||||||
: myData.node?.template[templateParam]
|
.display_name
|
||||||
.name}
|
: myData.node?.template[templateParam].name}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="w-[300px] p-0 text-center text-xs text-foreground ">
|
<TableCell className="w-[300px] p-0 text-center text-xs text-foreground ">
|
||||||
{myData.node?.template[templateParam].type ===
|
{myData.node?.template[templateParam].type ===
|
||||||
|
|
@ -297,7 +297,13 @@ const EditNodeModal = forwardRef(
|
||||||
"prompt" ? (
|
"prompt" ? (
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<PromptAreaComponent
|
<PromptAreaComponent
|
||||||
readonly={myData.node?.flow && myData.node.template[templateParam].dynamic? true : false}
|
readonly={
|
||||||
|
myData.node?.flow &&
|
||||||
|
myData.node.template[templateParam]
|
||||||
|
.dynamic
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
}
|
||||||
field_name={templateParam}
|
field_name={templateParam}
|
||||||
editNode={true}
|
editNode={true}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
|
@ -318,7 +324,13 @@ const EditNodeModal = forwardRef(
|
||||||
"code" ? (
|
"code" ? (
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<CodeAreaComponent
|
<CodeAreaComponent
|
||||||
readonly={myData.node?.flow && myData.node.template[templateParam].dynamic? true : false}
|
readonly={
|
||||||
|
myData.node?.flow &&
|
||||||
|
myData.node.template[templateParam]
|
||||||
|
.dynamic
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
}
|
||||||
dynamic={
|
dynamic={
|
||||||
data.node!.template[templateParam]
|
data.node!.template[templateParam]
|
||||||
.dynamic ?? false
|
.dynamic ?? false
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,13 @@ export default function CodeAreaModal({
|
||||||
setNodeClass,
|
setNodeClass,
|
||||||
children,
|
children,
|
||||||
dynamic,
|
dynamic,
|
||||||
readonly=false
|
readonly = false,
|
||||||
}: codeAreaModalPropsType): JSX.Element {
|
}: codeAreaModalPropsType): JSX.Element {
|
||||||
const [code, setCode] = useState(value);
|
const [code, setCode] = useState(value);
|
||||||
const { dark } = useContext(darkContext);
|
const { dark } = useContext(darkContext);
|
||||||
const { reactFlowInstance } = useContext(typesContext);
|
const { reactFlowInstance } = useContext(typesContext);
|
||||||
const [height, setHeight] = useState<string | null>(null);
|
const [height, setHeight] = useState<string | null>(null);
|
||||||
const { setErrorData, setSuccessData } =
|
const { setErrorData, setSuccessData } = useContext(alertContext);
|
||||||
useContext(alertContext);
|
|
||||||
const [error, setError] = useState<{
|
const [error, setError] = useState<{
|
||||||
detail: { error: string | undefined; traceback: string | undefined };
|
detail: { error: string | undefined; traceback: string | undefined };
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
|
|
@ -183,7 +182,12 @@ export default function CodeAreaModal({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex h-fit w-full justify-end">
|
<div className="flex h-fit w-full justify-end">
|
||||||
<Button disabled={readonly} className="mt-3" onClick={handleClick} type="submit">
|
<Button
|
||||||
|
disabled={readonly}
|
||||||
|
className="mt-3"
|
||||||
|
onClick={handleClick}
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
Check & Save
|
Check & Save
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import { AuthContext } from "../../contexts/authContext";
|
||||||
import { TabsContext } from "../../contexts/tabsContext";
|
import { TabsContext } from "../../contexts/tabsContext";
|
||||||
import { getBuildStatus } from "../../controllers/API";
|
import { getBuildStatus } from "../../controllers/API";
|
||||||
import { TabsState } from "../../types/tabs";
|
import { TabsState } from "../../types/tabs";
|
||||||
import { validateNodes,processFlow } from "../../utils/reactflowUtils";
|
import { processFlow, validateNodes } from "../../utils/reactflowUtils";
|
||||||
|
|
||||||
export default function FormModal({
|
export default function FormModal({
|
||||||
flow,
|
flow,
|
||||||
|
|
@ -368,7 +368,7 @@ export default function FormModal({
|
||||||
tabsState[flow.id].formKeysData.template
|
tabsState[flow.id].formKeysData.template
|
||||||
);
|
);
|
||||||
sendAll({
|
sendAll({
|
||||||
... processFlow(reactFlowInstance?.toObject()!),
|
...processFlow(reactFlowInstance?.toObject()!),
|
||||||
inputs: inputs!,
|
inputs: inputs!,
|
||||||
chatHistory,
|
chatHistory,
|
||||||
name: flow.name,
|
name: flow.name,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export default function GenericModal({
|
||||||
nodeClass,
|
nodeClass,
|
||||||
setNodeClass,
|
setNodeClass,
|
||||||
children,
|
children,
|
||||||
readonly=false,
|
readonly = false,
|
||||||
}: genericModalPropsType): JSX.Element {
|
}: genericModalPropsType): JSX.Element {
|
||||||
const [myButtonText] = useState(buttonText);
|
const [myButtonText] = useState(buttonText);
|
||||||
const [myModalTitle] = useState(modalTitle);
|
const [myModalTitle] = useState(modalTitle);
|
||||||
|
|
@ -285,7 +285,7 @@ export default function GenericModal({
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
disabled={readonly}
|
disabled={readonly}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
switch (myModalType) {
|
switch (myModalType) {
|
||||||
case TypeModal.TEXT:
|
case TypeModal.TEXT:
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ export default function CommunityPage(): JSX.Element {
|
||||||
size="sm"
|
size="sm"
|
||||||
className="whitespace-nowrap "
|
className="whitespace-nowrap "
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
addFlow(true,flow).then((id) => {
|
addFlow(true, flow).then((id) => {
|
||||||
navigate("/flow/" + id);
|
navigate("/flow/" + id);
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ import {
|
||||||
} from "../../../../utils/reactflowUtils";
|
} from "../../../../utils/reactflowUtils";
|
||||||
import { getRandomName, isWrappedWithClass } from "../../../../utils/utils";
|
import { getRandomName, isWrappedWithClass } from "../../../../utils/utils";
|
||||||
import ConnectionLineComponent from "../ConnectionLineComponent";
|
import ConnectionLineComponent from "../ConnectionLineComponent";
|
||||||
import ExtraSidebar from "../extraSidebarComponent";
|
|
||||||
import SelectionMenu from "../SelectionMenuComponent";
|
import SelectionMenu from "../SelectionMenuComponent";
|
||||||
|
import ExtraSidebar from "../extraSidebarComponent";
|
||||||
|
|
||||||
const nodeTypes = {
|
const nodeTypes = {
|
||||||
genericNode: GenericNode,
|
genericNode: GenericNode,
|
||||||
|
|
@ -444,30 +444,47 @@ export default function Page({
|
||||||
[&>button]:border-b-border hover:[&>button]:bg-border"
|
[&>button]:border-b-border hover:[&>button]:bg-border"
|
||||||
></Controls>
|
></Controls>
|
||||||
)}
|
)}
|
||||||
<SelectionMenu isVisible={selectionMenuVisible} nodes={lastSelection?.nodes}
|
<SelectionMenu
|
||||||
onClick={()=>{
|
isVisible={selectionMenuVisible}
|
||||||
if(validateSelection(lastSelection!,edges).length===0){
|
nodes={lastSelection?.nodes}
|
||||||
const {newFlow} = generateFlow(lastSelection!,reactFlowInstance!,getRandomName());
|
onClick={() => {
|
||||||
const newGroupNode = generateNodeFromFlow(newFlow)
|
if (
|
||||||
setNodes((oldNodes)=>[...oldNodes.filter((oldNodes)=>!lastSelection?.nodes.some((selectionNode)=>selectionNode.id===oldNodes.id)),newGroupNode])
|
validateSelection(lastSelection!, edges).length === 0
|
||||||
setEdges((oldEdges) =>
|
) {
|
||||||
oldEdges.filter(
|
const { newFlow } = generateFlow(
|
||||||
(oldEdge) =>
|
lastSelection!,
|
||||||
!lastSelection!.nodes.some(
|
reactFlowInstance!,
|
||||||
(selectionNode) =>
|
getRandomName()
|
||||||
selectionNode.id === oldEdge.target ||
|
);
|
||||||
selectionNode.id === oldEdge.source
|
const newGroupNode = generateNodeFromFlow(newFlow);
|
||||||
|
setNodes((oldNodes) => [
|
||||||
|
...oldNodes.filter(
|
||||||
|
(oldNodes) =>
|
||||||
|
!lastSelection?.nodes.some(
|
||||||
|
(selectionNode) =>
|
||||||
|
selectionNode.id === oldNodes.id
|
||||||
|
)
|
||||||
|
),
|
||||||
|
newGroupNode,
|
||||||
|
]);
|
||||||
|
setEdges((oldEdges) =>
|
||||||
|
oldEdges.filter(
|
||||||
|
(oldEdge) =>
|
||||||
|
!lastSelection!.nodes.some(
|
||||||
|
(selectionNode) =>
|
||||||
|
selectionNode.id === oldEdge.target ||
|
||||||
|
selectionNode.id === oldEdge.source
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
);
|
} else {
|
||||||
}
|
setErrorData({
|
||||||
else{
|
title: "Invalid selection",
|
||||||
setErrorData({
|
list: validateSelection(lastSelection!, edges),
|
||||||
title: "Invalid selection",
|
});
|
||||||
list: validateSelection(lastSelection!,edges),
|
}
|
||||||
});
|
}}
|
||||||
}
|
/>
|
||||||
}}/>
|
|
||||||
</ReactFlow>
|
</ReactFlow>
|
||||||
{!view && (
|
{!view && (
|
||||||
<Chat flow={flow} reactFlowInstance={reactFlowInstance!} />
|
<Chat flow={flow} reactFlowInstance={reactFlowInstance!} />
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { NodeToolbar } from "reactflow";
|
import { NodeToolbar } from "reactflow";
|
||||||
import IconComponent from "../../../../components/genericIconComponent";
|
import IconComponent from "../../../../components/genericIconComponent";
|
||||||
export default function SelectionMenu({ onClick, nodes, isVisible }) {
|
export default function SelectionMenu({ onClick, nodes, isVisible }) {
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,11 @@ import IconComponent from "../../../../components/genericIconComponent";
|
||||||
import { TabsContext } from "../../../../contexts/tabsContext";
|
import { TabsContext } from "../../../../contexts/tabsContext";
|
||||||
import EditNodeModal from "../../../../modals/EditNodeModal";
|
import EditNodeModal from "../../../../modals/EditNodeModal";
|
||||||
import { nodeToolbarPropsType } from "../../../../types/components";
|
import { nodeToolbarPropsType } from "../../../../types/components";
|
||||||
|
import {
|
||||||
|
expandGroupNode,
|
||||||
|
updateFlowPosition,
|
||||||
|
} from "../../../../utils/reactflowUtils";
|
||||||
import { classNames } from "../../../../utils/utils";
|
import { classNames } from "../../../../utils/utils";
|
||||||
import { expandGroupNode, ungroupNode, updateFlowPosition } from "../../../../utils/reactflowUtils";
|
|
||||||
|
|
||||||
export default function NodeToolbarComponent({
|
export default function NodeToolbarComponent({
|
||||||
data,
|
data,
|
||||||
|
|
@ -82,9 +85,9 @@ export default function NodeToolbarComponent({
|
||||||
<a
|
<a
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10" +
|
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10" +
|
||||||
(data.node?.documentation === ""
|
(data.node?.documentation === ""
|
||||||
? " text-muted-foreground"
|
? " text-muted-foreground"
|
||||||
: " text-foreground")
|
: " text-foreground")
|
||||||
)}
|
)}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
|
|
@ -110,9 +113,10 @@ export default function NodeToolbarComponent({
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10" +
|
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10" +
|
||||||
(nodeLength == 0
|
(nodeLength == 0
|
||||||
? " text-muted-foreground"
|
? " text-muted-foreground"
|
||||||
: " text-foreground") +(isGroup?"":" rounded-r-md")
|
: " text-foreground") +
|
||||||
|
(isGroup ? "" : " rounded-r-md")
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<IconComponent name="Settings2" className="h-4 w-4 " />
|
<IconComponent name="Settings2" className="h-4 w-4 " />
|
||||||
|
|
@ -128,8 +132,8 @@ export default function NodeToolbarComponent({
|
||||||
)}
|
)}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
updateFlowPosition(position,data.node?.flow!)
|
updateFlowPosition(position, data.node?.flow!);
|
||||||
expandGroupNode(data,reactFlowInstance)
|
expandGroupNode(data, reactFlowInstance);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconComponent name="Ungroup" className="h-4 w-4" />
|
<IconComponent name="Ungroup" className="h-4 w-4" />
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,14 @@ export type APIClassType = {
|
||||||
beta?: boolean;
|
beta?: boolean;
|
||||||
documentation: string;
|
documentation: string;
|
||||||
error?: string;
|
error?: string;
|
||||||
flow?:FlowType;
|
flow?: FlowType;
|
||||||
[key: string]: Array<string> | string | APITemplateType | boolean | FlowType | undefined;
|
[key: string]:
|
||||||
|
| Array<string>
|
||||||
|
| string
|
||||||
|
| APITemplateType
|
||||||
|
| boolean
|
||||||
|
| FlowType
|
||||||
|
| undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TemplateVariableType = {
|
export type TemplateVariableType = {
|
||||||
|
|
@ -30,8 +36,8 @@ export type TemplateVariableType = {
|
||||||
readonly: boolean;
|
readonly: boolean;
|
||||||
multiline?: boolean;
|
multiline?: boolean;
|
||||||
value?: any;
|
value?: any;
|
||||||
dynamic?:boolean;
|
dynamic?: boolean;
|
||||||
proxy?:{id:string,field:string}
|
proxy?: { id: string; field: string };
|
||||||
input_types?: Array<string>;
|
input_types?: Array<string>;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ export type ParameterComponentType = {
|
||||||
dataContext?: typesContextType;
|
dataContext?: typesContextType;
|
||||||
optionalHandle?: Array<String> | null;
|
optionalHandle?: Array<String> | null;
|
||||||
info?: string;
|
info?: string;
|
||||||
proxy?: {field: string, id: string};
|
proxy?: { field: string; id: string };
|
||||||
};
|
};
|
||||||
export type InputListComponentType = {
|
export type InputListComponentType = {
|
||||||
value: string[];
|
value: string[];
|
||||||
|
|
@ -395,7 +395,7 @@ export type nodeToolbarPropsType = {
|
||||||
data: NodeDataType;
|
data: NodeDataType;
|
||||||
deleteNode: (idx: string) => void;
|
deleteNode: (idx: string) => void;
|
||||||
setData: (newState: NodeDataType) => void;
|
setData: (newState: NodeDataType) => void;
|
||||||
position:XYPosition;
|
position: XYPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type parsedDataType = {
|
export type parsedDataType = {
|
||||||
|
|
|
||||||
|
|
@ -50,5 +50,5 @@ export type targetHandleType = {
|
||||||
type: string;
|
type: string;
|
||||||
fieldName: string;
|
fieldName: string;
|
||||||
id: string;
|
id: string;
|
||||||
proxy?:{field:string, id:string}
|
proxy?: { field: string; id: string };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { Edge, Node } from "reactflow";
|
import { Edge, Node } from "reactflow";
|
||||||
import { FlowType, NodeType } from "../flow";
|
import { FlowType, NodeType } from "../flow";
|
||||||
import { generateFlow } from "../../utils/reactflowUtils";
|
|
||||||
|
|
||||||
export type cleanEdgesType = {
|
export type cleanEdgesType = {
|
||||||
flow: {
|
flow: {
|
||||||
|
|
@ -20,9 +19,9 @@ export type updateEdgesHandleIdsType = {
|
||||||
edges: Edge[];
|
edges: Edge[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type generateFlowType = { newFlow: FlowType; removedEdges: Edge[] }
|
export type generateFlowType = { newFlow: FlowType; removedEdges: Edge[] };
|
||||||
|
|
||||||
export type findLastNodeType = {
|
export type findLastNodeType = {
|
||||||
nodes: NodeType[];
|
nodes: NodeType[];
|
||||||
edges: Edge[];
|
edges: Edge[];
|
||||||
}
|
};
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import {
|
||||||
Gift,
|
Gift,
|
||||||
GitFork,
|
GitFork,
|
||||||
GithubIcon,
|
GithubIcon,
|
||||||
|
Group,
|
||||||
Hammer,
|
Hammer,
|
||||||
HelpCircle,
|
HelpCircle,
|
||||||
Home,
|
Home,
|
||||||
|
|
@ -63,6 +64,7 @@ import {
|
||||||
TerminalSquare,
|
TerminalSquare,
|
||||||
Trash2,
|
Trash2,
|
||||||
Undo,
|
Undo,
|
||||||
|
Ungroup,
|
||||||
Unplug,
|
Unplug,
|
||||||
Upload,
|
Upload,
|
||||||
UserCog2,
|
UserCog2,
|
||||||
|
|
@ -75,8 +77,6 @@ import {
|
||||||
X,
|
X,
|
||||||
XCircle,
|
XCircle,
|
||||||
Zap,
|
Zap,
|
||||||
Group,
|
|
||||||
Ungroup
|
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { FaApple, FaGithub } from "react-icons/fa";
|
import { FaApple, FaGithub } from "react-icons/fa";
|
||||||
import { AirbyteIcon } from "../icons/Airbyte";
|
import { AirbyteIcon } from "../icons/Airbyte";
|
||||||
|
|
@ -305,5 +305,5 @@ export const nodeIconsLucide: iconsType = {
|
||||||
Unplug,
|
Unplug,
|
||||||
Group,
|
Group,
|
||||||
ChevronUp,
|
ChevronUp,
|
||||||
Ungroup
|
Ungroup,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue