Merge branch 'modalRefactor' into python_custom_node_component

This commit is contained in:
Lucas Oliveira 2023-07-16 17:09:56 -03:00
commit 8e6e2e9708
30 changed files with 1625 additions and 1894 deletions

View file

@ -147,9 +147,9 @@
} }
}, },
"node_modules/@babel/compat-data": { "node_modules/@babel/compat-data": {
"version": "7.22.6", "version": "7.22.9",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz",
"integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==", "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==",
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
} }
@ -194,10 +194,18 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@babel/core/node_modules/@nicolo-ribaudo/semver-v6": {
"version": "6.3.3",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
"integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/generator": { "node_modules/@babel/generator": {
"version": "7.22.7", "version": "7.22.9",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.7.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.9.tgz",
"integrity": "sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ==", "integrity": "sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==",
"dependencies": { "dependencies": {
"@babel/types": "^7.22.5", "@babel/types": "^7.22.5",
"@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/gen-mapping": "^0.3.2",
@ -209,15 +217,15 @@
} }
}, },
"node_modules/@babel/helper-compilation-targets": { "node_modules/@babel/helper-compilation-targets": {
"version": "7.22.6", "version": "7.22.9",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz",
"integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==", "integrity": "sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==",
"dependencies": { "dependencies": {
"@babel/compat-data": "^7.22.6", "@babel/compat-data": "^7.22.9",
"@babel/helper-validator-option": "^7.22.5", "@babel/helper-validator-option": "^7.22.5",
"@nicolo-ribaudo/semver-v6": "^6.3.3",
"browserslist": "^4.21.9", "browserslist": "^4.21.9",
"lru-cache": "^5.1.1" "lru-cache": "^5.1.1",
"semver": "^6.3.1"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@ -226,6 +234,14 @@
"@babel/core": "^7.0.0" "@babel/core": "^7.0.0"
} }
}, },
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/helper-environment-visitor": { "node_modules/@babel/helper-environment-visitor": {
"version": "7.22.5", "version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz",
@ -269,21 +285,21 @@
} }
}, },
"node_modules/@babel/helper-module-transforms": { "node_modules/@babel/helper-module-transforms": {
"version": "7.22.5", "version": "7.22.9",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz",
"integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==",
"dependencies": { "dependencies": {
"@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.5",
"@babel/helper-module-imports": "^7.22.5", "@babel/helper-module-imports": "^7.22.5",
"@babel/helper-simple-access": "^7.22.5", "@babel/helper-simple-access": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6",
"@babel/helper-validator-identifier": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5"
"@babel/template": "^7.22.5",
"@babel/traverse": "^7.22.5",
"@babel/types": "^7.22.5"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0"
} }
}, },
"node_modules/@babel/helper-simple-access": { "node_modules/@babel/helper-simple-access": {
@ -1149,12 +1165,12 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
}, },
"node_modules/@mui/private-theming": { "node_modules/@mui/private-theming": {
"version": "5.13.1", "version": "5.13.7",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.13.1.tgz", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.13.7.tgz",
"integrity": "sha512-HW4npLUD9BAkVppOUZHeO1FOKUJWAwbpy0VQoGe3McUYTlck1HezGHQCfBQ5S/Nszi7EViqiimECVl9xi+/WjQ==", "integrity": "sha512-qbSr+udcij5F9dKhGX7fEdx2drXchq7htLNr2Qg2Ma+WJ6q0ERlEqGSBiPiVDJkptcjeVL4DGmcf1wl5+vD4EA==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.21.0", "@babel/runtime": "^7.22.5",
"@mui/utils": "^5.13.1", "@mui/utils": "^5.13.7",
"prop-types": "^15.8.1" "prop-types": "^15.8.1"
}, },
"engines": { "engines": {
@ -1175,9 +1191,9 @@
} }
}, },
"node_modules/@mui/private-theming/node_modules/@babel/runtime": { "node_modules/@mui/private-theming/node_modules/@babel/runtime": {
"version": "7.22.5", "version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
"integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
"dependencies": { "dependencies": {
"regenerator-runtime": "^0.13.11" "regenerator-runtime": "^0.13.11"
}, },
@ -1185,6 +1201,33 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@mui/private-theming/node_modules/@mui/utils": {
"version": "5.13.7",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.13.7.tgz",
"integrity": "sha512-/3BLptG/q0u36eYED7Nhf4fKXmcKb6LjjT7ZMwhZIZSdSxVqDqSTmATW3a56n3KEPQUXCU9TpxAfCBQhs6brVA==",
"dependencies": {
"@babel/runtime": "^7.22.5",
"@types/prop-types": "^15.7.5",
"@types/react-is": "^18.2.1",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui"
},
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0"
}
},
"node_modules/@mui/private-theming/node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/@mui/styled-engine": { "node_modules/@mui/styled-engine": {
"version": "5.13.2", "version": "5.13.2",
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz", "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz",
@ -1217,9 +1260,9 @@
} }
}, },
"node_modules/@mui/styled-engine/node_modules/@babel/runtime": { "node_modules/@mui/styled-engine/node_modules/@babel/runtime": {
"version": "7.22.5", "version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
"integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
"dependencies": { "dependencies": {
"regenerator-runtime": "^0.13.11" "regenerator-runtime": "^0.13.11"
}, },
@ -1272,9 +1315,9 @@
} }
}, },
"node_modules/@mui/system/node_modules/@babel/runtime": { "node_modules/@mui/system/node_modules/@babel/runtime": {
"version": "7.22.5", "version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
"integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
"dependencies": { "dependencies": {
"regenerator-runtime": "^0.13.11" "regenerator-runtime": "^0.13.11"
}, },
@ -1323,9 +1366,9 @@
} }
}, },
"node_modules/@mui/utils/node_modules/@babel/runtime": { "node_modules/@mui/utils/node_modules/@babel/runtime": {
"version": "7.22.5", "version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
"integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
"dependencies": { "dependencies": {
"regenerator-runtime": "^0.13.11" "regenerator-runtime": "^0.13.11"
}, },
@ -1338,14 +1381,6 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
}, },
"node_modules/@nicolo-ribaudo/semver-v6": {
"version": "6.3.3",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
"integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@nodelib/fs.scandir": { "node_modules/@nodelib/fs.scandir": {
"version": "2.1.5", "version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -3542,7 +3577,7 @@
"version": "16.18.12", "version": "16.18.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.12.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.12.tgz",
"integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw==", "integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw==",
"devOptional": true "dev": true
}, },
"node_modules/@types/parse-json": { "node_modules/@types/parse-json": {
"version": "4.0.0", "version": "4.0.0",
@ -5094,9 +5129,9 @@
"integrity": "sha512-ae0mA+Qiqp6C29pqZX3fQgK+F91+F7wobM/v8DRzDqJdZJELXiFUx4PP4pK/mzUS0xkiSEx3Ncd9gr69jg3YsQ==" "integrity": "sha512-ae0mA+Qiqp6C29pqZX3fQgK+F91+F7wobM/v8DRzDqJdZJELXiFUx4PP4pK/mzUS0xkiSEx3Ncd9gr69jg3YsQ=="
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.4.440", "version": "1.4.457",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.440.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.457.tgz",
"integrity": "sha512-r6dCgNpRhPwiWlxbHzZQ/d9swfPaEJGi8ekqRBwQYaR3WmA5VkqQfBWSDDjuJU1ntO+W9tHx8OHV/96Q8e0dVw==" "integrity": "sha512-/g3UyNDmDd6ebeWapmAoiyy+Sy2HyJ+/X8KyvNeHfKRFfHaA2W8oF5fxD5F3tjBDcjpwo0iek6YNgxNXDBoEtA=="
}, },
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
@ -5588,6 +5623,7 @@
"version": "2.3.2", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"optional": true, "optional": true,
"os": [ "os": [
@ -8025,9 +8061,9 @@
} }
}, },
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.12", "version": "2.0.13",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
"integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==" "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ=="
}, },
"node_modules/normalize-path": { "node_modules/normalize-path": {
"version": "3.0.0", "version": "3.0.0",

View file

@ -1,3 +1,4 @@
import { cloneDeep } from "lodash";
import { Info } from "lucide-react"; import { Info } from "lucide-react";
import React, { useContext, useEffect, useRef, useState } from "react"; import React, { useContext, useEffect, useRef, useState } from "react";
import { Handle, Position, useUpdateNodeInternals } from "reactflow"; import { Handle, Position, useUpdateNodeInternals } from "reactflow";
@ -13,7 +14,6 @@ import PromptAreaComponent from "../../../../components/promptComponent";
import TextAreaComponent from "../../../../components/textAreaComponent"; import TextAreaComponent from "../../../../components/textAreaComponent";
import ToggleShadComponent from "../../../../components/toggleShadComponent"; import ToggleShadComponent from "../../../../components/toggleShadComponent";
import { MAX_LENGTH_TO_SCROLL_TOOLTIP } from "../../../../constants"; import { MAX_LENGTH_TO_SCROLL_TOOLTIP } from "../../../../constants";
import { PopUpContext } from "../../../../contexts/popUpContext";
import { TabsContext } from "../../../../contexts/tabsContext"; import { TabsContext } from "../../../../contexts/tabsContext";
import { typesContext } from "../../../../contexts/typesContext"; import { typesContext } from "../../../../contexts/typesContext";
import { ParameterComponentType } from "../../../../types/components"; import { ParameterComponentType } from "../../../../types/components";
@ -32,6 +32,7 @@ export default function ParameterComponent({
left, left,
id, id,
data, data,
setData,
tooltipTitle, tooltipTitle,
title, title,
color, color,
@ -47,7 +48,6 @@ export default function ParameterComponent({
const infoHtml = useRef(null); const infoHtml = useRef(null);
const updateNodeInternals = useUpdateNodeInternals(); const updateNodeInternals = useUpdateNodeInternals();
const [position, setPosition] = useState(0); const [position, setPosition] = useState(0);
const { closePopUp } = useContext(PopUpContext);
const { setTabsState, tabId, save } = useContext(TabsContext); const { setTabsState, tabId, save } = useContext(TabsContext);
useEffect(() => { useEffect(() => {
@ -61,15 +61,16 @@ export default function ParameterComponent({
updateNodeInternals(data.id); updateNodeInternals(data.id);
}, [data.id, position, updateNodeInternals]); }, [data.id, position, updateNodeInternals]);
useEffect(() => {}, [closePopUp, data.node.template]);
const { reactFlowInstance } = useContext(typesContext); const { reactFlowInstance } = useContext(typesContext);
let disabled = let disabled =
reactFlowInstance?.getEdges().some((e) => e.targetHandle === id) ?? false; reactFlowInstance?.getEdges().some((e) => e.targetHandle === id) ?? false;
const [myData, setMyData] = useState(useContext(typesContext).data);
const { data: myData } = useContext(typesContext);
const handleOnNewValue = (newValue: any) => { const handleOnNewValue = (newValue: any) => {
data.node.template[name].value = newValue; let newData = cloneDeep(data);
newData.node.template[name].value = newValue;
setData(newData);
// Set state to pending // Set state to pending
setTabsState((prev) => { setTabsState((prev) => {
return { return {

View file

@ -5,9 +5,7 @@ import ShadTooltip from "../../components/ShadTooltipComponent";
import Tooltip from "../../components/TooltipComponent"; import Tooltip from "../../components/TooltipComponent";
import { useSSE } from "../../contexts/SSEContext"; import { useSSE } from "../../contexts/SSEContext";
import { alertContext } from "../../contexts/alertContext"; import { alertContext } from "../../contexts/alertContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { typesContext } from "../../contexts/typesContext"; import { typesContext } from "../../contexts/typesContext";
import NodeModal from "../../modals/NodeModal";
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent"; import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
import { NodeDataType } from "../../types/flow"; import { NodeDataType } from "../../types/flow";
import { import {
@ -19,17 +17,16 @@ import {
import ParameterComponent from "./components/parameterComponent"; import ParameterComponent from "./components/parameterComponent";
export default function GenericNode({ export default function GenericNode({
data, data: olddata,
selected, selected,
}: { }: {
data: NodeDataType; data: NodeDataType;
selected: boolean; selected: boolean;
}) { }) {
const [data, setData] = useState(olddata);
const { setErrorData } = useContext(alertContext); const { setErrorData } = useContext(alertContext);
const showError = useRef(true); const showError = useRef(true);
const { types, deleteNode } = useContext(typesContext); const { types, deleteNode, reactFlowInstance } = useContext(typesContext);
const { closePopUp, openPopUp } = useContext(PopUpContext);
// any to avoid type conflict // any to avoid type conflict
const Icon: any = const Icon: any =
nodeIconsLucide[data.type] || nodeIconsLucide[types[data.type]]; nodeIconsLucide[data.type] || nodeIconsLucide[types[data.type]];
@ -37,12 +34,9 @@ export default function GenericNode({
// State for outline color // State for outline color
const { sseData, isBuilding } = useSSE(); const { sseData, isBuilding } = useSSE();
const refHtml = useRef(null); const refHtml = useRef(null);
useEffect(() => {
// useEffect(() => { olddata.node = data.node;
// if (reactFlowInstance) { }, [data, reactFlowInstance]);
// setParams(Object.values(reactFlowInstance.toObject()));
// }
// }, [save]);
// 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(() => {
@ -67,13 +61,12 @@ export default function GenericNode({
deleteNode(data.id); deleteNode(data.id);
return; return;
} }
useEffect(() => {}, [closePopUp, data.node.template]);
return ( return (
<> <>
<NodeToolbar> <NodeToolbar>
<NodeToolbarComponent <NodeToolbarComponent
data={data} data={data}
openPopUp={openPopUp} setData={setData}
deleteNode={deleteNode} deleteNode={deleteNode}
></NodeToolbarComponent> ></NodeToolbarComponent>
</NodeToolbar> </NodeToolbar>
@ -101,15 +94,6 @@ export default function GenericNode({
</ShadTooltip> </ShadTooltip>
</div> </div>
</div> </div>
<div className="round-button-div">
<button
className="relative"
onClick={(event) => {
event.preventDefault();
openPopUp(<NodeModal data={data} />);
}}
></button>
</div>
<div className="round-button-div"> <div className="round-button-div">
<div> <div>
<Tooltip <Tooltip
@ -198,6 +182,7 @@ export default function GenericNode({
!data.node.template[t].advanced ? ( !data.node.template[t].advanced ? (
<ParameterComponent <ParameterComponent
data={data} data={data}
setData={setData}
color={ color={
nodeColors[types[data.node.template[t].type]] ?? nodeColors[types[data.node.template[t].type]] ??
nodeColors[data.node.template[t].type] ?? nodeColors[data.node.template[t].type] ??
@ -242,9 +227,12 @@ export default function GenericNode({
> >
{" "} {" "}
</div> </div>
{data.node.base_classes?.length > 0 && ( {/* <div className="px-5 py-2 mt-2 text-center">
Output
</div> */}
<ParameterComponent <ParameterComponent
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
@ -256,7 +244,6 @@ export default function GenericNode({
type={data.node.base_classes.join("|")} type={data.node.base_classes.join("|")}
left={false} left={false}
/> />
)}
</> </>
</div> </div>
</div> </div>

View file

@ -16,6 +16,8 @@ export default function AccordionComponent({
open.length === 0 ? "" : getOpenAccordion() open.length === 0 ? "" : getOpenAccordion()
); );
console.log(open);
function getOpenAccordion() { function getOpenAccordion() {
let value = ""; let value = "";
open.forEach((el) => { open.forEach((el) => {

View file

@ -62,7 +62,10 @@ export const EditFlowSettings: React.FC<InputProps> = ({
/> />
</Label> </Label>
<Label> <Label>
<span className="font-medium">Description (optional)</span> <div className="edit-flow-arrangement mt-3">
<span className="font-medium ">Description (optional)</span>
</div>
<Textarea <Textarea
name="description" name="description"
id="description" id="description"

View file

@ -1,6 +1,5 @@
import { useContext, useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext"; import CodeAreaModal from "../../modals/codeAreaModal";
import CodeAreaModal from "../../modals/codeAreaModal/v2";
import { CodeAreaComponentType } from "../../types/components"; import { CodeAreaComponentType } from "../../types/components";
import { ExternalLink } from "lucide-react"; import { ExternalLink } from "lucide-react";
@ -11,11 +10,12 @@ export default function CodeAreaComponent({
disabled, disabled,
editNode = false, editNode = false,
nodeClass, nodeClass,
setNodeClass,
dynamic, dynamic,
setNodeClass,
}: CodeAreaComponentType) { }: CodeAreaComponentType) {
const [myValue, setMyValue] = useState(value); const [myValue, setMyValue] = useState(
const { openPopUp } = useContext(PopUpContext); typeof value == "string" ? value : JSON.stringify(value)
);
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
setMyValue(""); setMyValue("");
@ -28,15 +28,7 @@ export default function CodeAreaComponent({
}, [value]); }, [value]);
return ( return (
<div <div className={disabled ? "pointer-events-none w-full " : " w-full"}>
className={
disabled ? "pointer-events-none w-full cursor-not-allowed" : "w-full"
}
>
<div className="flex w-full items-center">
<span
onClick={() => {
openPopUp(
<CodeAreaModal <CodeAreaModal
dynamic={dynamic} dynamic={dynamic}
value={myValue} value={myValue}
@ -46,43 +38,26 @@ export default function CodeAreaComponent({
setMyValue(t); setMyValue(t);
onChange(t); onChange(t);
}} }}
/> >
); <div className="flex w-full items-center">
}} <span
className={ className={
editNode editNode
? "input-edit-node input-dialog " ? "input-edit-node input-dialog"
: "input-dialog input-primary " + : (disabled ? " input-disable input-ring " : "") +
(disabled ? "input-disable" : "") " input-primary text-muted-foreground "
} }
> >
{myValue !== "" ? myValue : "Type something..."} {myValue !== "" ? myValue : "Type something..."}
</span> </span>
<button
onClick={() => {
openPopUp(
<CodeAreaModal
key={myValue}
dynamic={dynamic}
setNodeClass={setNodeClass}
value={myValue}
nodeClass={nodeClass}
setValue={(t: string) => {
setMyValue(t);
onChange(t);
}}
/>
);
}}
>
{!editNode && ( {!editNode && (
<ExternalLink <ExternalLink
strokeWidth={1.5} strokeWidth={1.5}
className="ml-3 h-6 w-6 hover:text-accent-foreground" className="ml-3 h-6 w-6 hover:text-accent-foreground"
/> />
)} )}
</button>
</div> </div>
</CodeAreaModal>
</div> </div>
); );
} }

View file

@ -1,7 +1,6 @@
import { Listbox, Transition } from "@headlessui/react"; import { Listbox, Transition } from "@headlessui/react";
import { Check, ChevronsUpDown } from "lucide-react"; import { Check, ChevronsUpDown } from "lucide-react";
import { Fragment, useContext, useEffect, useState } from "react"; import { Fragment, useEffect, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import { DropDownComponentType } from "../../types/components"; import { DropDownComponentType } from "../../types/components";
import { classNames } from "../../utils"; import { classNames } from "../../utils";
@ -13,15 +12,13 @@ export default function Dropdown({
numberOfOptions = 0, numberOfOptions = 0,
apiModal = false, apiModal = false,
}: DropDownComponentType) { }: DropDownComponentType) {
const { closePopUp } = useContext(PopUpContext);
let [internalValue, setInternalValue] = useState( let [internalValue, setInternalValue] = useState(
value === "" || !value ? "Choose an option" : value value === "" || !value ? "Choose an option" : value
); );
useEffect(() => { useEffect(() => {
setInternalValue(value === "" || !value ? "Choose an option" : value); setInternalValue(value === "" || !value ? "Choose an option" : value);
}, [closePopUp]); }, [value]);
return ( return (
<> <>

View file

@ -1,5 +1,4 @@
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { FloatComponentType } from "../../types/components"; import { FloatComponentType } from "../../types/components";
@ -10,9 +9,7 @@ export default function FloatComponent({
disabled, disabled,
editNode = false, editNode = false,
}: FloatComponentType) { }: FloatComponentType) {
const [myValue, setMyValue] = useState(value ?? "");
const { setDisableCopyPaste } = useContext(TabsContext); const { setDisableCopyPaste } = useContext(TabsContext);
const { closePopUp } = useContext(PopUpContext);
const step = 0.1; const step = 0.1;
const min = 0; const min = 0;
@ -20,15 +17,10 @@ export default function FloatComponent({
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
setMyValue("");
onChange(""); onChange("");
} }
}, [disabled, onChange]); }, [disabled, onChange]);
useEffect(() => {
setMyValue(value);
}, [closePopUp]);
return ( return (
<div className={"w-full " + (disabled ? "float-component-pointer" : "")}> <div className={"w-full " + (disabled ? "float-component-pointer" : "")}>
<input <input
@ -50,7 +42,7 @@ export default function FloatComponent({
} }
}} }}
max={max} max={max}
value={myValue} value={value ?? ""}
className={ className={
editNode editNode
? "input-edit-node" ? "input-edit-node"
@ -60,7 +52,6 @@ export default function FloatComponent({
editNode ? "Number 0 to 1" : "Type a number from zero to one" editNode ? "Number 0 to 1" : "Type a number from zero to one"
} }
onChange={(e) => { onChange={(e) => {
setMyValue(e.target.value);
onChange(e.target.value); onChange(e.target.value);
}} }}
/> />

View file

@ -6,8 +6,7 @@ import {
Settings2, Settings2,
Undo, Undo,
} from "lucide-react"; } from "lucide-react";
import { useContext } from "react"; import { useContext, useState } from "react";
import { PopUpContext } from "../../../../contexts/popUpContext";
import { TabsContext } from "../../../../contexts/tabsContext"; import { TabsContext } from "../../../../contexts/tabsContext";
import { import {
DropdownMenu, DropdownMenu,
@ -26,8 +25,8 @@ import { Button } from "../../../ui/button";
export const MenuBar = ({ flows, tabId }) => { export const MenuBar = ({ flows, tabId }) => {
const { updateFlow, setTabId, addFlow } = useContext(TabsContext); const { updateFlow, setTabId, addFlow } = useContext(TabsContext);
const { setErrorData } = useContext(alertContext); const { setErrorData } = useContext(alertContext);
const { openPopUp } = useContext(PopUpContext);
const { undo, redo } = useContext(undoRedoContext); const { undo, redo } = useContext(undoRedoContext);
const [openSettings, setOpenSettings] = useState(false);
const navigate = useNavigate(); const navigate = useNavigate();
@ -69,15 +68,17 @@ export const MenuBar = ({ flows, tabId }) => {
<Plus className="header-menu-options" /> <Plus className="header-menu-options" />
New New
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuItem <DropdownMenuItem
onClick={() => { onClick={() => {
openPopUp(<FlowSettingsModal />); setOpenSettings(true);
}} }}
className="cursor-pointer" className="cursor-pointer"
> >
<Settings2 className="header-menu-options " /> <Settings2 className="header-menu-options " />
Settings Settings
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuItem <DropdownMenuItem
onClick={() => { onClick={() => {
undo(); undo();
@ -96,32 +97,12 @@ export const MenuBar = ({ flows, tabId }) => {
<Redo className="header-menu-options " /> <Redo className="header-menu-options " />
Redo Redo
</DropdownMenuItem> </DropdownMenuItem>
{/* <DropdownMenuSeparator /> */}
{/* <DropdownMenuLabel>Projects</DropdownMenuLabel> */}
{/* <DropdownMenuRadioGroup className="max-h-full overflow-scroll"
value={tabId}
onValueChange={(value) => {
setTabId(value);
}}
>
{flows.map((flow, idx) => {
return (
<Link
to={"/flow/" + flow.id}
className="flex w-full items-center"
>
<DropdownMenuRadioItem
value={flow.id}
className="flex-1 w-full inline-block truncate break-words mr-2"
>
{flow.name}
</DropdownMenuRadioItem>
</Link>
);
})}
</DropdownMenuRadioGroup> */}
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
<FlowSettingsModal
open={openSettings}
setOpen={setOpenSettings}
></FlowSettingsModal>
</div> </div>
</div> </div>
); );

View file

@ -1,5 +1,4 @@
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { InputComponentType } from "../../types/components"; import { InputComponentType } from "../../types/components";
import { classNames } from "../../utils"; import { classNames } from "../../utils";
@ -12,26 +11,19 @@ export default function InputComponent({
password, password,
editNode = false, editNode = false,
}: InputComponentType) { }: InputComponentType) {
const [myValue, setMyValue] = useState(value ?? "");
const [pwdVisible, setPwdVisible] = useState(false); const [pwdVisible, setPwdVisible] = useState(false);
const { setDisableCopyPaste } = useContext(TabsContext); const { setDisableCopyPaste } = useContext(TabsContext);
const { closePopUp } = useContext(PopUpContext);
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
setMyValue("");
onChange(""); onChange("");
} }
}, [disabled, onChange]); }, [disabled, onChange]);
useEffect(() => {
setMyValue(value ?? "");
}, [closePopUp]);
return ( return (
<div className={disabled ? "input-component-div" : "relative"}> <div className={disabled ? "input-component-div" : "relative"}>
<input <input
value={myValue} value={value}
onFocus={() => { onFocus={() => {
if (disableCopyPaste) setDisableCopyPaste(true); if (disableCopyPaste) setDisableCopyPaste(true);
}} }}
@ -40,16 +32,13 @@ export default function InputComponent({
}} }}
className={classNames( className={classNames(
disabled ? " input-disable " : "", disabled ? " input-disable " : "",
password && !pwdVisible && myValue !== "" password && !pwdVisible && value !== "" ? " text-clip password " : "",
? " text-clip password "
: "",
editNode ? " input-edit-node " : " input-primary ", editNode ? " input-edit-node " : " input-primary ",
password && editNode ? "pr-8" : "", password && editNode ? "pr-8" : "",
password && !editNode ? "pr-10" : "" password && !editNode ? "pr-10" : ""
)} )}
placeholder={password && editNode ? "Key" : "Type something..."} placeholder={password && editNode ? "Key" : "Type something..."}
onChange={(e) => { onChange={(e) => {
setMyValue(e.target.value);
onChange(e.target.value); onChange(e.target.value);
}} }}
/> />

View file

@ -1,9 +1,8 @@
import { useContext, useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { InputListComponentType } from "../../types/components"; import { InputListComponentType } from "../../types/components";
import _ from "lodash"; import _ from "lodash";
import { Plus, X } from "lucide-react"; import { Plus, X } from "lucide-react";
import { PopUpContext } from "../../contexts/popUpContext";
export default function InputListComponent({ export default function InputListComponent({
value, value,
@ -13,7 +12,12 @@ export default function InputListComponent({
onAddInput, onAddInput,
}: InputListComponentType) { }: InputListComponentType) {
const [inputList, setInputList] = useState(value ?? [""]); const [inputList, setInputList] = useState(value ?? [""]);
const { closePopUp } = useContext(PopUpContext);
useEffect(() => {
if (value) {
setInputList(value);
}
}, [value]);
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
@ -22,10 +26,6 @@ export default function InputListComponent({
} }
}, [disabled, onChange]); }, [disabled, onChange]);
useEffect(() => {
setInputList(value);
}, [closePopUp]);
return ( return (
<div <div
className={ className={

View file

@ -1,5 +1,4 @@
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { FloatComponentType } from "../../types/components"; import { FloatComponentType } from "../../types/components";
@ -10,22 +9,15 @@ export default function IntComponent({
disabled, disabled,
editNode = false, editNode = false,
}: FloatComponentType) { }: FloatComponentType) {
const [myValue, setMyValue] = useState(value ?? "");
const { setDisableCopyPaste } = useContext(TabsContext); const { setDisableCopyPaste } = useContext(TabsContext);
const min = 0; const min = 0;
const { closePopUp } = useContext(PopUpContext);
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
setMyValue("");
onChange(""); onChange("");
} }
}, [disabled, onChange]); }, [disabled, onChange]);
useEffect(() => {
setMyValue(value);
}, [closePopUp]);
return ( return (
<div <div
className={ className={
@ -66,7 +58,7 @@ export default function IntComponent({
e.target.value = min.toString(); e.target.value = min.toString();
} }
}} }}
value={myValue} value={value ?? ""}
className={ className={
editNode editNode
? " input-edit-node " ? " input-edit-node "
@ -74,7 +66,6 @@ export default function IntComponent({
} }
placeholder={editNode ? "Integer number" : "Type an integer number"} placeholder={editNode ? "Integer number" : "Type an integer number"}
onChange={(e) => { onChange={(e) => {
setMyValue(e.target.value);
onChange(e.target.value); onChange(e.target.value);
}} }}
/> />

View file

@ -1,8 +1,6 @@
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import GenericModal from "../../modals/genericModal"; import GenericModal from "../../modals/genericModal";
import { TextAreaComponentType } from "../../types/components"; import { TextAreaComponentType } from "../../types/components";
import { TypeModal } from "../../utils";
import { ExternalLink } from "lucide-react"; import { ExternalLink } from "lucide-react";
import { typesContext } from "../../contexts/typesContext"; import { typesContext } from "../../contexts/typesContext";
@ -18,7 +16,6 @@ export default function PromptAreaComponent({
editNode = false, editNode = false,
}: TextAreaComponentType) { }: TextAreaComponentType) {
const [myValue, setMyValue] = useState(value); const [myValue, setMyValue] = useState(value);
const { openPopUp } = useContext(PopUpContext);
const { reactFlowInstance } = useContext(typesContext); const { reactFlowInstance } = useContext(typesContext);
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
@ -39,32 +36,10 @@ export default function PromptAreaComponent({
} }
}, [value, reactFlowInstance]); }, [value, reactFlowInstance]);
// useEffect(() => {
// if (value !== "" && myValue !== value && reactFlowInstance) {
// // only executed once
// setMyValue(value);
// postValidatePrompt(field_name, value, nodeClass)
// .then((apiReturn) => {
// if (apiReturn.data) {
// setNodeClass(apiReturn.data.frontend_node);
// // need to update reactFlowInstance to re-render the nodes.
// reactFlowInstance.setEdges(
// _.cloneDeep(reactFlowInstance.getEdges())
// );
// }
// })
// .catch((error) => {});
// }
// }, [reactFlowInstance, field_name, myValue, nodeClass, setNodeClass, value]);
return ( return (
<div className={disabled ? "pointer-events-none w-full " : " w-full"}> <div className={disabled ? "pointer-events-none w-full " : " w-full"}>
<div className="flex w-full items-center">
<span
onClick={() => {
openPopUp(
<GenericModal <GenericModal
type={TypeModal.PROMPT} type={"prompt"}
value={myValue} value={myValue}
buttonText="Check & Save" buttonText="Check & Save"
modalTitle="Edit Prompt" modalTitle="Edit Prompt"
@ -74,9 +49,9 @@ export default function PromptAreaComponent({
}} }}
nodeClass={nodeClass} nodeClass={nodeClass}
setNodeClass={setNodeClass} setNodeClass={setNodeClass}
/> >
); <div className="flex w-full items-center">
}} <span
className={ className={
editNode editNode
? "input-edit-node input-dialog" ? "input-edit-node input-dialog"
@ -84,27 +59,8 @@ export default function PromptAreaComponent({
" input-primary text-muted-foreground " " input-primary text-muted-foreground "
} }
> >
{myValue !== "" ? myValue : "Type your prompt here"} {myValue !== "" ? myValue : "Type your prompt here..."}
</span> </span>
<button
onClick={() => {
openPopUp(
<GenericModal
field_name={field_name}
type={TypeModal.PROMPT}
value={myValue}
buttonText="Check & Save"
modalTitle="Edit Prompt"
setValue={(t: string) => {
setMyValue(t);
onChange(t);
}}
nodeClass={nodeClass}
setNodeClass={setNodeClass}
/>
);
}}
>
{!editNode && ( {!editNode && (
<ExternalLink <ExternalLink
strokeWidth={1.5} strokeWidth={1.5}
@ -114,8 +70,8 @@ export default function PromptAreaComponent({
} }
/> />
)} )}
</button>
</div> </div>
</GenericModal>
</div> </div>
); );
} }

View file

@ -1,8 +1,6 @@
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import GenericModal from "../../modals/genericModal"; import GenericModal from "../../modals/genericModal";
import { TextAreaComponentType } from "../../types/components"; import { TextAreaComponentType } from "../../types/components";
import { TypeModal } from "../../utils";
import { ExternalLink } from "lucide-react"; import { ExternalLink } from "lucide-react";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
@ -13,26 +11,19 @@ export default function TextAreaComponent({
disabled, disabled,
editNode = false, editNode = false,
}: TextAreaComponentType) { }: TextAreaComponentType) {
const [myValue, setMyValue] = useState(value);
const { openPopUp, closePopUp } = useContext(PopUpContext);
const { setDisableCopyPaste } = useContext(TabsContext); const { setDisableCopyPaste } = useContext(TabsContext);
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
setMyValue("");
onChange(""); onChange("");
} }
}, [disabled, onChange]); }, [disabled, onChange]);
useEffect(() => {
setMyValue(value);
}, [closePopUp]);
return ( return (
<div className={disabled ? "pointer-events-none w-full " : " w-full"}> <div className={disabled ? "pointer-events-none w-full " : " w-full"}>
<div className="flex w-full items-center"> <div className="flex w-full items-center">
<input <input
value={myValue} value={value}
onFocus={() => { onFocus={() => {
setDisableCopyPaste(true); setDisableCopyPaste(true);
}} }}
@ -40,32 +31,25 @@ export default function TextAreaComponent({
setDisableCopyPaste(false); setDisableCopyPaste(false);
}} }}
className={ className={
editNode (editNode
? " input-edit-node " ? " input-edit-node "
: " input-primary " + (disabled ? " input-disable" : "") : " input-primary " + (disabled ? " input-disable" : "")) +
" w-full"
} }
placeholder={"Type something..."} placeholder={"Type something..."}
onChange={(e) => { onChange={(e) => {
setMyValue(e.target.value);
onChange(e.target.value); onChange(e.target.value);
}} }}
/> />
<div>
<button
onClick={() => {
openPopUp(
<GenericModal <GenericModal
type={TypeModal.TEXT} type={"text"}
buttonText="Finishing Editing" buttonText="Finishing Editing"
modalTitle="Edit Text" modalTitle="Edit Text"
value={myValue} value={value}
setValue={(t: string) => { setValue={(t: string) => {
setMyValue(t);
onChange(t); onChange(t);
}} }}
/>
);
}}
> >
{!editNode && ( {!editNode && (
<ExternalLink <ExternalLink
@ -76,7 +60,8 @@ export default function TextAreaComponent({
} }
/> />
)} )}
</button> </GenericModal>
</div>
</div> </div>
</div> </div>
); );

View file

@ -212,11 +212,11 @@ The cursor: default; property value restores the browser's default cursor style
@apply focus:placeholder-transparent focus:ring-ring focus:border-ring @apply focus:placeholder-transparent focus:ring-ring focus:border-ring
} }
.input-primary { .input-primary {
@apply bg-background block border-border form-input px-3 placeholder:text-muted-foreground rounded-md shadow-sm sm:text-sm truncate w-full; @apply bg-background text-left block border-border form-input px-3 placeholder:text-muted-foreground rounded-md shadow-sm sm:text-sm truncate w-full;
} }
.input-edit-node{ .input-edit-node{
@apply input-primary border-border placeholder:text-center pt-0.5 pb-0.5 text-center @apply input-primary border-border pt-0.5 pb-0.5
} }
.input-search{ .input-search{
@apply input-primary pr-7 mx-2 @apply input-primary pr-7 mx-2
@ -904,7 +904,7 @@ The cursor: default; property value restores the browser's default cursor style
} }
.api-modal-tabs { .api-modal-tabs {
@apply w-full h-full overflow-hidden text-center bg-muted rounded-md border @apply lg:w-full h-full overflow-hidden text-center bg-muted rounded-md border sm:w-[75vw]
} }
.api-modal-tablist-div { .api-modal-tablist-div {
@apply flex items-center justify-between px-2 @apply flex items-center justify-between px-2

View file

@ -2,8 +2,14 @@ import "ace-builds/src-noconflict/ext-language_tools";
import "ace-builds/src-noconflict/mode-python"; import "ace-builds/src-noconflict/mode-python";
import "ace-builds/src-noconflict/theme-github"; import "ace-builds/src-noconflict/theme-github";
import "ace-builds/src-noconflict/theme-twilight"; import "ace-builds/src-noconflict/theme-twilight";
import { useContext, useEffect, useRef, useState } from "react"; import {
import { PopUpContext } from "../../contexts/popUpContext"; ReactNode,
forwardRef,
useContext,
useEffect,
useRef,
useState,
} from "react";
// import "ace-builds/webpack-resolver"; // import "ace-builds/webpack-resolver";
import { Check, Clipboard, Code2 } from "lucide-react"; import { Check, Clipboard, Code2 } from "lucide-react";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
@ -20,14 +26,6 @@ import IntComponent from "../../components/intComponent";
import PromptAreaComponent from "../../components/promptComponent"; import PromptAreaComponent from "../../components/promptComponent";
import TextAreaComponent from "../../components/textAreaComponent"; import TextAreaComponent from "../../components/textAreaComponent";
import ToggleShadComponent from "../../components/toggleShadComponent"; import ToggleShadComponent from "../../components/toggleShadComponent";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import { import {
Table, Table,
TableBody, TableBody,
@ -48,22 +46,30 @@ import {
getPythonApiCode, getPythonApiCode,
getPythonCode, getPythonCode,
} from "../../constants"; } from "../../constants";
import { darkContext } from "../../contexts/darkContext";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { FlowType } from "../../types/flow/index"; import { FlowType } from "../../types/flow/index";
import { buildTweaks, classNames } from "../../utils"; import { buildTweaks, classNames } from "../../utils";
import BaseModal from "../baseModal";
export default function ApiModal({ flow }: { flow: FlowType }) { const ApiModal = forwardRef(
const [open, setOpen] = useState(true); (
const { dark } = useContext(darkContext); {
const { closePopUp, closeEdit, setCloseEdit } = useContext(PopUpContext); flow,
children,
}: {
flow: FlowType;
children: ReactNode;
},
ref
) => {
const [activeTab, setActiveTab] = useState("0"); const [activeTab, setActiveTab] = useState("0");
const [open, setOpen] = useState(false);
const [isCopied, setIsCopied] = useState<Boolean>(false); const [isCopied, setIsCopied] = useState<Boolean>(false);
const [enabled, setEnabled] = useState(null);
const [openAccordion, setOpenAccordion] = useState([]); const [openAccordion, setOpenAccordion] = useState([]);
const tweak = useRef([]); const tweak = useRef([]);
const tweaksList = useRef([]); const tweaksList = useRef([]);
const { setTweak, getTweak, tabsState } = useContext(TabsContext); const { setTweak, getTweak, tabsState } = useContext(TabsContext);
const copyToClipboard = () => { const copyToClipboard = () => {
if (!navigator.clipboard || !navigator.clipboard.writeText) { if (!navigator.clipboard || !navigator.clipboard.writeText) {
return; return;
@ -81,7 +87,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
const curl_code = getCurlCode(flow, tweak.current, tabsState); const curl_code = getCurlCode(flow, tweak.current, tabsState);
const pythonCode = getPythonCode(flow, tweak.current, tabsState); const pythonCode = getPythonCode(flow, tweak.current, tabsState);
const tweaksCode = buildTweaks(flow); const tweaksCode = buildTweaks(flow);
const tabs = [ const [tabs, setTabs] = useState([
{ {
name: "cURL", name: "cURL",
mode: "bash", mode: "bash",
@ -101,50 +107,78 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png", image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png",
code: pythonCode, code: pythonCode,
}, },
]; ]);
function startState() {
tweak.current = [];
setTweak([]);
tweaksList.current = [];
}
useEffect(() => { useEffect(() => {
if (closeEdit !== "") { if (flow["data"]["nodes"].length == 0) {
tweak.current = getTweak; startState();
if (tweak.current.length > 0) {
setActiveTab("3");
openAccordions();
} else { } else {
startTweaks(); tweak.current = [];
const t = buildTweaks(flow);
tweak.current.push(t);
} }
} else {
if (tweak?.current) {
startTweaks();
}
}
}, [closeEdit]);
useEffect(() => {
filterNodes(); filterNodes();
}, []);
if (Object.keys(tweaksCode).length > 0) { if (Object.keys(tweaksCode).length > 0) {
tabs.push({ setActiveTab("0");
setTabs([
{
name: "cURL",
mode: "bash",
image: "https://curl.se/logo/curl-symbol-transparent.png",
code: curl_code,
},
{
name: "Python API",
mode: "python",
image:
"https://images.squarespace-cdn.com/content/v1/5df3d8c5d2be5962e4f87890/1628015119369-OY4TV3XJJ53ECO0W2OLQ/Python+API+Training+Logo.png?format=1000w",
code: pythonApiCode,
},
{
name: "Python Code",
mode: "python",
image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png",
code: pythonCode,
},
{
name: "Tweaks", name: "Tweaks",
mode: "python", mode: "python",
image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png", image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png",
code: pythonCode, code: pythonCode,
}); },
} ]);
} else {
function setModalOpen(x: boolean) { setTabs([
setOpen(x); {
if (x === false) { name: "cURL",
setCloseEdit(""); mode: "bash",
setTweak([]); image: "https://curl.se/logo/curl-symbol-transparent.png",
closePopUp(); code: curl_code,
} },
} {
name: "Python API",
function startTweaks() { mode: "python",
const t = buildTweaks(flow); image:
tweak?.current?.push(t); "https://images.squarespace-cdn.com/content/v1/5df3d8c5d2be5962e4f87890/1628015119369-OY4TV3XJJ53ECO0W2OLQ/Python+API+Training+Logo.png?format=1000w",
code: pythonApiCode,
},
{
name: "Python Code",
mode: "python",
image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png",
code: pythonCode,
},
]);
} }
}, [flow["data"]["nodes"], open]);
function filterNodes() { function filterNodes() {
let arrNodesWithValues = []; let arrNodesWithValues = [];
@ -262,23 +296,24 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
} }
}); });
}); });
if (accordionsToOpen.length == 0) {
setOpenAccordion([]);
}
} }
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <BaseModal open={open} setOpen={setOpen}>
<DialogTrigger></DialogTrigger> <BaseModal.Trigger>{children}</BaseModal.Trigger>
<DialogContent className="h-[80vh] md:max-w-[80vw]"> <BaseModal.Header description={EXPORT_CODE_DIALOG}>
<DialogHeader>
<DialogTitle className="flex items-center">
<span className="pr-2">Code</span> <span className="pr-2">Code</span>
<Code2 <Code2
className="h-6 w-6 pl-1 text-gray-800 dark:text-white" strokeWidth={1.5}
className="h-6 w-6 pl-1 text-primary "
aria-hidden="true" aria-hidden="true"
/> />
</DialogTitle> </BaseModal.Header>
<DialogDescription>{EXPORT_CODE_DIALOG}</DialogDescription> <BaseModal.Content>
</DialogHeader>
<Tabs <Tabs
value={activeTab} value={activeTab}
className="api-modal-tabs" className="api-modal-tabs"
@ -318,7 +353,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
> >
{index < 3 ? ( {index < 3 ? (
<SyntaxHighlighter <SyntaxHighlighter
className="h-[60vh] w-full overflow-auto custom-scroll" className="h-[70vh] w-full overflow-auto custom-scroll"
language={tab.mode} language={tab.mode}
style={oneDark} style={oneDark}
> >
@ -329,7 +364,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
<div className="api-modal-according-display"> <div className="api-modal-according-display">
<div <div
className={classNames( className={classNames(
"h-[60vh] w-full rounded-lg bg-muted", "h-[70vh] w-full rounded-lg bg-muted",
1 == 1 1 == 1
? "overflow-scroll overflow-x-hidden custom-scroll" ? "overflow-scroll overflow-x-hidden custom-scroll"
: "overflow-hidden" : "overflow-hidden"
@ -355,7 +390,9 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody className="p-0"> <TableBody className="p-0">
{Object.keys(t["data"]["node"]["template"]) {Object.keys(
t["data"]["node"]["template"]
)
.filter( .filter(
(n) => (n) =>
n.charAt(0) !== "_" && n.charAt(0) !== "_" &&
@ -399,12 +436,12 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
editNode={true} editNode={true}
disabled={false} disabled={false}
value={ value={
!t.data.node.template[ !t.data.node
n .template[n]
].value || .value ||
t.data.node.template[ t.data.node
n .template[n]
].value === "" .value === ""
? [""] ? [""]
: t.data.node : t.data.node
.template[n] .template[n]
@ -420,13 +457,13 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
); );
}} }}
/> />
) : t.data.node.template[n] ) : t.data.node.template[
.multiline ? ( n
].multiline ? (
<ShadTooltip <ShadTooltip
content={buildContent( content={buildContent(
t.data.node.template[ t.data.node
n .template[n].value
].value
)} )}
> >
<div> <div>
@ -443,7 +480,9 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
)} )}
onChange={(k) => { onChange={(k) => {
buildTweakObject( buildTweakObject(
t["data"]["id"], t["data"][
"id"
],
k, k,
t.data.node t.data.node
.template[n] .template[n]
@ -457,18 +496,17 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
editNode={true} editNode={true}
disabled={false} disabled={false}
password={ password={
t.data.node.template[ t.data.node
n .template[n]
].password ?? false .password ?? false
} }
value={getValue( value={getValue(
t.data.node.template[ t.data.node
n .template[n]
].value, .value,
t.data, t.data,
t.data.node.template[ t.data.node
n .template[n]
]
)} )}
onChange={(k) => { onChange={(k) => {
buildTweakObject( buildTweakObject(
@ -487,20 +525,19 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
{" "} {" "}
<ToggleShadComponent <ToggleShadComponent
enabled={ enabled={
t.data.node.template[n] t.data.node.template[
.value n
].value
} }
setEnabled={(e) => { setEnabled={(e) => {
t.data.node.template[ t.data.node.template[
n n
].value = e; ].value = e;
setEnabled(e);
buildTweakObject( buildTweakObject(
t["data"]["id"], t["data"]["id"],
e, e,
t.data.node.template[ t.data.node
n .template[n]
]
); );
}} }}
size="small" size="small"
@ -512,10 +549,13 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
<ShadTooltip <ShadTooltip
content={buildContent( content={buildContent(
getValue( getValue(
t.data.node.template[n] t.data.node.template[
.value, n
].value,
t.data, t.data,
t.data.node.template[n] t.data.node.template[
n
]
) )
)} )}
> >
@ -524,22 +564,22 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
editNode={true} editNode={true}
disabled={false} disabled={false}
value={ value={
t.data.node.template[ t.data.node
n .template[n]
].value ?? "" .value ?? ""
} }
onChange={( onChange={(
k: any k: any
) => {}} ) => {}}
fileTypes={ fileTypes={
t.data.node.template[ t.data.node
n .template[n]
].fileTypes .fileTypes
} }
suffixes={ suffixes={
t.data.node.template[ t.data.node
n .template[n]
].suffixes .suffixes
} }
onFileChange={( onFileChange={(
k: any k: any
@ -553,91 +593,6 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
<FloatComponent <FloatComponent
disabled={false} disabled={false}
editNode={true} editNode={true}
value={getValue(
t.data.node.template[n]
.value,
t.data,
t.data.node.template[n]
)}
onChange={(k) => {
buildTweakObject(
t["data"]["id"],
k,
t.data.node.template[
n
]
);
}}
/>
</div>
) : t.data.node.template[n]
.type === "str" &&
t.data.node.template[n]
.options ? (
<div className="mx-auto">
<Dropdown
editNode={true}
apiModal={true}
options={
t.data.node.template[n]
.options
}
onSelect={(k) => {
buildTweakObject(
t["data"]["id"],
k,
t.data.node.template[
n
]
);
}}
value={getValue(
t.data.node.template[n]
.value,
t.data,
t.data.node.template[n]
)}
></Dropdown>
</div>
) : t.data.node.template[n]
.type === "int" ? (
<div className="mx-auto">
<IntComponent
disabled={false}
editNode={true}
value={getValue(
t.data.node.template[n]
.value,
t.data,
t.data.node.template[n]
)}
onChange={(k) => {
buildTweakObject(
t["data"]["id"],
k,
t.data.node.template[
n
]
);
}}
/>
</div>
) : t.data.node.template[n]
.type === "prompt" ? (
<ShadTooltip
content={buildContent(
getValue(
t.data.node.template[n]
.value,
t.data,
t.data.node.template[n]
)
)}
>
<div className="mx-auto">
<PromptAreaComponent
editNode={true}
disabled={false}
value={getValue( value={getValue(
t.data.node.template[ t.data.node.template[
n n
@ -657,21 +612,42 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
}} }}
/> />
</div> </div>
</ShadTooltip>
) : t.data.node.template[n] ) : t.data.node.template[n]
.type === "code" ? ( .type === "str" &&
<ShadTooltip
content={buildContent(
getValue(
t.data.node.template[n] t.data.node.template[n]
.value, .options ? (
t.data,
t.data.node.template[n]
)
)}
>
<div className="mx-auto"> <div className="mx-auto">
<CodeAreaComponent <Dropdown
editNode={true}
apiModal={true}
options={
t.data.node.template[
n
].options
}
onSelect={(k) => {
buildTweakObject(
t["data"]["id"],
k,
t.data.node
.template[n]
);
}}
value={getValue(
t.data.node.template[
n
].value,
t.data,
t.data.node.template[
n
]
)}
></Dropdown>
</div>
) : t.data.node.template[n]
.type === "int" ? (
<div className="mx-auto">
<IntComponent
disabled={false} disabled={false}
editNode={true} editNode={true}
value={getValue( value={getValue(
@ -693,6 +669,81 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
}} }}
/> />
</div> </div>
) : t.data.node.template[n]
.type === "prompt" ? (
<ShadTooltip
content={buildContent(
getValue(
t.data.node.template[
n
].value,
t.data,
t.data.node.template[
n
]
)
)}
>
<div className="mx-auto">
<PromptAreaComponent
editNode={true}
disabled={false}
value={getValue(
t.data.node
.template[n]
.value,
t.data,
t.data.node
.template[n]
)}
onChange={(k) => {
buildTweakObject(
t["data"]["id"],
k,
t.data.node
.template[n]
);
}}
/>
</div>
</ShadTooltip>
) : t.data.node.template[n]
.type === "code" ? (
<ShadTooltip
content={buildContent(
getValue(
t.data.node.template[
n
].value,
t.data,
t.data.node.template[
n
]
)
)}
>
<div className="mx-auto">
<CodeAreaComponent
disabled={false}
editNode={true}
value={getValue(
t.data.node
.template[n]
.value,
t.data,
t.data.node
.template[n]
)}
onChange={(k) => {
buildTweakObject(
t["data"]["id"],
k,
t.data.node
.template[n]
);
}}
/>
</div>
</ShadTooltip> </ShadTooltip>
) : t.data.node.template[n] ) : t.data.node.template[n]
.type === "Any" ? ( .type === "Any" ? (
@ -720,34 +771,6 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
)} )}
</div> </div>
))} ))}
{/*
<div className="flex flex-col gap-5 bg-muted">
<Table className="table-fixed bg-muted outline-1">
<TableHeader className="border-gray-200 text-gray-500 text-xs font-medium h-10">
<TableRow className="dark:border-b-muted">
<TableHead className="h-5 text-center">
TWEAK
</TableHead>
<TableHead className="p-0 h-5 text-center">
VALUE
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{invoices.map((invoice) => (
<TableRow className="p-0 text-center text-gray-900 text-sm">
<TableCell className="p-2 text-center text-gray-900 text-sm truncate">
{invoice.paymentStatus}
</TableCell>
<TableCell className="p-2 text-center text-gray-900 text-sm truncate">
{invoice.paymentMethod}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div> */}
</div> </div>
</div> </div>
</> </>
@ -755,7 +778,10 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
</TabsContent> </TabsContent>
))} ))}
</Tabs> </Tabs>
</DialogContent> </BaseModal.Content>
</Dialog> </BaseModal>
); );
} }
);
export default ApiModal;

View file

@ -1,5 +1,6 @@
import { cloneDeep } from "lodash";
import { Variable } from "lucide-react"; import { Variable } from "lucide-react";
import { useContext, useRef, useState } from "react"; import { ReactNode, forwardRef, useContext, useEffect, useState } from "react";
import CodeAreaComponent from "../../components/codeAreaComponent"; import CodeAreaComponent from "../../components/codeAreaComponent";
import Dropdown from "../../components/dropdownComponent"; import Dropdown from "../../components/dropdownComponent";
import FloatComponent from "../../components/floatComponent"; import FloatComponent from "../../components/floatComponent";
@ -12,15 +13,6 @@ import TextAreaComponent from "../../components/textAreaComponent";
import ToggleShadComponent from "../../components/toggleShadComponent"; import ToggleShadComponent from "../../components/toggleShadComponent";
import { Badge } from "../../components/ui/badge"; import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import { import {
Table, Table,
TableBody, TableBody,
@ -29,92 +21,68 @@ import {
TableHeader, TableHeader,
TableRow, TableRow,
} from "../../components/ui/table"; } from "../../components/ui/table";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { typesContext } from "../../contexts/typesContext"; import { typesContext } from "../../contexts/typesContext";
import { NodeDataType } from "../../types/flow"; import { NodeDataType } from "../../types/flow";
import { classNames, limitScrollFieldsModal } from "../../utils"; import { classNames, limitScrollFieldsModal } from "../../utils";
import BaseModal from "../baseModal";
export default function EditNodeModal({ data }: { data: NodeDataType }) { const EditNodeModal = forwardRef(
const [open, setOpen] = useState(true); (
const [nodeLength, setNodeLength] = useState( {
Object.keys(data.node.template).filter( data,
(t) => setData,
t.charAt(0) !== "_" && nodeLength,
data.node.template[t].show && children,
(data.node.template[t].type === "str" || }: {
data.node.template[t].type === "bool" || data: NodeDataType;
data.node.template[t].type === "float" || setData: (data: NodeDataType) => void;
data.node.template[t].type === "code" || nodeLength: number;
data.node.template[t].type === "prompt" || children: ReactNode;
data.node.template[t].type === "file" || },
data.node.template[t].type === "int") ref
).length ) => {
); const [modalOpen, setModalOpen] = useState(false);
const [nodeValue, setNodeValue] = useState(null); const [myData, setMyData] = useState(data);
const { closePopUp } = useContext(PopUpContext);
const { types } = useContext(typesContext);
const ref = useRef();
const { setTabsState, tabId } = useContext(TabsContext); const { setTabsState, tabId } = useContext(TabsContext);
const { reactFlowInstance } = useContext(typesContext); const { reactFlowInstance } = useContext(typesContext);
let disabled = let disabled =
reactFlowInstance?.getEdges().some((e) => e.targetHandle === data.id) ?? reactFlowInstance?.getEdges().some((e) => e.targetHandle === data.id) ??
false; false;
if (nodeLength == 0) {
closePopUp();
}
function setModalOpen(x: boolean) { function changeAdvanced(n) {
setOpen(x); setMyData((old) => {
if (x === false) { let newData = cloneDeep(old);
closePopUp(); newData.node.template[n].advanced = !newData.node.template[n].advanced;
} return newData;
}
function changeAdvanced(node) {
Object.keys(data.node.template).map((n, i) => {
if (n === node.name) {
data.node.template[n].advanced = !data.node.template[n].advanced;
}
return n;
}); });
setNodeValue(!nodeValue);
} }
const handleOnNewValue = (newValue: any, name) => { const handleOnNewValue = (newValue: any, name) => {
data.node.template[name].value = newValue; setMyData((old) => {
// Set state to pending let newData = cloneDeep(old);
setTabsState((prev) => { newData.node.template[name].value = newValue;
return { return newData;
...prev,
[tabId]: {
...prev[tabId],
isPending: true,
},
};
}); });
}; };
useEffect(() => {
setMyData(data); // reset data to what it is on node when opening modal
}, [modalOpen]);
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <BaseModal size="large-h-full" open={modalOpen} setOpen={setModalOpen}>
<DialogTrigger asChild></DialogTrigger> <BaseModal.Trigger>{children}</BaseModal.Trigger>
<DialogContent className="sm:max-w-[600px] lg:max-w-[700px]"> <BaseModal.Header description={myData.node?.description}>
<DialogHeader> <span className="pr-2">{myData.type}</span>
<DialogTitle className="flex items-center"> <Badge variant="secondary">ID: {myData.id}</Badge>
<span className="pr-2">{data.type}</span> </BaseModal.Header>
<Badge variant="secondary">ID: {data.id}</Badge> <BaseModal.Content>
</DialogTitle> <div className="flex pb-2">
<DialogDescription asChild>
<div>
{data.node?.description}
<div className="flex pt-3">
<Variable className="edit-node-modal-variable "></Variable> <Variable className="edit-node-modal-variable "></Variable>
<span className="edit-node-modal-span">Parameters</span> <span className="edit-node-modal-span">Parameters</span>
</div> </div>
</div>
</DialogDescription>
</DialogHeader>
<div className="edit-node-modal-arrangement"> <div className="edit-node-modal-arrangement">
<div <div
@ -138,49 +106,51 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody className="p-0"> <TableBody className="p-0">
{Object.keys(data.node.template) {Object.keys(myData.node.template)
.filter( .filter(
(t) => (t) =>
t.charAt(0) !== "_" && t.charAt(0) !== "_" &&
data.node.template[t].show && myData.node.template[t].show &&
(data.node.template[t].type === "str" || (myData.node.template[t].type === "str" ||
data.node.template[t].type === "bool" || myData.node.template[t].type === "bool" ||
data.node.template[t].type === "float" || myData.node.template[t].type === "float" ||
data.node.template[t].type === "code" || myData.node.template[t].type === "code" ||
data.node.template[t].type === "prompt" || myData.node.template[t].type === "prompt" ||
data.node.template[t].type === "file" || myData.node.template[t].type === "file" ||
data.node.template[t].type === "int") myData.node.template[t].type === "int")
) )
.map((n, i) => ( .map((n, i) => (
<TableRow key={i} className="h-10"> <TableRow key={i} 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">
{data.node.template[n].name {myData.node.template[n].name
? data.node.template[n].name ? myData.node.template[n].name
: data.node.template[n].display_name} : myData.node.template[n].display_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 ">
{data.node.template[n].type === "str" && {myData.node.template[n].type === "str" &&
!data.node.template[n].options ? ( !myData.node.template[n].options ? (
<div className="mx-auto"> <div className="mx-auto">
{data.node.template[n].list ? ( {myData.node.template[n].list ? (
<InputListComponent <InputListComponent
editNode={true} editNode={true}
disabled={disabled} disabled={disabled}
value={ value={
!data.node.template[n].value || !myData.node.template[n].value ||
data.node.template[n].value === "" myData.node.template[n].value === ""
? [""] ? [""]
: data.node.template[n].value : myData.node.template[n].value
} }
onChange={(t: string[]) => { onChange={(t: string[]) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
/> />
) : data.node.template[n].multiline ? ( ) : myData.node.template[n].multiline ? (
<TextAreaComponent <TextAreaComponent
disabled={disabled} disabled={disabled}
editNode={true} editNode={true}
value={data.node.template[n].value ?? ""} value={
myData.node.template[n].value ?? ""
}
onChange={(t: string) => { onChange={(t: string) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
@ -190,96 +160,101 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
editNode={true} editNode={true}
disabled={disabled} disabled={disabled}
password={ password={
data.node.template[n].password ?? false myData.node.template[n].password ??
false
}
value={
myData.node.template[n].value ?? ""
} }
value={data.node.template[n].value ?? ""}
onChange={(t) => { onChange={(t) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
/> />
)} )}
</div> </div>
) : data.node.template[n].type === "bool" ? ( ) : myData.node.template[n].type === "bool" ? (
<div className="ml-auto"> <div className="ml-auto">
{" "} {" "}
<ToggleShadComponent <ToggleShadComponent
disabled={disabled} disabled={disabled}
enabled={data.node.template[n].value} enabled={myData.node.template[n].value}
setEnabled={(t) => { setEnabled={(t) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
size="small" size="small"
/> />
</div> </div>
) : data.node.template[n].type === "float" ? ( ) : myData.node.template[n].type === "float" ? (
<div className="mx-auto"> <div className="mx-auto">
<FloatComponent <FloatComponent
disabled={disabled} disabled={disabled}
editNode={true} editNode={true}
value={data.node.template[n].value ?? ""} value={myData.node.template[n].value ?? ""}
onChange={(t) => { onChange={(t) => {
data.node.template[n].value = t; handleOnNewValue(t, n);
}} }}
/> />
</div> </div>
) : data.node.template[n].type === "str" && ) : myData.node.template[n].type === "str" &&
data.node.template[n].options ? ( myData.node.template[n].options ? (
<div className="mx-auto"> <div className="mx-auto">
<Dropdown <Dropdown
numberOfOptions={nodeLength} numberOfOptions={nodeLength}
editNode={true} editNode={true}
options={data.node.template[n].options} options={myData.node.template[n].options}
onSelect={(t) => handleOnNewValue(t, n)} onSelect={(t) => handleOnNewValue(t, n)}
value={ value={
data.node.template[n].value ?? myData.node.template[n].value ??
"Choose an option" "Choose an option"
} }
></Dropdown> ></Dropdown>
</div> </div>
) : data.node.template[n].type === "int" ? ( ) : myData.node.template[n].type === "int" ? (
<div className="mx-auto"> <div className="mx-auto">
<IntComponent <IntComponent
disabled={disabled} disabled={disabled}
editNode={true} editNode={true}
value={data.node.template[n].value ?? ""} value={myData.node.template[n].value ?? ""}
onChange={(t) => { onChange={(t) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
/> />
</div> </div>
) : data.node.template[n].type === "file" ? ( ) : myData.node.template[n].type === "file" ? (
<div className="mx-auto"> <div className="mx-auto">
<InputFileComponent <InputFileComponent
editNode={true} editNode={true}
disabled={disabled} disabled={disabled}
value={data.node.template[n].value ?? ""} value={myData.node.template[n].value ?? ""}
onChange={(t: string) => { onChange={(t: string) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
fileTypes={data.node.template[n].fileTypes} fileTypes={
suffixes={data.node.template[n].suffixes} myData.node.template[n].fileTypes
}
suffixes={myData.node.template[n].suffixes}
onFileChange={(t: string) => { onFileChange={(t: string) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
></InputFileComponent> ></InputFileComponent>
</div> </div>
) : data.node.template[n].type === "prompt" ? ( ) : myData.node.template[n].type === "prompt" ? (
<div className="mx-auto"> <div className="mx-auto">
<PromptAreaComponent <PromptAreaComponent
field_name={n} field_name={n}
editNode={true} editNode={true}
disabled={disabled} disabled={disabled}
nodeClass={data.node} nodeClass={myData.node}
setNodeClass={(nodeClass) => { setNodeClass={(nodeClass) => {
data.node = nodeClass; myData.node = nodeClass;
}} }}
value={data.node.template[n].value ?? ""} value={myData.node.template[n].value ?? ""}
onChange={(t: string) => { onChange={(t: string) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
/> />
</div> </div>
) : data.node.template[n].type === "code" ? ( ) : myData.node.template[n].type === "code" ? (
<div className="mx-auto"> <div className="mx-auto">
<CodeAreaComponent <CodeAreaComponent
dynamic={ dynamic={
@ -289,15 +264,15 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
data.node = nodeClass; data.node = nodeClass;
}} }}
nodeClass={data.node} nodeClass={data.node}
disabled={false} disabled={disabled}
editNode={true} editNode={true}
value={data.node.template[n].value ?? ""} value={myData.node.template[n].value ?? ""}
onChange={(t: string) => { onChange={(t: string) => {
handleOnNewValue(t, n); handleOnNewValue(t, n);
}} }}
/> />
</div> </div>
) : data.node.template[n].type === "Any" ? ( ) : myData.node.template[n].type === "Any" ? (
"-" "-"
) : ( ) : (
<div className="hidden"></div> <div className="hidden"></div>
@ -306,10 +281,8 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
<TableCell className="p-0 text-right"> <TableCell className="p-0 text-right">
<div className="items-center text-center"> <div className="items-center text-center">
<ToggleShadComponent <ToggleShadComponent
enabled={!data.node.template[n].advanced} enabled={!myData.node.template[n].advanced}
setEnabled={(e) => setEnabled={(e) => changeAdvanced(n)}
changeAdvanced(data.node.template[n])
}
disabled={disabled} disabled={disabled}
size="small" size="small"
/> />
@ -323,19 +296,32 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
)} )}
</div> </div>
</div> </div>
</BaseModal.Content>
<DialogFooter> <BaseModal.Footer>
<Button <Button
className="mt-3" className="mt-3"
onClick={() => { onClick={() => {
setData(cloneDeep(myData)); //saves data with actual state of modal
setTabsState((prev) => {
return {
...prev,
[tabId]: {
...prev[tabId],
isPending: true,
},
};
});
setModalOpen(false); setModalOpen(false);
}} }}
type="submit" type="submit"
> >
Save Changes Save Changes
</Button> </Button>
</DialogFooter> </BaseModal.Footer>
</DialogContent> </BaseModal>
</Dialog>
); );
} }
);
export default EditNodeModal;

View file

@ -1,7 +1,6 @@
import { Dialog, Transition } from "@headlessui/react"; import { Dialog, Transition } from "@headlessui/react";
import { X } from "lucide-react"; import { X } from "lucide-react";
import { Fragment, useContext, useRef, useState } from "react"; import { Fragment, useContext, useRef, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import { typesContext } from "../../contexts/typesContext"; import { typesContext } from "../../contexts/typesContext";
import { NodeDataType } from "../../types/flow"; import { NodeDataType } from "../../types/flow";
import { import {
@ -14,23 +13,14 @@ import {
import ModalField from "./components/ModalField"; import ModalField from "./components/ModalField";
export default function NodeModal({ data }: { data: NodeDataType }) { export default function NodeModal({ data }: { data: NodeDataType }) {
const [open, setOpen] = useState(true); const [modalOpen, setModalOpen] = useState(false);
const { closePopUp } = useContext(PopUpContext);
const { types } = useContext(typesContext); const { types } = useContext(typesContext);
const ref = useRef(); const ref = useRef();
function setModalOpen(x: boolean) {
setOpen(x);
if (x === false) {
setTimeout(() => {
closePopUp();
}, 300);
}
}
// any to avoid type conflict // any to avoid type conflict
const Icon: any = nodeIconsLucide[types[data.type]]; const Icon: any = nodeIconsLucide[types[data.type]];
return ( return (
<Transition.Root show={open} appear={true} as={Fragment}>
<Dialog <Dialog
open={modalOpen}
as="div" as="div"
className="relative z-10" className="relative z-10"
onClose={setModalOpen} onClose={setModalOpen}
@ -78,8 +68,7 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
strokeWidth={1.5} strokeWidth={1.5}
className="node-modal-icon" className="node-modal-icon"
style={{ style={{
color: color: nodeColors[types[data.type]] ?? nodeColors.unknown,
nodeColors[types[data.type]] ?? nodeColors.unknown,
}} }}
/> />
<div className="node-modal-title-div"> <div className="node-modal-title-div">
@ -158,6 +147,5 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
</div> </div>
</div> </div>
</Dialog> </Dialog>
</Transition.Root>
); );
} }

View file

@ -1,4 +1,4 @@
import { ReactNode, useContext } from "react"; import { ReactNode } from "react";
import React from "react"; import React from "react";
import { import {
@ -9,14 +9,18 @@ import {
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger,
} from "../../components/ui/dialog"; } from "../../components/ui/dialog";
import { PopUpContext } from "../../contexts/popUpContext";
type ContentProps = { children: ReactNode }; type ContentProps = { children: ReactNode };
type HeaderProps = { children: ReactNode; description: string }; type HeaderProps = { children: ReactNode; description: string };
type FooterProps = { children: ReactNode };
type TriggerProps = { children: ReactNode };
const Content: React.FC<ContentProps> = ({ children }) => { const Content: React.FC<ContentProps> = ({ children }) => {
return <div className="h-full w-full">{children}</div>; return <div className="h-full w-full">{children}</div>;
}; };
const Trigger: React.FC<ContentProps> = ({ children }) => {
return <>{children}</>;
};
const Header: React.FC<{ children: ReactNode; description: string }> = ({ const Header: React.FC<{ children: ReactNode; description: string }> = ({
children, children,
@ -29,36 +33,80 @@ const Header: React.FC<{ children: ReactNode; description: string }> = ({
</DialogHeader> </DialogHeader>
); );
}; };
interface BaseModalProps {
children: [React.ReactElement<ContentProps>, React.ReactElement<HeaderProps>];
open: boolean;
setOpen: (open: boolean) => void;
}
function BaseModal({ open, setOpen, children }: BaseModalProps) {
const { closePopUp, setCloseEdit } = useContext(PopUpContext);
function setModalOpen(x: boolean) { const Footer: React.FC<{ children: ReactNode }> = ({ children }) => {
setOpen(x); return <>{children}</>;
if (x === false) { };
setTimeout(() => { interface BaseModalProps {
setCloseEdit("editcode"); children: [
closePopUp(); React.ReactElement<ContentProps>,
}, 300); React.ReactElement<HeaderProps>,
} React.ReactElement<TriggerProps>?,
} React.ReactElement<FooterProps>?
];
open?: boolean;
setOpen?: (open: boolean) => void;
size?: "smaller" | "small" | "medium" | "large" | "large-h-full";
}
function BaseModal({
open,
setOpen,
children,
size = "large",
}: BaseModalProps) {
const headerChild = React.Children.toArray(children).find( const headerChild = React.Children.toArray(children).find(
(child) => (child as React.ReactElement).type === Header (child) => (child as React.ReactElement).type === Header
); );
const triggerChild = React.Children.toArray(children).find(
(child) => (child as React.ReactElement).type === Trigger
);
const ContentChild = React.Children.toArray(children).find( const ContentChild = React.Children.toArray(children).find(
(child) => (child as React.ReactElement).type === Content (child) => (child as React.ReactElement).type === Content
); );
const ContentFooter = React.Children.toArray(children).find(
(child) => (child as React.ReactElement).type === Footer
);
let minWidth: string;
let height: string;
switch (size) {
case "smaller":
minWidth = "min-w-[40vw]";
height = "h-[25vh]";
break;
case "small":
minWidth = "min-w-[40vw]";
height = "h-[40vh]";
break;
case "medium":
minWidth = "min-w-[60vw]";
height = "h-[60vh]";
break;
case "large":
minWidth = "min-w-[80vw]";
height = "h-[80vh]";
break;
case "large-h-full":
minWidth = "min-w-[80vw]";
break;
default:
minWidth = "min-w-[80vw]";
height = "h-[80vh]";
break;
}
//UPDATE COLORS AND STYLE CLASSSES //UPDATE COLORS AND STYLE CLASSSES
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger className="hidden"></DialogTrigger> <DialogTrigger className="w-full" hidden={triggerChild ? false : true}>
<DialogContent className="min-w-[80vw]"> {triggerChild}
</DialogTrigger>
<DialogContent className={minWidth}>
{headerChild} {headerChild}
<div className="mt-2 flex h-[80vh] w-full ">{ContentChild}</div> <div className={`mt-2 flex ${height} w-full `}>{ContentChild}</div>
<div className="flex flex-row-reverse">{ContentFooter}</div>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
); );
@ -66,4 +114,6 @@ function BaseModal({ open, setOpen, children }: BaseModalProps) {
BaseModal.Content = Content; BaseModal.Content = Content;
BaseModal.Header = Header; BaseModal.Header = Header;
BaseModal.Trigger = Trigger;
BaseModal.Footer = Footer;
export default BaseModal; export default BaseModal;

View file

@ -1,7 +1,4 @@
// organize-imports-ignore import "ace-builds/src-noconflict/ace";
import { useContext, useEffect, useRef, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import AceEditor from "react-ace";
import "ace-builds/src-noconflict/ext-language_tools"; import "ace-builds/src-noconflict/ext-language_tools";
import "ace-builds/src-noconflict/mode-python"; import "ace-builds/src-noconflict/mode-python";
import "ace-builds/src-noconflict/theme-github"; import "ace-builds/src-noconflict/theme-github";
@ -10,7 +7,7 @@ import "ace-builds/src-noconflict/ext-language_tools";
import "ace-builds/src-noconflict/ace"; import "ace-builds/src-noconflict/ace";
// import "ace-builds/webpack-resolver"; // import "ace-builds/webpack-resolver";
import { TerminalSquare } from "lucide-react"; import { TerminalSquare } from "lucide-react";
import { useContext, useState } from "react"; import { ReactNode, useContext, useEffect, useState } from "react";
import AceEditor from "react-ace"; import AceEditor from "react-ace";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
import { CODE_PROMPT_DIALOG_SUBTITLE } from "../../constants"; import { CODE_PROMPT_DIALOG_SUBTITLE } from "../../constants";
@ -24,48 +21,39 @@ import {
TabsList, TabsList,
TabsTrigger, TabsTrigger,
} from "../../components/ui/tabs"; } from "../../components/ui/tabs";
import BaseModal from "../baseModal";
export default function CodeAreaModal({ export default function CodeAreaModal({
value, value,
setValue, setValue,
nodeClass, nodeClass,
setNodeClass, setNodeClass,
children,
dynamic, dynamic,
}: { }: {
setValue: (value: string) => void; setValue: (value: string) => void;
value: string; value: string;
nodeClass: APIClassType; nodeClass: APIClassType;
children: ReactNode;
setNodeClass: (Class: APIClassType) => void; setNodeClass: (Class: APIClassType) => void;
dynamic?: boolean; dynamic?: boolean;
}) { }) {
const [code, setCode] = useState(value); const [code, setCode] = useState(value);
const { dark } = useContext(darkContext); const { dark } = useContext(darkContext);
const [height, setHeight] = useState(null);
const { setErrorData, setSuccessData } = useContext(alertContext); const { setErrorData, setSuccessData } = useContext(alertContext);
const [activeTab, setActiveTab] = useState("0");
const [error, setError] = useState<{ const [error, setError] = useState<{
detail: { error: string; traceback: string }; detail: { error: string; traceback: string };
}>(null); }>(null);
const { closePopUp, setCloseEdit } = useContext(PopUpContext);
const { setErrorData, setSuccessData } = useContext(alertContext);
function setModalOpen(x: boolean) {
if (x === false) {
setCloseEdit("codearea");
closePopUp();
}
}
console.log(dynamic);
useEffect(() => { useEffect(() => {
setValue(code); handleClick();
}, [code, setValue]); }, [])
function handleClick() { function handleClick() {
setLoading(true);
if (!dynamic) { if (!dynamic) {
postValidateCode(code) postValidateCode(code)
.then((apiReturn) => { .then((apiReturn) => {
setLoading(false);
if (apiReturn.data) { if (apiReturn.data) {
let importsErrors = apiReturn.data.imports.errors; let importsErrors = apiReturn.data.imports.errors;
let funcErrors = apiReturn.data.function.errors; let funcErrors = apiReturn.data.function.errors;
@ -95,7 +83,6 @@ export default function CodeAreaModal({
} }
}) })
.catch((_) => { .catch((_) => {
setLoading(false);
setErrorData({ setErrorData({
title: "There is something wrong with this code, please review it", title: "There is something wrong with this code, please review it",
}); });
@ -106,74 +93,51 @@ export default function CodeAreaModal({
const { data } = apiReturn; const { data } = apiReturn;
if (data) { if (data) {
setNodeClass(data); setNodeClass(data);
setModalOpen(false); setOpen(false);
} }
}) })
.catch((err) => { .catch((err) => {
setErrorData({
title:
"There is something wrong with this code, please see the error on the errors tab",
});
console.log(err.response.data);
setError(err.response.data); setError(err.response.data);
}); });
} }
// axios.get("/api/v1/custom_component_error").catch((err) => {
// })
} }
const tabs = [{ name: "code" }, { name: "errors" }];
useEffect(() => {
// Function to be executed after the state changes
const delayedFunction = setTimeout(() => {
if (error?.detail.error !== undefined) {
//trigger to update the height, does not really apply any height
setHeight("90%");
}
//600 to happen after the transition of 500ms
}, 600);
// Cleanup function to clear the timeout if the component unmounts or the state changes again
return () => {
clearTimeout(delayedFunction);
};
}, [error, setHeight]);
const [open, setOpen] = useState(false);
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <BaseModal open={open} setOpen={setOpen}>
<DialogTrigger></DialogTrigger> <BaseModal.Trigger>{children}</BaseModal.Trigger>
<DialogContent className="min-w-[80vw]"> <BaseModal.Header description={CODE_PROMPT_DIALOG_SUBTITLE}>
<DialogHeader>
<DialogTitle className="flex items-center">
<span className="pr-2">Edit Code</span> <span className="pr-2">Edit Code</span>
<TerminalSquare <TerminalSquare
strokeWidth={1.5} strokeWidth={1.5}
className="h-6 w-6 pl-1 text-primary " className="h-6 w-6 pl-1 text-primary "
aria-hidden="true" aria-hidden="true"
/> />
</DialogTitle> </BaseModal.Header>
<DialogDescription>{CODE_PROMPT_DIALOG_SUBTITLE}</DialogDescription> <BaseModal.Content>
</DialogHeader> <div className="flex h-full w-full flex-col transition-all">
<Tabs
defaultValue={"0"}
className="h-full w-full overflow-hidden rounded-md border bg-muted text-center"
onValueChange={(value) => setActiveTab(value)}
>
<div className="flex h-72 flex-col items-start px-2">
<TabsList>
{tabs.map((tab, index) => (
<TabsTrigger
disabled={index === 1 && error?.detail.error === undefined}
key={index}
value={index.toString()}
>
<span
className={
error?.detail.error !== undefined && index === 1
? "text-destructive"
: ""
}
>
{tab.name}
</span>
</TabsTrigger>
))}
</TabsList>
{tabs.map((tab, index) => (
<TabsContent
value={index.toString()}
className="mt-1 h-full w-full overflow-hidden px-4 pb-4"
>
{tab.name === "code" ? (
<div className="h-full w-full"> <div className="h-full w-full">
<AceEditor <AceEditor
value={code} value={code}
mode="python" mode="python"
height={height ?? "100%"}
highlightActiveLine={true} highlightActiveLine={true}
showPrintMargin={false} showPrintMargin={false}
fontSize={14} fontSize={14}
@ -184,31 +148,16 @@ export default function CodeAreaModal({
onChange={(value) => { onChange={(value) => {
setCode(value); setCode(value);
}} }}
className="h-full w-full rounded-lg border-[1px] border-gray-300 custom-scroll dark:border-gray-600" className="h-full w-full rounded-lg border-[1px] border-border custom-scroll"
/> />
</div> </div>
) : ( <div className="flex h-fit w-full justify-end">
<div className="flex h-full w-full flex-col overflow-scroll bg-red-200 p-2 text-left custom-scroll">
<h1 className="text-lg text-red-600">
{error?.detail?.error}
</h1>
<span className="w-full border border-red-300"></span>
<div className="text-sm text-red-500">
{error?.detail?.traceback}
</div>
</div>
)}
</TabsContent>
))}
</div>
</Tabs>
<DialogFooter>
<Button className="mt-3" onClick={handleClick} type="submit"> <Button className="mt-3" onClick={handleClick} type="submit">
{/* {loading?(<Loading/>):'Check & Save'} */}
Check & Save Check & Save
</Button> </Button>
</DialogFooter> </div>
</DialogContent> </div>
</Dialog> </BaseModal.Content>
</BaseModal>
); );
} }

View file

@ -1,60 +1,34 @@
import { Download } from "lucide-react"; import { Download } from "lucide-react";
import { useContext, useRef, useState } from "react"; import { ReactNode, forwardRef, useContext, useState } from "react";
import EditFlowSettings from "../../components/EditFlowSettingsComponent"; import EditFlowSettings from "../../components/EditFlowSettingsComponent";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
import { Checkbox } from "../../components/ui/checkbox"; import { Checkbox } from "../../components/ui/checkbox";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import { EXPORT_DIALOG_SUBTITLE } from "../../constants"; import { EXPORT_DIALOG_SUBTITLE } from "../../constants";
import { alertContext } from "../../contexts/alertContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { removeApiKeys } from "../../utils"; import { removeApiKeys } from "../../utils";
import BaseModal from "../baseModal";
export default function ExportModal() { const ExportModal = forwardRef((props: { children: ReactNode }, ref) => {
const [open, setOpen] = useState(true);
const { closePopUp } = useContext(PopUpContext);
const ref = useRef();
const { setErrorData } = useContext(alertContext);
const { flows, tabId, updateFlow, downloadFlow, saveFlow } = const { flows, tabId, updateFlow, downloadFlow, saveFlow } =
useContext(TabsContext); useContext(TabsContext);
const [isMaxLength, setIsMaxLength] = useState(false);
function setModalOpen(x: boolean) {
setOpen(x);
if (x === false) {
setTimeout(() => {
closePopUp();
}, 300);
}
}
const [checked, setChecked] = useState(false); const [checked, setChecked] = useState(false);
const [name, setName] = useState(flows.find((f) => f.id === tabId).name); const [name, setName] = useState(flows.find((f) => f.id === tabId).name);
const [description, setDescription] = useState( const [description, setDescription] = useState(
flows.find((f) => f.id === tabId).description flows.find((f) => f.id === tabId).description
); );
const [open, setOpen] = useState(false);
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <BaseModal size="smaller" open={open} setOpen={setOpen}>
<DialogTrigger asChild></DialogTrigger> <BaseModal.Trigger>{props.children}</BaseModal.Trigger>
<DialogContent className="h-[420px] lg:max-w-[600px] "> <BaseModal.Header description={EXPORT_DIALOG_SUBTITLE}>
<DialogHeader>
<DialogTitle className="flex items-center">
<span className="pr-2">Export</span> <span className="pr-2">Export</span>
<Download <Download
strokeWidth={1.5} strokeWidth={1.5}
className="h-6 w-6 pl-1 text-foreground" className="h-6 w-6 pl-1 text-primary "
aria-hidden="true" aria-hidden="true"
/> />
</DialogTitle> </BaseModal.Header>
<DialogDescription>{EXPORT_DIALOG_SUBTITLE}</DialogDescription> <BaseModal.Content>
</DialogHeader>
<EditFlowSettings <EditFlowSettings
name={name} name={name}
description={description} description={description}
@ -64,19 +38,20 @@ export default function ExportModal() {
setDescription={setDescription} setDescription={setDescription}
updateFlow={updateFlow} updateFlow={updateFlow}
/> />
<div className="flex items-center space-x-2"> <div className="mt-3 flex items-center space-x-2">
<Checkbox <Checkbox
id="terms" id="terms"
onCheckedChange={(event: boolean) => { onCheckedChange={(event: boolean) => {
setChecked(event); setChecked(event);
}} }}
/> />
<label htmlFor="terms" className="export-modal-save-api text-sm"> <label htmlFor="terms" className="export-modal-save-api text-sm ">
Save with my API keys Save with my API keys
</label> </label>
</div> </div>
</BaseModal.Content>
<DialogFooter> <BaseModal.Footer>
<Button <Button
onClick={() => { onClick={() => {
if (checked) if (checked)
@ -91,15 +66,14 @@ export default function ExportModal() {
name, name,
description description
); );
setOpen(false);
closePopUp();
}} }}
type="submit" type="submit"
> >
Download Flow Download Flow
</Button> </Button>
</DialogFooter> </BaseModal.Footer>
</DialogContent> </BaseModal>
</Dialog>
); );
} });
export default ExportModal;

View file

@ -2,23 +2,18 @@ import { Settings2 } from "lucide-react";
import { useContext, useRef, useState } from "react"; import { useContext, useRef, useState } from "react";
import EditFlowSettings from "../../components/EditFlowSettingsComponent"; import EditFlowSettings from "../../components/EditFlowSettingsComponent";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import { SETTINGS_DIALOG_SUBTITLE } from "../../constants"; import { SETTINGS_DIALOG_SUBTITLE } from "../../constants";
import { alertContext } from "../../contexts/alertContext"; import { alertContext } from "../../contexts/alertContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import BaseModal from "../baseModal";
export default function FlowSettingsModal() { export default function FlowSettingsModal({
const [open, setOpen] = useState(true); open,
const { closePopUp } = useContext(PopUpContext); setOpen,
}: {
open: boolean;
setOpen: (open: boolean) => void;
}) {
const { setErrorData, setSuccessData } = useContext(alertContext); const { setErrorData, setSuccessData } = useContext(alertContext);
const ref = useRef(); const ref = useRef();
const { flows, tabId, updateFlow, setTabsState, saveFlow } = const { flows, tabId, updateFlow, setTabsState, saveFlow } =
@ -28,34 +23,25 @@ export default function FlowSettingsModal() {
const [description, setDescription] = useState( const [description, setDescription] = useState(
flows.find((f) => f.id === tabId).description flows.find((f) => f.id === tabId).description
); );
function setModalOpen(x: boolean) {
setOpen(x);
if (x === false) {
setTimeout(() => {
closePopUp();
}, 300);
}
}
function handleClick() { function handleClick() {
let savedFlow = flows.find((f) => f.id === tabId); let savedFlow = flows.find((f) => f.id === tabId);
savedFlow.name = name; savedFlow.name = name;
savedFlow.description = description; savedFlow.description = description;
saveFlow(savedFlow); saveFlow(savedFlow);
setSuccessData({ title: "Changes saved successfully" }); setSuccessData({ title: "Changes saved successfully" });
closePopUp(); setOpen(false);
} }
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <BaseModal open={open} setOpen={setOpen} size="smaller">
<DialogTrigger asChild></DialogTrigger> <BaseModal.Header description={SETTINGS_DIALOG_SUBTITLE}>
<DialogContent className="h-[390px] lg:max-w-[600px]"> <span className="pr-2">Settings</span>
<DialogHeader> <Settings2
<DialogTitle className="flex items-center"> strokeWidth={1.5}
<span className="pr-2">Settings </span> className="h-6 w-6 pl-1 text-primary "
<Settings2 className="mr-2 h-4 w-4 " /> aria-hidden="true"
</DialogTitle> />
<DialogDescription>{SETTINGS_DIALOG_SUBTITLE}</DialogDescription> </BaseModal.Header>
</DialogHeader> <BaseModal.Content>
<EditFlowSettings <EditFlowSettings
name={name} name={name}
description={description} description={description}
@ -65,13 +51,13 @@ export default function FlowSettingsModal() {
setDescription={setDescription} setDescription={setDescription}
updateFlow={updateFlow} updateFlow={updateFlow}
/> />
</BaseModal.Content>
<DialogFooter> <BaseModal.Footer>
<Button onClick={handleClick} type="submit"> <Button onClick={handleClick} type="submit">
Save Save
</Button> </Button>
</DialogFooter> </BaseModal.Footer>
</DialogContent> </BaseModal>
</Dialog>
); );
} }

View file

@ -36,7 +36,7 @@ export default function FormModal({
setOpen, setOpen,
}: { }: {
open: boolean; open: boolean;
setOpen: Function; setOpen: (open: boolean) => void;
flow: FlowType; flow: FlowType;
}) { }) {
const { tabsState, setTabsState } = useContext(TabsContext); const { tabsState, setTabsState } = useContext(TabsContext);
@ -389,8 +389,8 @@ export default function FormModal({
} }
} }
return ( return (
<Dialog open={open} onOpenChange={setModalOpen}> <Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger className="hidden"></DialogTrigger> <DialogTrigger hidden></DialogTrigger>
{tabsState[flow.id].formKeysData && ( {tabsState[flow.id].formKeysData && (
<DialogContent className="min-w-[80vw]"> <DialogContent className="min-w-[80vw]">
<DialogHeader> <DialogHeader>

View file

@ -1,10 +1,9 @@
import { FileText, Variable } from "lucide-react"; import { FileText, Variable } from "lucide-react";
import { useContext, useEffect, useRef, useState } from "react"; import { ReactNode, useContext, useEffect, useRef, useState } from "react";
import SanitizedHTMLWrapper from "../../components/SanitizedHTMLWrapper"; import SanitizedHTMLWrapper from "../../components/SanitizedHTMLWrapper";
import ShadTooltip from "../../components/ShadTooltipComponent"; import ShadTooltip from "../../components/ShadTooltipComponent";
import { Badge } from "../../components/ui/badge"; import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
import { DialogTitle } from "../../components/ui/dialog";
import { Textarea } from "../../components/ui/textarea"; import { Textarea } from "../../components/ui/textarea";
import { import {
MAX_WORDS_HIGHLIGHT, MAX_WORDS_HIGHLIGHT,
@ -12,13 +11,10 @@ import {
TEXT_DIALOG_SUBTITLE, TEXT_DIALOG_SUBTITLE,
} from "../../constants"; } from "../../constants";
import { alertContext } from "../../contexts/alertContext"; import { alertContext } from "../../contexts/alertContext";
import { darkContext } from "../../contexts/darkContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { postValidatePrompt } from "../../controllers/API"; import { postValidatePrompt } from "../../controllers/API";
import { APIClassType } from "../../types/api"; import { APIClassType } from "../../types/api";
import { import {
INVALID_CHARACTERS, INVALID_CHARACTERS,
TypeModal,
classNames, classNames,
getRandomKeyByssmm, getRandomKeyByssmm,
regexHighlight, regexHighlight,
@ -35,13 +31,15 @@ export default function GenericModal({
type, type,
nodeClass, nodeClass,
setNodeClass, setNodeClass,
children,
}: { }: {
field_name?: string; field_name?: string;
setValue: (value: string) => void; setValue: (value: string) => void;
value: string; value: string;
buttonText: string; buttonText: string;
modalTitle: string; modalTitle: string;
type: number; type: "prompt" | "text";
children: ReactNode;
nodeClass?: APIClassType; nodeClass?: APIClassType;
setNodeClass?: (Class: APIClassType) => void; setNodeClass?: (Class: APIClassType) => void;
}) { }) {
@ -51,17 +49,9 @@ export default function GenericModal({
const [inputValue, setInputValue] = useState(value); const [inputValue, setInputValue] = useState(value);
const [isEdit, setIsEdit] = useState(true); const [isEdit, setIsEdit] = useState(true);
const [wordsHighlight, setWordsHighlight] = useState([]); const [wordsHighlight, setWordsHighlight] = useState([]);
const { dark } = useContext(darkContext);
const { setErrorData, setSuccessData, setNoticeData } = const { setErrorData, setSuccessData, setNoticeData } =
useContext(alertContext); useContext(alertContext);
const { closePopUp, setCloseEdit } = useContext(PopUpContext);
const ref = useRef(); const ref = useRef();
function setModalOpen(x: boolean) {
if (x === false) {
setCloseEdit("generic");
closePopUp();
}
}
const divRef = useRef(null); const divRef = useRef(null);
const divRefPrompt = useRef(null); const divRefPrompt = useRef(null);
@ -100,7 +90,7 @@ export default function GenericModal({
} }
useEffect(() => { useEffect(() => {
if (type === TypeModal.PROMPT && inputValue && inputValue != "") { if (type === "prompt" && inputValue && inputValue != "") {
checkVariables(inputValue); checkVariables(inputValue);
} }
}, [inputValue, type]); }, [inputValue, type]);
@ -170,8 +160,11 @@ export default function GenericModal({
}); });
} }
const [modalOpen, setModalOpen] = useState(false);
return ( return (
<BaseModal open={true} setOpen={setModalOpen}> <BaseModal open={modalOpen} setOpen={setModalOpen}>
<BaseModal.Trigger>{children}</BaseModal.Trigger>
<BaseModal.Header <BaseModal.Header
description={(() => { description={(() => {
switch (myModalTitle) { switch (myModalTitle) {
@ -186,14 +179,12 @@ export default function GenericModal({
} }
})()} })()}
> >
<DialogTitle className="flex items-center">
<span className="pr-2">{myModalTitle}</span> <span className="pr-2">{myModalTitle}</span>
<FileText <FileText
strokeWidth={1.5} strokeWidth={1.5}
className="h-6 w-6 pl-1 text-primary " className="h-6 w-6 pl-1 text-primary "
aria-hidden="true" aria-hidden="true"
/> />
</DialogTitle>
</BaseModal.Header> </BaseModal.Header>
<BaseModal.Content> <BaseModal.Content>
<div className="flex h-full flex-col"> <div className="flex h-full flex-col">
@ -203,7 +194,7 @@ export default function GenericModal({
"flex h-full w-full" "flex h-full w-full"
)} )}
> >
{type === TypeModal.PROMPT && isEdit ? ( {type === "prompt" && isEdit ? (
<Textarea <Textarea
ref={divRefPrompt} ref={divRefPrompt}
className="form-input h-full w-full rounded-lg custom-scroll focus-visible:ring-1" className="form-input h-full w-full rounded-lg custom-scroll focus-visible:ring-1"
@ -218,9 +209,9 @@ export default function GenericModal({
}} }}
placeholder="Type message here." placeholder="Type message here."
/> />
) : type === TypeModal.PROMPT && !isEdit ? ( ) : type === "prompt" && !isEdit ? (
<TextAreaContentView /> <TextAreaContentView />
) : type !== TypeModal.PROMPT ? ( ) : type !== "prompt" ? (
<Textarea <Textarea
ref={ref} ref={ref}
className="form-input h-full w-full rounded-lg focus-visible:ring-1" className="form-input h-full w-full rounded-lg focus-visible:ring-1"
@ -237,7 +228,7 @@ export default function GenericModal({
<div className="mt-6 flex h-fit w-full items-end justify-between"> <div className="mt-6 flex h-fit w-full items-end justify-between">
<div className="mb-auto flex-1"> <div className="mb-auto flex-1">
{type === TypeModal.PROMPT && ( {type === "prompt" && (
<div className=" mr-2"> <div className=" mr-2">
<div <div
ref={divRef} ref={divRef}
@ -274,7 +265,7 @@ export default function GenericModal({
))} ))}
</div> </div>
</div> </div>
<span className="mt-1 text-xs text-muted-foreground"> <span className="mt-2 text-xs text-muted-foreground">
Prompt variables can be created with any chosen name inside Prompt variables can be created with any chosen name inside
curly brackets, e.g. {"{variable_name}"} curly brackets, e.g. {"{variable_name}"}
</span> </span>
@ -284,11 +275,11 @@ export default function GenericModal({
<Button <Button
onClick={() => { onClick={() => {
switch (myModalType) { switch (myModalType) {
case 1: case "text":
setValue(inputValue); setValue(inputValue);
setModalOpen(false); setModalOpen(false);
break; break;
case 2: case "prompt":
!inputValue || inputValue === "" !inputValue || inputValue === ""
? setModalOpen(false) ? setModalOpen(false)
: validatePrompt(false); : validatePrompt(false);

View file

@ -17,7 +17,6 @@ import {
} from "../../components/ui/dialog"; } from "../../components/ui/dialog";
import { IMPORT_DIALOG_SUBTITLE } from "../../constants"; import { IMPORT_DIALOG_SUBTITLE } from "../../constants";
import { alertContext } from "../../contexts/alertContext"; import { alertContext } from "../../contexts/alertContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { getExamples } from "../../controllers/API"; import { getExamples } from "../../controllers/API";
import { FlowType } from "../../types/flow"; import { FlowType } from "../../types/flow";
@ -27,20 +26,11 @@ import ButtonBox from "./buttonBox";
export default function ImportModal() { export default function ImportModal() {
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
const { setErrorData } = useContext(alertContext); const { setErrorData } = useContext(alertContext);
const { closePopUp } = useContext(PopUpContext);
const ref = useRef(); const ref = useRef();
const [showExamples, setShowExamples] = useState(false); const [showExamples, setShowExamples] = useState(false);
const [loadingExamples, setLoadingExamples] = useState(false); const [loadingExamples, setLoadingExamples] = useState(false);
const [examples, setExamples] = useState<FlowType[]>([]); const [examples, setExamples] = useState<FlowType[]>([]);
const { uploadFlow, addFlow } = useContext(TabsContext); const { uploadFlow, addFlow } = useContext(TabsContext);
function setModalOpen(x: boolean) {
setOpen(x);
if (x === false) {
setTimeout(() => {
closePopUp();
}, 300);
}
}
function handleExamples() { function handleExamples() {
setLoadingExamples(true); setLoadingExamples(true);
@ -57,8 +47,10 @@ export default function ImportModal() {
); );
} }
const [modalOpen, setModalOpen] = useState(false);
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <Dialog open={modalOpen} onOpenChange={setModalOpen}>
<DialogTrigger></DialogTrigger> <DialogTrigger></DialogTrigger>
<DialogContent <DialogContent
className={classNames( className={classNames(

View file

@ -3,7 +3,6 @@ import { useContext, useState } from "react";
import ShadTooltip from "../../../../components/ShadTooltipComponent"; import ShadTooltip from "../../../../components/ShadTooltipComponent";
import { Separator } from "../../../../components/ui/separator"; import { Separator } from "../../../../components/ui/separator";
import { alertContext } from "../../../../contexts/alertContext"; import { alertContext } from "../../../../contexts/alertContext";
import { PopUpContext } from "../../../../contexts/popUpContext";
import { TabsContext } from "../../../../contexts/tabsContext"; import { TabsContext } from "../../../../contexts/tabsContext";
import { typesContext } from "../../../../contexts/typesContext"; import { typesContext } from "../../../../contexts/typesContext";
import ApiModal from "../../../../modals/ApiModal"; import ApiModal from "../../../../modals/ApiModal";
@ -19,7 +18,6 @@ import DisclosureComponent from "../DisclosureComponent";
export default function ExtraSidebar() { export default function ExtraSidebar() {
const { data } = useContext(typesContext); const { data } = useContext(typesContext);
const { openPopUp } = useContext(PopUpContext);
const { flows, tabId, uploadFlow, tabsState, saveFlow } = const { flows, tabId, uploadFlow, tabsState, saveFlow } =
useContext(TabsContext); useContext(TabsContext);
const { setSuccessData, setErrorData } = useContext(alertContext); const { setSuccessData, setErrorData } = useContext(alertContext);
@ -56,6 +54,7 @@ export default function ExtraSidebar() {
return ret; return ret;
}); });
} }
const flow = flows.find((f) => f.id === tabId);
return ( return (
<div className="side-bar-arrangement"> <div className="side-bar-arrangement">
@ -64,7 +63,6 @@ export default function ExtraSidebar() {
<button <button
className="extra-side-bar-buttons" className="extra-side-bar-buttons"
onClick={() => { onClick={() => {
// openPopUp(<ImportModal />);
uploadFlow(); uploadFlow();
}} }}
> >
@ -76,34 +74,33 @@ export default function ExtraSidebar() {
</ShadTooltip> </ShadTooltip>
<ShadTooltip content="Export" side="top"> <ShadTooltip content="Export" side="top">
<button <ExportModal>
className={classNames("extra-side-bar-buttons")} <div className={classNames("extra-side-bar-buttons")}>
onClick={(event) => {
openPopUp(<ExportModal />);
}}
>
<FileDown <FileDown
strokeWidth={1.5} strokeWidth={1.5}
className="side-bar-button-size" className="side-bar-button-size"
></FileDown> ></FileDown>
</button> </div>
</ExportModal>
</ShadTooltip> </ShadTooltip>
<ShadTooltip content="Code" side="top"> <ShadTooltip content="Code" side="top">
<button {flow && flow.data && (
className={classNames("extra-side-bar-buttons")} <ApiModal flow={flow}>
onClick={(event) => { <div className={classNames("extra-side-bar-buttons")}>
openPopUp(<ApiModal flow={flows.find((f) => f.id === tabId)} />); <Code2
}} strokeWidth={1.5}
> className="side-bar-button-size"
<Code2 strokeWidth={1.5} className="side-bar-button-size"></Code2> ></Code2>
</button> </div>
</ApiModal>
)}
</ShadTooltip> </ShadTooltip>
<ShadTooltip content="Save" side="top"> <ShadTooltip content="Save" side="top">
<button <button
className="extra-side-bar-buttons" className="extra-side-bar-buttons"
onClick={(event) => { onClick={(event) => {
saveFlow(flows.find((f) => f.id === tabId)); saveFlow(flow);
setSuccessData({ title: "Changes saved successfully" }); setSuccessData({ title: "Changes saved successfully" });
}} }}
disabled={!isPending} disabled={!isPending}

View file

@ -6,24 +6,24 @@ import { TabsContext } from "../../../../contexts/tabsContext";
import EditNodeModal from "../../../../modals/EditNodeModal"; import EditNodeModal from "../../../../modals/EditNodeModal";
import { classNames } from "../../../../utils"; import { classNames } from "../../../../utils";
const NodeToolbarComponent = (props) => { export default function NodeToolbarComponent({ data, setData, deleteNode }) {
const [nodeLength, setNodeLength] = useState( const [nodeLength, setNodeLength] = useState(
Object.keys(props.data.node.template).filter( Object.keys(data.node.template).filter(
(t) => (t) =>
t.charAt(0) !== "_" && t.charAt(0) !== "_" &&
props.data.node.template[t].show && data.node.template[t].show &&
(props.data.node.template[t].type === "str" || (data.node.template[t].type === "str" ||
props.data.node.template[t].type === "bool" || data.node.template[t].type === "bool" ||
props.data.node.template[t].type === "float" || data.node.template[t].type === "float" ||
props.data.node.template[t].type === "code" || data.node.template[t].type === "code" ||
props.data.node.template[t].type === "prompt" || data.node.template[t].type === "prompt" ||
props.data.node.template[t].type === "file" || data.node.template[t].type === "file" ||
props.data.node.template[t].type === "Any" || data.node.template[t].type === "Any" ||
props.data.node.template[t].type === "int") data.node.template[t].type === "int")
).length ).length
); );
const { setLastCopiedSelection, paste } = useContext(TabsContext); const { paste } = useContext(TabsContext);
const reactFlowInstance = useReactFlow(); const reactFlowInstance = useReactFlow();
return ( return (
<> <>
@ -33,7 +33,7 @@ const NodeToolbarComponent = (props) => {
<button <button
className="relative inline-flex items-center rounded-l-md 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" className="relative inline-flex items-center rounded-l-md 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"
onClick={() => { onClick={() => {
props.deleteNode(props.data.id); deleteNode(data.id);
}} }}
> >
<Trash2 className="h-4 w-4"></Trash2> <Trash2 className="h-4 w-4"></Trash2>
@ -49,14 +49,14 @@ const NodeToolbarComponent = (props) => {
event.preventDefault(); event.preventDefault();
paste( paste(
{ {
nodes: [reactFlowInstance.getNode(props.data.id)], nodes: [reactFlowInstance.getNode(data.id)],
edges: [], edges: [],
}, },
{ {
x: 50, x: 50,
y: 10, y: 10,
paneX: reactFlowInstance.getNode(props.data.id).position.x, paneX: reactFlowInstance.getNode(data.id).position.x,
paneY: reactFlowInstance.getNode(props.data.id).position.y, paneY: reactFlowInstance.getNode(data.id).position.y,
} }
); );
}} }}
@ -67,25 +67,23 @@ const NodeToolbarComponent = (props) => {
<ShadTooltip <ShadTooltip
content={ content={
props.data.node.documentation === "" data.node.documentation === "" ? "Coming Soon" : "Documentation"
? "Coming Soon"
: "Documentation"
} }
side="top" side="top"
> >
<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" +
(props.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"
href={props.data.node.documentation} href={data.node.documentation}
// deactivate link if no documentation is provided // deactivate link if no documentation is provided
onClick={(event) => { onClick={(event) => {
if (props.data.node.documentation === "") { if (data.node.documentation === "") {
event.preventDefault(); event.preventDefault();
} }
}} }}
@ -95,121 +93,25 @@ const NodeToolbarComponent = (props) => {
</ShadTooltip> </ShadTooltip>
<ShadTooltip content="Edit" side="top"> <ShadTooltip content="Edit" side="top">
<button <EditNodeModal
data={data}
setData={setData}
nodeLength={nodeLength}
>
<div
className={classNames( className={classNames(
"relative -ml-px inline-flex items-center rounded-r-md 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 rounded-r-md 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") : " text-foreground")
)} )}
onClick={(event) => {
if (nodeLength == 0) {
event.preventDefault();
}
event.preventDefault();
props.openPopUp(<EditNodeModal data={props.data} />);
}}
> >
<Settings2 className="h-4 w-4 "></Settings2> <Settings2 className="h-4 w-4 "></Settings2>
</button> </div>
</EditNodeModal>
</ShadTooltip> </ShadTooltip>
{/*
<Menu as="div" className="relative inline-block text-left z-100">
<button className="hover:dark:hover:bg-[#242f47] text-gray-700 transition-all duration-500 ease-in-out dark:bg-gray-800 dark:text-gray-300 shadow-md relative -ml-px inline-flex items-center bg-white px-2 py-2 ring-1 ring-inset ring-gray-300 hover:bg-muted focus:z-10 rounded-r-md">
<div>
<Menu.Button className="flex items-center">
<EllipsisVerticalIcon
className="w-5 h-5 "
aria-hidden="true"
/>
</Menu.Button>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute z-40 mt-2 w-56 origin-top-right rounded-md bg-background shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none top-[28px]">
<div className="py-1">
<Menu.Item>
{({ active }) => (
<button
onClick={(event) => {
event.preventDefault();
props.openPopUp(
<EditNodeModal data={props.data} />
);
}}
className={classNames(
active
? "bg-muted text-gray-900"
: "text-foreground",
"w-full group flex items-center px-4 py-2 text-sm"
)}
>
<Settings
className="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
Edit
</button>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<button
onClick={(event) => {
event.preventDefault();
console.log(
reactFlowInstance.getNode(props.data.id)
);
paste(
{
nodes: [
reactFlowInstance.getNode(props.data.id),
],
edges: [],
},
{
x: 50,
y: 10,
paneX: reactFlowInstance.getNode(props.data.id)
.position.x,
paneY: reactFlowInstance.getNode(props.data.id)
.position.y,
}
);
}}
className={classNames(
active
? "bg-muted text-gray-900"
: "text-foreground",
"w-full group flex items-center px-4 py-2 text-sm"
)}
>
<DocumentDuplicateIcon
className="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
Duplicate
</button>
)}
</Menu.Item>
</div>
</Menu.Items>
</Transition>
</button>
</Menu> */}
</span> </span>
</div> </div>
</> </>
); );
}; }
export default NodeToolbarComponent;

View file

@ -28,6 +28,7 @@ export type DropDownComponentType = {
}; };
export type ParameterComponentType = { export type ParameterComponentType = {
data: NodeDataType; data: NodeDataType;
setData: (value: NodeDataType) => void;
title: string; title: string;
id: string; id: string;
color: string; color: string;

View file

@ -59,11 +59,6 @@ export function classNames(...classes: Array<string>) {
export const limitScrollFieldsModal = 10; export const limitScrollFieldsModal = 10;
export enum TypeModal {
TEXT = 1,
PROMPT = 2,
}
export const textColors = { export const textColors = {
white: "text-white", white: "text-white",
red: "text-red-700", red: "text-red-700",

View file

@ -132,7 +132,7 @@ module.exports = {
keyframes: { keyframes: {
slideDown: { slideDown: {
from: { height: 0 }, from: { height: 0 },
to: { height: 100 }, to: { height: "100vh" },
}, },
slideUp: { slideUp: {
from: { height: "var(--radix-accordion-content-height)" }, from: { height: "var(--radix-accordion-content-height)" },