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