Merge branch 'bug/undo-copy' into feature/store
This commit is contained in:
commit
52338db3c5
12 changed files with 155 additions and 171 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
import { cloneDeep } from "lodash";
|
|
||||||
import React, {
|
import React, {
|
||||||
ReactNode,
|
ReactNode,
|
||||||
useContext,
|
useContext,
|
||||||
|
|
@ -29,6 +28,7 @@ import {
|
||||||
import { alertContext } from "../../../../contexts/alertContext";
|
import { alertContext } from "../../../../contexts/alertContext";
|
||||||
import { FlowsContext } from "../../../../contexts/flowsContext";
|
import { FlowsContext } from "../../../../contexts/flowsContext";
|
||||||
import { typesContext } from "../../../../contexts/typesContext";
|
import { typesContext } from "../../../../contexts/typesContext";
|
||||||
|
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
|
||||||
import { postCustomComponentUpdate } from "../../../../controllers/API";
|
import { postCustomComponentUpdate } from "../../../../controllers/API";
|
||||||
import { ParameterComponentType } from "../../../../types/components";
|
import { ParameterComponentType } from "../../../../types/components";
|
||||||
import { NodeDataType } from "../../../../types/flow";
|
import { NodeDataType } from "../../../../types/flow";
|
||||||
|
|
@ -50,7 +50,6 @@ export default function ParameterComponent({
|
||||||
left,
|
left,
|
||||||
id,
|
id,
|
||||||
data,
|
data,
|
||||||
setData,
|
|
||||||
tooltipTitle,
|
tooltipTitle,
|
||||||
title,
|
title,
|
||||||
color,
|
color,
|
||||||
|
|
@ -99,6 +98,8 @@ export default function ParameterComponent({
|
||||||
|
|
||||||
const { data: myData } = useContext(typesContext);
|
const { data: myData } = useContext(typesContext);
|
||||||
|
|
||||||
|
const { takeSnapshot } = useContext(undoRedoContext);
|
||||||
|
|
||||||
const handleUpdateValues = async (name: string, data: NodeDataType) => {
|
const handleUpdateValues = async (name: string, data: NodeDataType) => {
|
||||||
const code = data.node?.template["code"]?.value;
|
const code = data.node?.template["code"]?.value;
|
||||||
if (!code) {
|
if (!code) {
|
||||||
|
|
@ -121,9 +122,8 @@ export default function ParameterComponent({
|
||||||
const handleOnNewValue = (
|
const handleOnNewValue = (
|
||||||
newValue: string | string[] | boolean | Object[]
|
newValue: string | string[] | boolean | Object[]
|
||||||
): void => {
|
): void => {
|
||||||
let newData = cloneDeep(data);
|
takeSnapshot();
|
||||||
newData.node!.template[name].value = newValue;
|
data.node!.template[name].value = newValue;
|
||||||
setData(newData);
|
|
||||||
// Set state to pending
|
// Set state to pending
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
setTabsState((prev: TabsState) => {
|
setTabsState((prev: TabsState) => {
|
||||||
|
|
@ -484,9 +484,6 @@ export default function ParameterComponent({
|
||||||
field_name={name}
|
field_name={name}
|
||||||
setNodeClass={(nodeClass) => {
|
setNodeClass={(nodeClass) => {
|
||||||
data.node = nodeClass;
|
data.node = nodeClass;
|
||||||
const clone = cloneDeep(data);
|
|
||||||
clone.node = nodeClass;
|
|
||||||
setData(clone);
|
|
||||||
}}
|
}}
|
||||||
nodeClass={data.node}
|
nodeClass={data.node}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { Textarea } from "../../components/ui/textarea";
|
||||||
import { useSSE } from "../../contexts/SSEContext";
|
import { useSSE } from "../../contexts/SSEContext";
|
||||||
import { FlowsContext } from "../../contexts/flowsContext";
|
import { FlowsContext } from "../../contexts/flowsContext";
|
||||||
import { typesContext } from "../../contexts/typesContext";
|
import { typesContext } from "../../contexts/typesContext";
|
||||||
|
import { undoRedoContext } from "../../contexts/undoRedoContext";
|
||||||
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";
|
||||||
|
|
@ -22,7 +23,7 @@ import { classNames, getFieldTitle } from "../../utils/utils";
|
||||||
import ParameterComponent from "./components/parameterComponent";
|
import ParameterComponent from "./components/parameterComponent";
|
||||||
|
|
||||||
export default function GenericNode({
|
export default function GenericNode({
|
||||||
data: olddata,
|
data,
|
||||||
xPos,
|
xPos,
|
||||||
yPos,
|
yPos,
|
||||||
selected,
|
selected,
|
||||||
|
|
@ -32,7 +33,6 @@ export default function GenericNode({
|
||||||
xPos: number;
|
xPos: number;
|
||||||
yPos: number;
|
yPos: number;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const [data, setData] = useState(olddata);
|
|
||||||
const { updateFlow, flows, tabId } = useContext(FlowsContext);
|
const { updateFlow, flows, tabId } = useContext(FlowsContext);
|
||||||
const updateNodeInternals = useUpdateNodeInternals();
|
const updateNodeInternals = useUpdateNodeInternals();
|
||||||
const { types, deleteNode, reactFlowInstance, setFilterEdge, getFilterEdge } =
|
const { types, deleteNode, reactFlowInstance, setFilterEdge, getFilterEdge } =
|
||||||
|
|
@ -46,10 +46,11 @@ export default function GenericNode({
|
||||||
);
|
);
|
||||||
const [validationStatus, setValidationStatus] =
|
const [validationStatus, setValidationStatus] =
|
||||||
useState<validationStatusType | null>(null);
|
useState<validationStatusType | null>(null);
|
||||||
const [showNode, setShowNode] = useState<boolean>(true);
|
|
||||||
const [handles, setHandles] = useState<boolean[] | []>([]);
|
const [handles, setHandles] = useState<boolean[] | []>([]);
|
||||||
let numberOfInputs: boolean[] = [];
|
let numberOfInputs: boolean[] = [];
|
||||||
|
|
||||||
|
const { takeSnapshot } = useContext(undoRedoContext);
|
||||||
|
|
||||||
function countHandles(): void {
|
function countHandles(): void {
|
||||||
numberOfInputs = Object.keys(data.node!.template)
|
numberOfInputs = Object.keys(data.node!.template)
|
||||||
.filter((templateField) => templateField.charAt(0) !== "_")
|
.filter((templateField) => templateField.charAt(0) !== "_")
|
||||||
|
|
@ -86,7 +87,6 @@ export default function GenericNode({
|
||||||
// State for outline color
|
// State for outline color
|
||||||
const { sseData, isBuilding } = useSSE();
|
const { sseData, isBuilding } = useSSE();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
olddata.node = data.node;
|
|
||||||
let myFlow = flows.find((flow) => flow.id === tabId);
|
let myFlow = flows.find((flow) => flow.id === tabId);
|
||||||
if (reactFlowInstance && myFlow) {
|
if (reactFlowInstance && myFlow) {
|
||||||
let flow = cloneDeep(myFlow);
|
let flow = cloneDeep(myFlow);
|
||||||
|
|
@ -108,10 +108,12 @@ export default function GenericNode({
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => {
|
setNodeDescription(data.node!.description);
|
||||||
updateNodeInternals(data.id);
|
}, [data.node!.description]);
|
||||||
}, 300);
|
|
||||||
}, [showNode]);
|
useEffect(() => {
|
||||||
|
setNodeName(data.node!.display_name);
|
||||||
|
}, [data.node!.display_name]);
|
||||||
|
|
||||||
// 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(() => {
|
||||||
|
|
@ -123,15 +125,17 @@ export default function GenericNode({
|
||||||
setValidationStatus(null);
|
setValidationStatus(null);
|
||||||
}
|
}
|
||||||
}, [sseData, data.id]);
|
}, [sseData, data.id]);
|
||||||
|
|
||||||
|
const showNode = data.showNode ?? true;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NodeToolbar>
|
<NodeToolbar>
|
||||||
<NodeToolbarComponent
|
<NodeToolbarComponent
|
||||||
position={{ x: xPos, y: yPos }}
|
position={{ x: xPos, y: yPos }}
|
||||||
data={data}
|
data={data}
|
||||||
setData={setData}
|
|
||||||
deleteNode={deleteNode}
|
deleteNode={deleteNode}
|
||||||
setShowNode={setShowNode}
|
setShowNode={(showNode: boolean) => {data.showNode = showNode}}
|
||||||
numberOfHandles={handles}
|
numberOfHandles={handles}
|
||||||
showNode={showNode}
|
showNode={showNode}
|
||||||
></NodeToolbarComponent>
|
></NodeToolbarComponent>
|
||||||
|
|
@ -180,7 +184,6 @@ export default function GenericNode({
|
||||||
{data.node?.flow && inputName ? (
|
{data.node?.flow && inputName ? (
|
||||||
<div>
|
<div>
|
||||||
<InputComponent
|
<InputComponent
|
||||||
autoFocus
|
|
||||||
onBlur={() => {
|
onBlur={() => {
|
||||||
setInputName(false);
|
setInputName(false);
|
||||||
if (nodeName.trim() !== "") {
|
if (nodeName.trim() !== "") {
|
||||||
|
|
@ -200,7 +203,10 @@ export default function GenericNode({
|
||||||
<ShadTooltip content={data.node?.display_name}>
|
<ShadTooltip content={data.node?.display_name}>
|
||||||
<div
|
<div
|
||||||
className="flex"
|
className="flex"
|
||||||
onDoubleClick={() => setInputName(true)}
|
onDoubleClick={() => {
|
||||||
|
setInputName(true);
|
||||||
|
takeSnapshot();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="generic-node-tooltip-div pr-3 text-primary">
|
<div className="generic-node-tooltip-div pr-3 text-primary">
|
||||||
{data.node?.display_name}
|
{data.node?.display_name}
|
||||||
|
|
@ -237,7 +243,6 @@ export default function GenericNode({
|
||||||
proxy: data.node!.template[templateField].proxy,
|
proxy: data.node!.template[templateField].proxy,
|
||||||
})}
|
})}
|
||||||
data={data}
|
data={data}
|
||||||
setData={setData}
|
|
||||||
color={
|
color={
|
||||||
nodeColors[
|
nodeColors[
|
||||||
types[data.node?.template[templateField].type!]
|
types[data.node?.template[templateField].type!]
|
||||||
|
|
@ -286,7 +291,6 @@ export default function GenericNode({
|
||||||
dataType: data.type,
|
dataType: data.type,
|
||||||
})}
|
})}
|
||||||
data={data}
|
data={data}
|
||||||
setData={setData}
|
|
||||||
color={nodeColors[types[data.type]] ?? nodeColors.unknown}
|
color={nodeColors[types[data.type]] ?? nodeColors.unknown}
|
||||||
title={
|
title={
|
||||||
data.node?.output_types &&
|
data.node?.output_types &&
|
||||||
|
|
@ -417,7 +421,10 @@ export default function GenericNode({
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
className="generic-node-desc-text break-all"
|
className="generic-node-desc-text break-all"
|
||||||
onDoubleClick={() => setInputDescription(true)}
|
onDoubleClick={() => {
|
||||||
|
setInputDescription(true);
|
||||||
|
takeSnapshot();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{data.node?.description}
|
{data.node?.description}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -449,7 +456,6 @@ export default function GenericNode({
|
||||||
proxy: data.node!.template[templateField].proxy,
|
proxy: data.node!.template[templateField].proxy,
|
||||||
})}
|
})}
|
||||||
data={data}
|
data={data}
|
||||||
setData={setData}
|
|
||||||
color={
|
color={
|
||||||
nodeColors[
|
nodeColors[
|
||||||
types[data.node?.template[templateField].type!]
|
types[data.node?.template[templateField].type!]
|
||||||
|
|
@ -507,8 +513,7 @@ export default function GenericNode({
|
||||||
dataType: data.type,
|
dataType: data.type,
|
||||||
})}
|
})}
|
||||||
data={data}
|
data={data}
|
||||||
setData={setData}
|
color={nodeColors[types[data.type]] ?? nodeColors.unknown}
|
||||||
color={nodeColors[types[data.type]] ?? nodeColors.unknown}
|
|
||||||
title={
|
title={
|
||||||
data.node?.output_types && data.node.output_types.length > 0
|
data.node?.output_types && data.node.output_types.length > 0
|
||||||
? data.node.output_types.join("|")
|
? data.node.output_types.join("|")
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ export default function KeypairListComponent({
|
||||||
disabled,
|
disabled,
|
||||||
editNode = false,
|
editNode = false,
|
||||||
duplicateKey,
|
duplicateKey,
|
||||||
advanced = false,
|
|
||||||
dataValue,
|
|
||||||
}: KeyPairListComponentType): JSX.Element {
|
}: KeyPairListComponentType): JSX.Element {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
|
|
|
||||||
|
|
@ -418,7 +418,7 @@ export function FlowsProvider({ children }: { children: ReactNode }) {
|
||||||
|
|
||||||
const insidePosition = position.paneX
|
const insidePosition = position.paneX
|
||||||
? { x: position.paneX + position.x, y: position.paneY! + position.y }
|
? { x: position.paneX + position.x, y: position.paneY! + position.y }
|
||||||
: reactFlowInstance!.project({ x: position.x, y: position.y });
|
: reactFlowInstance!.screenToFlowPosition({ x: position.x, y: position.y });
|
||||||
|
|
||||||
selectionInstance.nodes.forEach((node: NodeType) => {
|
selectionInstance.nodes.forEach((node: NodeType) => {
|
||||||
// Generate a unique node ID
|
// Generate a unique node ID
|
||||||
|
|
|
||||||
|
|
@ -52,15 +52,23 @@ export function UndoRedoProvider({ children }) {
|
||||||
|
|
||||||
const takeSnapshot = useCallback(() => {
|
const takeSnapshot = useCallback(() => {
|
||||||
// push the current graph to the past state
|
// push the current graph to the past state
|
||||||
setPast((old) => {
|
let newPast = cloneDeep(past);
|
||||||
let newPast = cloneDeep(old);
|
let newState = {
|
||||||
newPast[tabIndex] = old[tabIndex].slice(
|
nodes: cloneDeep(getNodes()),
|
||||||
old[tabIndex].length - defaultOptions.maxHistorySize + 1,
|
edges: cloneDeep(getEdges()),
|
||||||
old[tabIndex].length
|
};
|
||||||
|
if (
|
||||||
|
past[tabIndex] &&
|
||||||
|
JSON.stringify(past[tabIndex][past[tabIndex].length - 1]) !==
|
||||||
|
JSON.stringify(newState)
|
||||||
|
) {
|
||||||
|
newPast[tabIndex] = past[tabIndex].slice(
|
||||||
|
past[tabIndex].length - defaultOptions.maxHistorySize + 1,
|
||||||
|
past[tabIndex].length
|
||||||
);
|
);
|
||||||
newPast[tabIndex].push({ nodes: getNodes(), edges: getEdges() });
|
newPast[tabIndex].push(newState);
|
||||||
return newPast;
|
}
|
||||||
});
|
setPast(newPast);
|
||||||
|
|
||||||
// whenever we take a new snapshot, the redo operations need to be cleared to avoid state mismatches
|
// whenever we take a new snapshot, the redo operations need to be cleared to avoid state mismatches
|
||||||
setFuture((old) => {
|
setFuture((old) => {
|
||||||
|
|
|
||||||
|
|
@ -45,13 +45,11 @@ const EditNodeModal = forwardRef(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
data,
|
data,
|
||||||
setData,
|
|
||||||
nodeLength,
|
nodeLength,
|
||||||
open,
|
open,
|
||||||
setOpen,
|
setOpen,
|
||||||
}: {
|
}: {
|
||||||
data: NodeDataType;
|
data: NodeDataType;
|
||||||
setData: (data: NodeDataType) => void;
|
|
||||||
nodeLength: number;
|
nodeLength: number;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
setOpen: (open: boolean) => void;
|
setOpen: (open: boolean) => void;
|
||||||
|
|
@ -60,7 +58,7 @@ const EditNodeModal = forwardRef(
|
||||||
) => {
|
) => {
|
||||||
const updateNodeInternals = useUpdateNodeInternals();
|
const updateNodeInternals = useUpdateNodeInternals();
|
||||||
|
|
||||||
let myData = useRef(data);
|
const [myData, setMyData] = useState(data);
|
||||||
|
|
||||||
const { setTabsState, tabId } = useContext(FlowsContext);
|
const { setTabsState, tabId } = useContext(FlowsContext);
|
||||||
const { reactFlowInstance } = useContext(typesContext);
|
const { reactFlowInstance } = useContext(typesContext);
|
||||||
|
|
@ -70,30 +68,31 @@ const EditNodeModal = forwardRef(
|
||||||
.some((edge) => edge.targetHandle === data.id) ?? false;
|
.some((edge) => edge.targetHandle === data.id) ?? false;
|
||||||
|
|
||||||
function changeAdvanced(n) {
|
function changeAdvanced(n) {
|
||||||
myData.current.node!.template[n].advanced =
|
setMyData((old) => {
|
||||||
!myData.current.node!.template[n].advanced;
|
let newData = cloneDeep(old);
|
||||||
|
newData.node!.template[n].advanced =
|
||||||
myData.current = {
|
!newData.node!.template[n].advanced;
|
||||||
...myData.current,
|
return newData;
|
||||||
};
|
});
|
||||||
setAdv(!adv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOnNewValue = (newValue: any, name) => {
|
const handleOnNewValue = (newValue: any, name) => {
|
||||||
myData.current.node!.template[name].value = newValue;
|
setMyData((old) => {
|
||||||
setDataValue(newValue);
|
let newData = cloneDeep(old);
|
||||||
|
newData.node!.template[name].value = newValue;
|
||||||
|
return newData;
|
||||||
|
});
|
||||||
updateNodeInternals(data.id);
|
updateNodeInternals(data.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
myData.current = data; // reset data to what it is on node when opening modal
|
setMyData(data); // reset data to what it is on node when opening modal
|
||||||
}
|
}
|
||||||
}, [open]);
|
}, [open]);
|
||||||
|
|
||||||
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
|
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
|
||||||
const [adv, setAdv] = useState<boolean | null>(null);
|
|
||||||
const [dataValue, setDataValue] = useState(data);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseModal
|
<BaseModal
|
||||||
|
|
@ -102,15 +101,15 @@ const EditNodeModal = forwardRef(
|
||||||
open={open}
|
open={open}
|
||||||
setOpen={setOpen}
|
setOpen={setOpen}
|
||||||
onChangeOpenModal={(open) => {
|
onChangeOpenModal={(open) => {
|
||||||
myData.current = data;
|
setMyData(data);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<BaseModal.Trigger>
|
<BaseModal.Trigger>
|
||||||
<></>
|
<></>
|
||||||
</BaseModal.Trigger>
|
</BaseModal.Trigger>
|
||||||
<BaseModal.Header description={myData.current.node?.description!}>
|
<BaseModal.Header description={myData.node?.description!}>
|
||||||
<span className="pr-2">{myData.current.type}</span>
|
<span className="pr-2">{myData.type}</span>
|
||||||
<Badge variant="secondary">ID: {myData.current.id}</Badge>
|
<Badge variant="secondary">ID: {myData.id}</Badge>
|
||||||
</BaseModal.Header>
|
</BaseModal.Header>
|
||||||
<BaseModal.Content>
|
<BaseModal.Content>
|
||||||
<div className="flex pb-2">
|
<div className="flex pb-2">
|
||||||
|
|
@ -143,13 +142,13 @@ const EditNodeModal = forwardRef(
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody className="p-0">
|
<TableBody className="p-0">
|
||||||
{Object.keys(myData.current.node!.template)
|
{Object.keys(myData.node!.template)
|
||||||
.filter(
|
.filter(
|
||||||
(templateParam) =>
|
(templateParam) =>
|
||||||
templateParam.charAt(0) !== "_" &&
|
templateParam.charAt(0) !== "_" &&
|
||||||
myData.current.node?.template[templateParam].show &&
|
myData.node?.template[templateParam].show &&
|
||||||
LANGFLOW_SUPPORTED_TYPES.has(
|
LANGFLOW_SUPPORTED_TYPES.has(
|
||||||
myData.current.node.template[templateParam].type
|
myData.node.template[templateParam].type
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.map((templateParam, index) => (
|
.map((templateParam, index) => (
|
||||||
|
|
@ -157,46 +156,46 @@ const EditNodeModal = forwardRef(
|
||||||
<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">
|
||||||
<ShadTooltip
|
<ShadTooltip
|
||||||
content={
|
content={
|
||||||
myData.current.node?.template[templateParam]
|
myData.node?.template[templateParam]
|
||||||
.proxy
|
.proxy
|
||||||
? myData.current.node?.template[
|
? myData.node?.template[
|
||||||
templateParam
|
templateParam
|
||||||
].proxy?.id
|
].proxy?.id
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
{myData.current.node?.template[templateParam]
|
{myData.node?.template[templateParam]
|
||||||
.display_name
|
.display_name
|
||||||
? myData.current.node.template[
|
? myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].display_name
|
].display_name
|
||||||
: myData.current.node?.template[
|
: myData.node?.template[
|
||||||
templateParam
|
templateParam
|
||||||
].name}
|
].name}
|
||||||
</span>
|
</span>
|
||||||
</ShadTooltip>
|
</ShadTooltip>
|
||||||
</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.current.node?.template[templateParam]
|
{myData.node?.template[templateParam]
|
||||||
.type === "str" &&
|
.type === "str" &&
|
||||||
!myData.current.node.template[templateParam]
|
!myData.node.template[templateParam]
|
||||||
.options ? (
|
.options ? (
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
{myData.current.node.template[templateParam]
|
{myData.node.template[templateParam]
|
||||||
.list ? (
|
.list ? (
|
||||||
<InputListComponent
|
<InputListComponent
|
||||||
editNode={true}
|
editNode={true}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={
|
value={
|
||||||
!myData.current.node.template[
|
!myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value ||
|
].value ||
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value === ""
|
].value === ""
|
||||||
? [""]
|
? [""]
|
||||||
: myData.current.node.template[
|
: myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value
|
].value
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +203,7 @@ const EditNodeModal = forwardRef(
|
||||||
handleOnNewValue(value, templateParam);
|
handleOnNewValue(value, templateParam);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : myData.current.node.template[
|
) : myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].multiline ? (
|
].multiline ? (
|
||||||
<TextAreaComponent
|
<TextAreaComponent
|
||||||
|
|
@ -212,7 +211,7 @@ const EditNodeModal = forwardRef(
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
editNode={true}
|
editNode={true}
|
||||||
value={
|
value={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value ?? ""
|
].value ?? ""
|
||||||
}
|
}
|
||||||
|
|
@ -226,12 +225,12 @@ const EditNodeModal = forwardRef(
|
||||||
editNode={true}
|
editNode={true}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
password={
|
password={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].password ?? false
|
].password ?? false
|
||||||
}
|
}
|
||||||
value={
|
value={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value ?? ""
|
].value ?? ""
|
||||||
}
|
}
|
||||||
|
|
@ -241,25 +240,25 @@ const EditNodeModal = forwardRef(
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : myData.current.node?.template[templateParam]
|
) : myData.node?.template[templateParam]
|
||||||
.type === "NestedDict" ? (
|
.type === "NestedDict" ? (
|
||||||
<div className=" w-full">
|
<div className=" w-full">
|
||||||
<DictComponent
|
<DictComponent
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
editNode={true}
|
editNode={true}
|
||||||
value={
|
value={
|
||||||
myData?.current?.node!.template[
|
myData.node!.template[
|
||||||
templateParam
|
templateParam
|
||||||
]?.value?.toString() === "{}"
|
]?.value?.toString() === "{}"
|
||||||
? {
|
? {
|
||||||
yourkey: "value",
|
yourkey: "value",
|
||||||
}
|
}
|
||||||
: myData.current.node!.template[
|
: myData.node!.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value
|
].value
|
||||||
}
|
}
|
||||||
onChange={(newValue) => {
|
onChange={(newValue) => {
|
||||||
myData.current.node!.template[
|
myData.node!.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value = newValue;
|
].value = newValue;
|
||||||
handleOnNewValue(newValue, templateParam);
|
handleOnNewValue(newValue, templateParam);
|
||||||
|
|
@ -267,32 +266,30 @@ const EditNodeModal = forwardRef(
|
||||||
id="editnode-div-dict-input"
|
id="editnode-div-dict-input"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : myData.current.node?.template[templateParam]
|
) : myData.node?.template[templateParam]
|
||||||
.type === "dict" ? (
|
.type === "dict" ? (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"max-h-48 w-full overflow-auto custom-scroll",
|
"max-h-48 w-full overflow-auto custom-scroll",
|
||||||
myData.current.node!.template[templateParam]
|
myData.node!.template[templateParam]
|
||||||
.value?.length > 1
|
.value?.length > 1
|
||||||
? "my-3"
|
? "my-3"
|
||||||
: ""
|
: ""
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<KeypairListComponent
|
<KeypairListComponent
|
||||||
dataValue={dataValue}
|
|
||||||
advanced={adv}
|
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
editNode={true}
|
editNode={true}
|
||||||
value={
|
value={
|
||||||
myData.current.node!.template[
|
myData.node!.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value?.length === 0 ||
|
].value?.length === 0 ||
|
||||||
!myData.current.node!.template[
|
!myData.node!.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value
|
].value
|
||||||
? [{ "": "" }]
|
? [{ "": "" }]
|
||||||
: convertObjToArray(
|
: convertObjToArray(
|
||||||
myData.current.node!.template[
|
myData.node!.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value
|
].value
|
||||||
)
|
)
|
||||||
|
|
@ -301,7 +298,7 @@ const EditNodeModal = forwardRef(
|
||||||
onChange={(newValue) => {
|
onChange={(newValue) => {
|
||||||
const valueToNumbers =
|
const valueToNumbers =
|
||||||
convertValuesToNumbers(newValue);
|
convertValuesToNumbers(newValue);
|
||||||
myData.current.node!.template[
|
myData.node!.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value = valueToNumbers;
|
].value = valueToNumbers;
|
||||||
setErrorDuplicateKey(
|
setErrorDuplicateKey(
|
||||||
|
|
@ -314,7 +311,7 @@ const EditNodeModal = forwardRef(
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : myData.current.node?.template[templateParam]
|
) : myData.node?.template[templateParam]
|
||||||
.type === "bool" ? (
|
.type === "bool" ? (
|
||||||
<div className="ml-auto">
|
<div className="ml-auto">
|
||||||
{" "}
|
{" "}
|
||||||
|
|
@ -322,7 +319,7 @@ const EditNodeModal = forwardRef(
|
||||||
id={"toggle-edit-" + index}
|
id={"toggle-edit-" + index}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
enabled={
|
enabled={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value
|
].value
|
||||||
}
|
}
|
||||||
|
|
@ -335,14 +332,14 @@ const EditNodeModal = forwardRef(
|
||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : myData.current.node?.template[templateParam]
|
) : myData.node?.template[templateParam]
|
||||||
.type === "float" ? (
|
.type === "float" ? (
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<FloatComponent
|
<FloatComponent
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
editNode={true}
|
editNode={true}
|
||||||
value={
|
value={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value ?? ""
|
].value ?? ""
|
||||||
}
|
}
|
||||||
|
|
@ -351,16 +348,16 @@ const EditNodeModal = forwardRef(
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : myData.current.node?.template[templateParam]
|
) : myData.node?.template[templateParam]
|
||||||
.type === "str" &&
|
.type === "str" &&
|
||||||
myData.current.node.template[templateParam]
|
myData.node.template[templateParam]
|
||||||
.options ? (
|
.options ? (
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<Dropdown
|
<Dropdown
|
||||||
numberOfOptions={nodeLength}
|
numberOfOptions={nodeLength}
|
||||||
editNode={true}
|
editNode={true}
|
||||||
options={
|
options={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].options
|
].options
|
||||||
}
|
}
|
||||||
|
|
@ -368,14 +365,14 @@ const EditNodeModal = forwardRef(
|
||||||
handleOnNewValue(value, templateParam)
|
handleOnNewValue(value, templateParam)
|
||||||
}
|
}
|
||||||
value={
|
value={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value ?? "Choose an option"
|
].value ?? "Choose an option"
|
||||||
}
|
}
|
||||||
id={"dropdown-edit-" + index}
|
id={"dropdown-edit-" + index}
|
||||||
></Dropdown>
|
></Dropdown>
|
||||||
</div>
|
</div>
|
||||||
) : myData.current.node?.template[templateParam]
|
) : myData.node?.template[templateParam]
|
||||||
.type === "int" ? (
|
.type === "int" ? (
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<IntComponent
|
<IntComponent
|
||||||
|
|
@ -383,7 +380,7 @@ const EditNodeModal = forwardRef(
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
editNode={true}
|
editNode={true}
|
||||||
value={
|
value={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value ?? ""
|
].value ?? ""
|
||||||
}
|
}
|
||||||
|
|
@ -392,14 +389,14 @@ const EditNodeModal = forwardRef(
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : myData.current.node?.template[templateParam]
|
) : myData.node?.template[templateParam]
|
||||||
.type === "file" ? (
|
.type === "file" ? (
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<InputFileComponent
|
<InputFileComponent
|
||||||
editNode={true}
|
editNode={true}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={
|
value={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value ?? ""
|
].value ?? ""
|
||||||
}
|
}
|
||||||
|
|
@ -407,12 +404,12 @@ const EditNodeModal = forwardRef(
|
||||||
handleOnNewValue(value, templateParam);
|
handleOnNewValue(value, templateParam);
|
||||||
}}
|
}}
|
||||||
fileTypes={
|
fileTypes={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].fileTypes
|
].fileTypes
|
||||||
}
|
}
|
||||||
suffixes={
|
suffixes={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].suffixes
|
].suffixes
|
||||||
}
|
}
|
||||||
|
|
@ -423,22 +420,22 @@ const EditNodeModal = forwardRef(
|
||||||
}}
|
}}
|
||||||
></InputFileComponent>
|
></InputFileComponent>
|
||||||
</div>
|
</div>
|
||||||
) : myData.current.node?.template[templateParam]
|
) : myData.node?.template[templateParam]
|
||||||
.type === "prompt" ? (
|
.type === "prompt" ? (
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<PromptAreaComponent
|
<PromptAreaComponent
|
||||||
readonly={
|
readonly={
|
||||||
myData.current.node?.flow ? true : false
|
myData.node?.flow ? true : false
|
||||||
}
|
}
|
||||||
field_name={templateParam}
|
field_name={templateParam}
|
||||||
editNode={true}
|
editNode={true}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
nodeClass={myData.current.node}
|
nodeClass={myData.node}
|
||||||
setNodeClass={(nodeClass) => {
|
setNodeClass={(nodeClass) => {
|
||||||
myData.current.node = nodeClass;
|
myData.node = nodeClass;
|
||||||
}}
|
}}
|
||||||
value={
|
value={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value ?? ""
|
].value ?? ""
|
||||||
}
|
}
|
||||||
|
|
@ -448,13 +445,13 @@ const EditNodeModal = forwardRef(
|
||||||
id={"prompt-area-edit" + index}
|
id={"prompt-area-edit" + index}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : myData.current.node?.template[templateParam]
|
) : myData.node?.template[templateParam]
|
||||||
.type === "code" ? (
|
.type === "code" ? (
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<CodeAreaComponent
|
<CodeAreaComponent
|
||||||
readonly={
|
readonly={
|
||||||
myData.current.node?.flow &&
|
myData.node?.flow &&
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].dynamic
|
].dynamic
|
||||||
? true
|
? true
|
||||||
|
|
@ -471,7 +468,7 @@ const EditNodeModal = forwardRef(
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
editNode={true}
|
editNode={true}
|
||||||
value={
|
value={
|
||||||
myData.current.node.template[
|
myData.node.template[
|
||||||
templateParam
|
templateParam
|
||||||
].value ?? ""
|
].value ?? ""
|
||||||
}
|
}
|
||||||
|
|
@ -481,7 +478,7 @@ const EditNodeModal = forwardRef(
|
||||||
id={"code-area-edit" + index}
|
id={"code-area-edit" + index}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : myData.current.node?.template[templateParam]
|
) : myData.node?.template[templateParam]
|
||||||
.type === "Any" ? (
|
.type === "Any" ? (
|
||||||
"-"
|
"-"
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -493,11 +490,11 @@ const EditNodeModal = forwardRef(
|
||||||
<ToggleShadComponent
|
<ToggleShadComponent
|
||||||
id={
|
id={
|
||||||
"show" +
|
"show" +
|
||||||
myData.current.node?.template[templateParam]
|
myData.node?.template[templateParam]
|
||||||
.name
|
.name
|
||||||
}
|
}
|
||||||
enabled={
|
enabled={
|
||||||
!myData.current.node?.template[
|
!myData.node?.template[
|
||||||
templateParam
|
templateParam
|
||||||
].advanced
|
].advanced
|
||||||
}
|
}
|
||||||
|
|
@ -524,8 +521,7 @@ const EditNodeModal = forwardRef(
|
||||||
id={"saveChangesBtn"}
|
id={"saveChangesBtn"}
|
||||||
className="mt-3"
|
className="mt-3"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const newData = cloneDeep(myData.current);
|
data.node = myData.node
|
||||||
myData.current = newData;
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
setTabsState((prev: FlowsState) => {
|
setTabsState((prev: FlowsState) => {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -90,8 +90,6 @@ export default function Page({
|
||||||
useState<OnSelectionChangeParams | null>(null);
|
useState<OnSelectionChangeParams | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// this effect is used to attach the global event handlers
|
|
||||||
|
|
||||||
const onKeyDown = (event: KeyboardEvent) => {
|
const onKeyDown = (event: KeyboardEvent) => {
|
||||||
if (!isWrappedWithClass(event, "nocopy")) {
|
if (!isWrappedWithClass(event, "nocopy")) {
|
||||||
if (
|
if (
|
||||||
|
|
@ -108,10 +106,9 @@ export default function Page({
|
||||||
lastCopiedSelection
|
lastCopiedSelection
|
||||||
) {
|
) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let bounds = reactFlowWrapper.current?.getBoundingClientRect();
|
|
||||||
paste(lastCopiedSelection, {
|
paste(lastCopiedSelection, {
|
||||||
x: position.x - bounds!.left,
|
x: position.x,
|
||||||
y: position.y - bounds!.top,
|
y: position.y,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
|
|
@ -133,18 +130,26 @@ export default function Page({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
document.addEventListener("keydown", onKeyDown);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("keydown", onKeyDown);
|
||||||
|
};
|
||||||
|
}, [lastCopiedSelection, lastSelection]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
const handleMouseMove = (event) => {
|
const handleMouseMove = (event) => {
|
||||||
setPosition({ x: event.clientX, y: event.clientY });
|
setPosition({ x: event.clientX, y: event.clientY });
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("keydown", onKeyDown);
|
|
||||||
document.addEventListener("mousemove", handleMouseMove);
|
document.addEventListener("mousemove", handleMouseMove);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener("keydown", onKeyDown);
|
|
||||||
document.removeEventListener("mousemove", handleMouseMove);
|
document.removeEventListener("mousemove", handleMouseMove);
|
||||||
};
|
};
|
||||||
}, [position, lastCopiedSelection, lastSelection]);
|
}, [position]);
|
||||||
|
|
||||||
const [selectionMenuVisible, setSelectionMenuVisible] = useState(false);
|
const [selectionMenuVisible, setSelectionMenuVisible] = useState(false);
|
||||||
|
|
||||||
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
||||||
|
|
@ -152,58 +157,34 @@ export default function Page({
|
||||||
const [nodes, setNodes, onNodesChange] = useNodesState(
|
const [nodes, setNodes, onNodesChange] = useNodesState(
|
||||||
flow.data?.nodes ?? []
|
flow.data?.nodes ?? []
|
||||||
);
|
);
|
||||||
|
|
||||||
const [edges, setEdges, onEdgesChange] = useEdgesState(
|
const [edges, setEdges, onEdgesChange] = useEdgesState(
|
||||||
flow.data?.edges ?? []
|
flow.data?.edges ?? []
|
||||||
);
|
);
|
||||||
const { setViewport } = useReactFlow();
|
const { setViewport } = useReactFlow();
|
||||||
const edgeUpdateSuccessful = useRef(true);
|
const edgeUpdateSuccessful = useRef(true);
|
||||||
useEffect(() => {
|
|
||||||
if (reactFlowInstance && flow) {
|
|
||||||
flow.data = reactFlowInstance.toObject();
|
|
||||||
updateFlow(flow);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [edges]);
|
|
||||||
//update flow when tabs change
|
//update flow when tabs change
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setNodes(flow?.data?.nodes ?? []);
|
setNodes(flow?.data?.nodes ?? []);
|
||||||
setEdges(flow?.data?.edges ?? []);
|
setEdges(flow?.data?.edges ?? []);
|
||||||
if (reactFlowInstance) {
|
if (reactFlowInstance) {
|
||||||
setViewport(flow?.data?.viewport ?? { x: 1, y: 0, zoom: 0.5 });
|
setViewport(flow?.data?.viewport ?? { x: 1, y: 0, zoom: 0.5 });
|
||||||
reactFlowInstance.fitView();
|
|
||||||
}
|
}
|
||||||
}, [flow, reactFlowInstance, setEdges, setNodes, setViewport]);
|
}, [flow, reactFlowInstance]);
|
||||||
//set extra sidebar
|
|
||||||
useEffect(() => {
|
|
||||||
setExtraComponent(<ExtraSidebar />);
|
|
||||||
setExtraNavigation({ title: "Components" });
|
|
||||||
}, [setExtraComponent, setExtraNavigation]);
|
|
||||||
|
|
||||||
const [seconds, setSeconds] = useState(0);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const index = flows.findIndex((flowId) => flowId.id === flow.id);
|
const index = flows.findIndex((flowId) => flowId.id === flow.id);
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
setSeconds((prevSeconds) => {
|
saveFlow(
|
||||||
let updatedSeconds = prevSeconds + 1;
|
{
|
||||||
|
...flows[index]!,
|
||||||
if (updatedSeconds % 30 === 0) {
|
data: reactFlowInstance ? reactFlowInstance!.toObject() : flow!.data,
|
||||||
saveFlow(
|
},
|
||||||
{
|
true
|
||||||
...flows[index]!,
|
);
|
||||||
data: reactFlowInstance
|
}, 30000);
|
||||||
? reactFlowInstance!.toObject()
|
|
||||||
: flow!.data,
|
|
||||||
},
|
|
||||||
true
|
|
||||||
);
|
|
||||||
updatedSeconds = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return updatedSeconds;
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
|
|
@ -212,11 +193,11 @@ export default function Page({
|
||||||
|
|
||||||
const onEdgesChangeMod = useCallback(
|
const onEdgesChangeMod = useCallback(
|
||||||
(change: EdgeChange[]) => {
|
(change: EdgeChange[]) => {
|
||||||
onEdgesChange(change);
|
updateFlow({
|
||||||
setNodes((node) => {
|
...flow!,
|
||||||
let newX = _.cloneDeep(node);
|
data: reactFlowInstance ? reactFlowInstance!.toObject() : flow!.data,
|
||||||
return newX;
|
|
||||||
});
|
});
|
||||||
|
onEdgesChange(change);
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
setTabsState((prev: FlowsState) => {
|
setTabsState((prev: FlowsState) => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -383,6 +364,9 @@ export default function Page({
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setExtraComponent(<ExtraSidebar />);
|
||||||
|
setExtraNavigation({ title: "Components" });
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (tabsState && tabsState[flow.id]?.isPending) {
|
if (tabsState && tabsState[flow.id]?.isPending) {
|
||||||
saveFlow({
|
saveFlow({
|
||||||
|
|
@ -520,6 +504,7 @@ export default function Page({
|
||||||
isVisible={selectionMenuVisible}
|
isVisible={selectionMenuVisible}
|
||||||
nodes={lastSelection?.nodes}
|
nodes={lastSelection?.nodes}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
takeSnapshot();
|
||||||
if (
|
if (
|
||||||
validateSelection(lastSelection!, edges).length === 0
|
validateSelection(lastSelection!, edges).length === 0
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ export default function ExtraSidebar(): JSX.Element {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (getFilterEdge.length === 0 && search === "") {
|
if (getFilterEdge.length === 0 && search === "") {
|
||||||
setFilterData(data);
|
setFilterData(data);
|
||||||
setFilterEdge([]);
|
|
||||||
setSearch("");
|
setSearch("");
|
||||||
}
|
}
|
||||||
}, [getFilterEdge]);
|
}, [getFilterEdge]);
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,10 @@ import {
|
||||||
updateFlowPosition,
|
updateFlowPosition,
|
||||||
} from "../../../../utils/reactflowUtils";
|
} from "../../../../utils/reactflowUtils";
|
||||||
import { classNames } from "../../../../utils/utils";
|
import { classNames } from "../../../../utils/utils";
|
||||||
|
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
|
||||||
|
|
||||||
export default function NodeToolbarComponent({
|
export default function NodeToolbarComponent({
|
||||||
data,
|
data,
|
||||||
setData,
|
|
||||||
deleteNode,
|
deleteNode,
|
||||||
position,
|
position,
|
||||||
setShowNode,
|
setShowNode,
|
||||||
|
|
@ -66,6 +66,7 @@ export default function NodeToolbarComponent({
|
||||||
const isGroup = data.node?.flow ? true : false;
|
const isGroup = data.node?.flow ? true : false;
|
||||||
|
|
||||||
const { paste, saveComponent, version, flows } = useContext(FlowsContext);
|
const { paste, saveComponent, version, flows } = useContext(FlowsContext);
|
||||||
|
const { takeSnapshot } = useContext(undoRedoContext);
|
||||||
const reactFlowInstance = useReactFlow();
|
const reactFlowInstance = useReactFlow();
|
||||||
const [showModalAdvanced, setShowModalAdvanced] = useState(false);
|
const [showModalAdvanced, setShowModalAdvanced] = useState(false);
|
||||||
const [showconfirmShare, setShowconfirmShare] = useState(false);
|
const [showconfirmShare, setShowconfirmShare] = useState(false);
|
||||||
|
|
@ -84,6 +85,7 @@ export default function NodeToolbarComponent({
|
||||||
setShowModalAdvanced(true);
|
setShowModalAdvanced(true);
|
||||||
break;
|
break;
|
||||||
case "show":
|
case "show":
|
||||||
|
takeSnapshot();
|
||||||
setShowNode((prev) => !prev);
|
setShowNode((prev) => !prev);
|
||||||
updateNodeInternals(data.id);
|
updateNodeInternals(data.id);
|
||||||
break;
|
break;
|
||||||
|
|
@ -99,6 +101,7 @@ export default function NodeToolbarComponent({
|
||||||
case "disabled":
|
case "disabled":
|
||||||
break;
|
break;
|
||||||
case "ungroup":
|
case "ungroup":
|
||||||
|
takeSnapshot();
|
||||||
updateFlowPosition(position, data.node?.flow!);
|
updateFlowPosition(position, data.node?.flow!);
|
||||||
expandGroupNode(data, reactFlowInstance, getNodeId);
|
expandGroupNode(data, reactFlowInstance, getNodeId);
|
||||||
break;
|
break;
|
||||||
|
|
@ -301,7 +304,6 @@ export default function NodeToolbarComponent({
|
||||||
</ConfirmationModal>
|
</ConfirmationModal>
|
||||||
<EditNodeModal
|
<EditNodeModal
|
||||||
data={data}
|
data={data}
|
||||||
setData={setData}
|
|
||||||
nodeLength={nodeLength}
|
nodeLength={nodeLength}
|
||||||
open={showModalAdvanced}
|
open={showModalAdvanced}
|
||||||
setOpen={setShowModalAdvanced}
|
setOpen={setShowModalAdvanced}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ export type DropDownComponentType = {
|
||||||
};
|
};
|
||||||
export type ParameterComponentType = {
|
export type ParameterComponentType = {
|
||||||
data: NodeDataType;
|
data: NodeDataType;
|
||||||
setData: (value: NodeDataType) => void;
|
|
||||||
title: string;
|
title: string;
|
||||||
id: sourceHandleType | targetHandleType;
|
id: sourceHandleType | targetHandleType;
|
||||||
color: string;
|
color: string;
|
||||||
|
|
@ -69,8 +68,6 @@ export type KeyPairListComponentType = {
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
editNode?: boolean;
|
editNode?: boolean;
|
||||||
duplicateKey?: boolean;
|
duplicateKey?: boolean;
|
||||||
advanced?: boolean | null;
|
|
||||||
dataValue?: any;
|
|
||||||
editNodeModal?: boolean;
|
editNodeModal?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -470,7 +467,6 @@ export type fileCardPropsType = {
|
||||||
export type nodeToolbarPropsType = {
|
export type nodeToolbarPropsType = {
|
||||||
data: NodeDataType;
|
data: NodeDataType;
|
||||||
deleteNode: (idx: string) => void;
|
deleteNode: (idx: string) => void;
|
||||||
setData: (newState: NodeDataType) => void;
|
|
||||||
position: XYPosition;
|
position: XYPosition;
|
||||||
setShowNode: (boolean: any) => void;
|
setShowNode: (boolean: any) => void;
|
||||||
numberOfHandles: boolean[] | [];
|
numberOfHandles: boolean[] | [];
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ export type NodeType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NodeDataType = {
|
export type NodeDataType = {
|
||||||
|
showNode?: boolean;
|
||||||
type: string;
|
type: string;
|
||||||
node?: APIClassType;
|
node?: APIClassType;
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
||||||
|
|
@ -934,8 +934,6 @@ export function expandGroupNode(
|
||||||
updateEdgesIds(flowEdges, idsMap);
|
updateEdgesIds(flowEdges, idsMap);
|
||||||
const gNodes: NodeType[] = flow?.data?.nodes!;
|
const gNodes: NodeType[] = flow?.data?.nodes!;
|
||||||
const gEdges = flow!.data!.edges;
|
const gEdges = flow!.data!.edges;
|
||||||
//TODO update ids of intern nodes and proxy on edges before expanding
|
|
||||||
console.log(gEdges);
|
|
||||||
//redirect edges to correct proxy node
|
//redirect edges to correct proxy node
|
||||||
let updatedEdges: Edge[] = [];
|
let updatedEdges: Edge[] = [];
|
||||||
flowEdges.forEach((edge) => {
|
flowEdges.forEach((edge) => {
|
||||||
|
|
@ -1046,7 +1044,6 @@ export function getGroupStatus(
|
||||||
let status = { valid: true, params: "Built sucessfully ✨" };
|
let status = { valid: true, params: "Built sucessfully ✨" };
|
||||||
const { nodes } = flow.data!;
|
const { nodes } = flow.data!;
|
||||||
const ids = nodes.map((n: NodeType) => n.data.id);
|
const ids = nodes.map((n: NodeType) => n.data.id);
|
||||||
ids.forEach((id) => console.log(ssData[id]));
|
|
||||||
ids.forEach((id) => {
|
ids.forEach((id) => {
|
||||||
if (!ssData[id]) {
|
if (!ssData[id]) {
|
||||||
status = ssData[id];
|
status = ssData[id];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue