From 6985b179d9be9fdd5a9cff04855c58ba820f8e69 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 10 Jun 2024 17:19:19 -0300 Subject: [PATCH 1/4] Fixed margin on buttons --- .../pages/ApiKeysPage/components/ApiKeyHeader/index.tsx | 2 +- .../src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/components/ApiKeyHeader/index.tsx b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/components/ApiKeyHeader/index.tsx index 4138d621f..9647cd96a 100644 --- a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/components/ApiKeyHeader/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/components/ApiKeyHeader/index.tsx @@ -29,7 +29,7 @@ const ApiKeyHeaderComponent = ({
diff --git a/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx index 131f7f46e..3c5d797b7 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx @@ -144,7 +144,7 @@ export default function GlobalVariablesPage() {
From 2bbce3798cda9771a9df67ac6254742cc5ce9194 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 10 Jun 2024 17:22:38 -0300 Subject: [PATCH 2/4] Fixed apiModal view --- .../src/components/chatComponent/index.tsx | 2 +- src/frontend/src/modals/apiModal/index.tsx | 263 +++++++++--------- .../src/modals/apiModal/views/index.tsx | 241 ---------------- 3 files changed, 127 insertions(+), 379 deletions(-) delete mode 100644 src/frontend/src/modals/apiModal/views/index.tsx diff --git a/src/frontend/src/components/chatComponent/index.tsx b/src/frontend/src/components/chatComponent/index.tsx index 5bcaade0a..fab9a88d7 100644 --- a/src/frontend/src/components/chatComponent/index.tsx +++ b/src/frontend/src/components/chatComponent/index.tsx @@ -2,7 +2,7 @@ import { Transition } from "@headlessui/react"; import { useMemo, useRef, useState } from "react"; import { useHotkeys } from "react-hotkeys-hook"; import IOModal from "../../modals/IOModal"; -import ApiModal from "../../modals/apiModal/views"; +import ApiModal from "../../modals/apiModal"; import ShareModal from "../../modals/shareModal"; import useFlowStore from "../../stores/flowStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore"; diff --git a/src/frontend/src/modals/apiModal/index.tsx b/src/frontend/src/modals/apiModal/index.tsx index 874e93f5b..c6fed4175 100644 --- a/src/frontend/src/modals/apiModal/index.tsx +++ b/src/frontend/src/modals/apiModal/index.tsx @@ -2,35 +2,29 @@ import "ace-builds/src-noconflict/ext-language_tools"; import "ace-builds/src-noconflict/mode-python"; import "ace-builds/src-noconflict/theme-github"; import "ace-builds/src-noconflict/theme-twilight"; -import { - ReactNode, - forwardRef, - useContext, - useEffect, - useRef, - useState, -} from "react"; +import { ReactNode, forwardRef, useContext, useEffect, useState } from "react"; // import "ace-builds/webpack-resolver"; +import { cloneDeep } from "lodash"; import CodeTabsComponent from "../../components/codeTabsComponent"; import IconComponent from "../../components/genericIconComponent"; -import { - EXPORT_CODE_DIALOG, - LANGFLOW_SUPPORTED_TYPES, -} from "../../constants/constants"; +import { EXPORT_CODE_DIALOG } from "../../constants/constants"; import { AuthContext } from "../../contexts/authContext"; -import useFlowStore from "../../stores/flowStore"; +import { useTweaksStore } from "../../stores/tweaksStore"; import { TemplateVariableType } from "../../types/api"; -import { tweakType, uniqueTweakType } from "../../types/components"; -import { FlowType, NodeType } from "../../types/flow/index"; -import { buildTweaks, convertArrayToObj } from "../../utils/reactflowUtils"; -import { - getCurlCode, - getPythonApiCode, - getPythonCode, - getWidgetCode, - tabsArray, -} from "../../utils/utils"; +import { uniqueTweakType } from "../../types/components"; +import { FlowType } from "../../types/flow/index"; import BaseModal from "../baseModal"; +import { buildContent } from "./utils/build-content"; +import { buildTweaks } from "./utils/build-tweaks"; +import { checkCanBuildTweakObject } from "./utils/check-can-build-tweak-object"; +import { getChangesType } from "./utils/get-changes-types"; +import { getCurlRunCode, getCurlWebhookCode } from "./utils/get-curl-code"; +import { getNodesWithDefaultValue } from "./utils/get-nodes-with-default-value"; +import getPythonApiCode from "./utils/get-python-api-code"; +import getPythonCode from "./utils/get-python-code"; +import { getValue } from "./utils/get-value"; +import getWidgetCode from "./utils/get-widget-code"; +import { createTabsArray } from "./utils/tabs-array"; const ApiModal = forwardRef( ( @@ -42,122 +36,136 @@ const ApiModal = forwardRef( }: { flow: FlowType; children: ReactNode; - open: any; - setOpen: any; + open?: boolean; + setOpen?: (a: boolean | ((o?: boolean) => boolean)) => void; }, - ref + ref, ) => { + const tweak = useTweaksStore((state) => state.tweak); + const addTweaks = useTweaksStore((state) => state.setTweak); + const setTweaksList = useTweaksStore((state) => state.setTweaksList); + const tweaksList = useTweaksStore((state) => state.tweaksList); + + const [activeTweaks, setActiveTweaks] = useState(false); const { autoLogin } = useContext(AuthContext); const [open, setOpen] = mySetOpen !== undefined && myOpen !== undefined ? [myOpen, mySetOpen] : useState(false); const [activeTab, setActiveTab] = useState("0"); - const tweak = useRef([]); - const tweaksList = useRef([]); - const [getTweak, setTweak] = useState([]); - const flowState = useFlowStore((state) => state.flowState); - const pythonApiCode = getPythonApiCode(flow, autoLogin, tweak.current); - const curl_code = getCurlCode(flow, autoLogin, tweak.current); - const pythonCode = getPythonCode(flow, tweak.current); - const widgetCode = getWidgetCode(flow, autoLogin, flowState); + const pythonApiCode = getPythonApiCode( + flow?.id, + autoLogin, + tweak, + flow?.endpoint_name, + ); + const curl_run_code = getCurlRunCode( + flow?.id, + autoLogin, + tweak, + flow?.endpoint_name, + ); + const curl_webhook_code = getCurlWebhookCode( + flow?.id, + autoLogin, + flow?.endpoint_name, + ); + const pythonCode = getPythonCode(flow?.name, tweak); + const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin); + const includeWebhook = flow.webhook; const tweaksCode = buildTweaks(flow); const codesArray = [ - curl_code, + curl_run_code, + curl_webhook_code, pythonApiCode, pythonCode, widgetCode, pythonCode, ]; - const [tabs, setTabs] = useState(tabsArray(codesArray, 0)); + const [tabs, setTabs] = useState( + createTabsArray(codesArray, includeWebhook), + ); - function startState() { - tweak.current = []; - setTweak([]); - tweaksList.current = []; - } + const canShowTweaks = + flow && + flow["data"] && + flow["data"]!["nodes"] && + tweak && + tweak?.length > 0 && + activeTweaks === true; + + const buildTweaksInitialState = () => { + const newTweak: any = []; + const t = buildTweaks(flow); + newTweak.push(t); + addTweaks(newTweak); + addCodes(newTweak); + }; useEffect(() => { if (flow["data"]!["nodes"].length == 0) { - startState(); + addTweaks([]); + setTweaksList([]); } else { - tweak.current = []; - const t = buildTweaks(flow); - tweak.current.push(t); + buildTweaksInitialState(); } filterNodes(); if (Object.keys(tweaksCode).length > 0) { setActiveTab("0"); - setTabs(tabsArray(codesArray, 1)); + setTabs(createTabsArray(codesArray, includeWebhook, true)); } else { - setTabs(tabsArray(codesArray, 1)); + setTabs(createTabsArray(codesArray, includeWebhook, true)); } }, [flow["data"]!["nodes"], open]); - function filterNodes() { - let arrNodesWithValues: string[] = []; + useEffect(() => { + if (canShowTweaks) { + const nodes = flow["data"]!["nodes"]; + nodes.forEach((element) => { + const nodeId = element["id"]; + const template = element["data"]["node"]["template"]; - flow["data"]!["nodes"].forEach((node) => { - if (!node["data"]["node"]["template"]) { - return; - } - Object.keys(node["data"]["node"]["template"]) - .filter( - (templateField) => - templateField.charAt(0) !== "_" && - node.data.node.template[templateField].show && - LANGFLOW_SUPPORTED_TYPES.has( - node.data.node.template[templateField].type - ) - ) - .map((n, i) => { - arrNodesWithValues.push(node["id"]); + Object.keys(template).forEach((templateField) => { + if (checkCanBuildTweakObject(element, templateField)) { + buildTweakObject( + nodeId, + element.data.node.template[templateField].value, + element.data.node.template[templateField], + ); + } }); - }); + }); + } else { + buildTweaksInitialState(); + } + }, [activeTweaks]); - tweaksList.current = arrNodesWithValues.filter((value, index, self) => { - return self.indexOf(value) === index; - }); - } - function buildTweakObject( + const filterNodes = () => { + setTweaksList(getNodesWithDefaultValue(flow)); + }; + + async function buildTweakObject( tw: string, changes: string | string[] | boolean | number | Object[] | Object, - template: TemplateVariableType + template: TemplateVariableType, ) { - if (typeof changes === "string" && template.type === "float") { - changes = parseFloat(changes); - } - if (typeof changes === "string" && template.type === "int") { - changes = parseInt(changes); - } - if (template.list === true && Array.isArray(changes)) { - changes = changes?.filter((x) => x !== ""); - } + changes = getChangesType(changes, template); - if (template.type === "dict" && Array.isArray(changes)) { - changes = convertArrayToObj(changes); - } - - if (template.type === "NestedDict") { - changes = JSON.stringify(changes); - } - - const existingTweak = tweak.current.find((element) => - element.hasOwnProperty(tw) - ); + const existingTweak = tweak.find((element) => element.hasOwnProperty(tw)); if (existingTweak) { existingTweak[tw][template["name"]!] = changes as string; if (existingTweak[tw][template["name"]!] == template.value) { - tweak.current.forEach((element) => { + tweak.forEach((element) => { if (element[tw] && Object.keys(element[tw])?.length === 0) { - tweak.current = tweak.current.filter((obj) => { + const filteredTweaks = tweak.filter((obj) => { const prop = obj[Object.keys(obj)[0]].prop; return prop !== undefined && prop !== null && prop !== ""; }); + addTweaks(filteredTweaks); } }); } @@ -167,56 +175,34 @@ const ApiModal = forwardRef( [template["name"]!]: changes, }, } as uniqueTweakType; - tweak.current.push(newTweak); + tweak.push(newTweak); } - const pythonApiCode = getPythonApiCode(flow, autoLogin, tweak.current); - const curl_code = getCurlCode(flow, autoLogin, tweak.current); - const pythonCode = getPythonCode(flow, tweak.current); - const widgetCode = getWidgetCode(flow, autoLogin, flowState); - - tabs![0].code = curl_code; - tabs![1].code = pythonApiCode; - tabs![2].code = pythonCode; - tabs![3].code = widgetCode; - - setTweak(tweak.current); + if (tweak && tweak.length > 0) { + const cloneTweak = cloneDeep(tweak); + addCodes(cloneTweak); + addTweaks(cloneTweak); + } } - function buildContent(value: string) { - const htmlContent = ( -
- {value != null && value != "" ? value : "None"} -
+ const addCodes = (cloneTweak) => { + const pythonApiCode = getPythonApiCode(flow?.id, autoLogin, cloneTweak); + const curl_code = getCurlRunCode( + flow?.id, + autoLogin, + cloneTweak, + flow?.endpoint_name, ); - return htmlContent; - } + const pythonCode = getPythonCode(flow?.name, cloneTweak); + const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin); - function getValue( - value: string, - node: NodeType, - template: TemplateVariableType - ) { - let returnValue = value ?? ""; - - if (getTweak.length > 0) { - for (const obj of getTweak) { - Object.keys(obj).forEach((key) => { - const value = obj[key]; - if (key == node["id"]) { - Object.keys(value).forEach((key) => { - if (key == template["name"]) { - returnValue = value[key]; - } - }); - } - }); - } - } else { - return value ?? ""; + if (tabs && tabs?.length > 0) { + tabs![0].code = curl_code; + tabs![1].code = pythonApiCode; + tabs![2].code = pythonCode; + tabs![3].code = widgetCode; } - return returnValue; - } + }; return ( @@ -242,11 +228,14 @@ const ApiModal = forwardRef( buildTweakObject, getValue, }} + activeTweaks={activeTweaks} + setActiveTweaks={setActiveTweaks} + allowExport /> ); - } + }, ); export default ApiModal; diff --git a/src/frontend/src/modals/apiModal/views/index.tsx b/src/frontend/src/modals/apiModal/views/index.tsx deleted file mode 100644 index 3b41103f9..000000000 --- a/src/frontend/src/modals/apiModal/views/index.tsx +++ /dev/null @@ -1,241 +0,0 @@ -import "ace-builds/src-noconflict/ext-language_tools"; -import "ace-builds/src-noconflict/mode-python"; -import "ace-builds/src-noconflict/theme-github"; -import "ace-builds/src-noconflict/theme-twilight"; -import { ReactNode, forwardRef, useContext, useEffect, useState } from "react"; -// import "ace-builds/webpack-resolver"; -import { cloneDeep } from "lodash"; -import CodeTabsComponent from "../../../components/codeTabsComponent"; -import IconComponent from "../../../components/genericIconComponent"; -import { EXPORT_CODE_DIALOG } from "../../../constants/constants"; -import { AuthContext } from "../../../contexts/authContext"; -import { useTweaksStore } from "../../../stores/tweaksStore"; -import { TemplateVariableType } from "../../../types/api"; -import { uniqueTweakType } from "../../../types/components"; -import { FlowType } from "../../../types/flow/index"; -import BaseModal from "../../baseModal"; -import { buildContent } from "../utils/build-content"; -import { buildTweaks } from "../utils/build-tweaks"; -import { checkCanBuildTweakObject } from "../utils/check-can-build-tweak-object"; -import { getChangesType } from "../utils/get-changes-types"; -import { getCurlRunCode, getCurlWebhookCode } from "../utils/get-curl-code"; -import { getNodesWithDefaultValue } from "../utils/get-nodes-with-default-value"; -import getPythonApiCode from "../utils/get-python-api-code"; -import getPythonCode from "../utils/get-python-code"; -import { getValue } from "../utils/get-value"; -import getWidgetCode from "../utils/get-widget-code"; -import { createTabsArray } from "../utils/tabs-array"; - -const ApiModal = forwardRef( - ( - { - flow, - children, - open: myOpen, - setOpen: mySetOpen, - }: { - flow: FlowType; - children: ReactNode; - open?: boolean; - setOpen?: (a: boolean | ((o?: boolean) => boolean)) => void; - }, - ref, - ) => { - const tweak = useTweaksStore((state) => state.tweak); - const addTweaks = useTweaksStore((state) => state.setTweak); - const setTweaksList = useTweaksStore((state) => state.setTweaksList); - const tweaksList = useTweaksStore((state) => state.tweaksList); - - const [activeTweaks, setActiveTweaks] = useState(false); - const { autoLogin } = useContext(AuthContext); - const [open, setOpen] = - mySetOpen !== undefined && myOpen !== undefined - ? [myOpen, mySetOpen] - : useState(false); - const [activeTab, setActiveTab] = useState("0"); - const pythonApiCode = getPythonApiCode( - flow?.id, - autoLogin, - tweak, - flow?.endpoint_name, - ); - const curl_run_code = getCurlRunCode( - flow?.id, - autoLogin, - tweak, - flow?.endpoint_name, - ); - const curl_webhook_code = getCurlWebhookCode( - flow?.id, - autoLogin, - flow?.endpoint_name, - ); - const pythonCode = getPythonCode(flow?.name, tweak); - const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin); - const includeWebhook = flow.webhook; - const tweaksCode = buildTweaks(flow); - const codesArray = [ - curl_run_code, - curl_webhook_code, - pythonApiCode, - pythonCode, - widgetCode, - pythonCode, - ]; - const [tabs, setTabs] = useState( - createTabsArray(codesArray, includeWebhook), - ); - - const canShowTweaks = - flow && - flow["data"] && - flow["data"]!["nodes"] && - tweak && - tweak?.length > 0 && - activeTweaks === true; - - const buildTweaksInitialState = () => { - const newTweak: any = []; - const t = buildTweaks(flow); - newTweak.push(t); - addTweaks(newTweak); - addCodes(newTweak); - }; - - useEffect(() => { - if (flow["data"]!["nodes"].length == 0) { - addTweaks([]); - setTweaksList([]); - } else { - buildTweaksInitialState(); - } - - filterNodes(); - - if (Object.keys(tweaksCode).length > 0) { - setActiveTab("0"); - setTabs(createTabsArray(codesArray, includeWebhook, true)); - } else { - setTabs(createTabsArray(codesArray, includeWebhook, true)); - } - }, [flow["data"]!["nodes"], open]); - - useEffect(() => { - if (canShowTweaks) { - const nodes = flow["data"]!["nodes"]; - nodes.forEach((element) => { - const nodeId = element["id"]; - const template = element["data"]["node"]["template"]; - - Object.keys(template).forEach((templateField) => { - if (checkCanBuildTweakObject(element, templateField)) { - buildTweakObject( - nodeId, - element.data.node.template[templateField].value, - element.data.node.template[templateField], - ); - } - }); - }); - } else { - buildTweaksInitialState(); - } - }, [activeTweaks]); - - const filterNodes = () => { - setTweaksList(getNodesWithDefaultValue(flow)); - }; - - async function buildTweakObject( - tw: string, - changes: string | string[] | boolean | number | Object[] | Object, - template: TemplateVariableType, - ) { - changes = getChangesType(changes, template); - - const existingTweak = tweak.find((element) => element.hasOwnProperty(tw)); - - if (existingTweak) { - existingTweak[tw][template["name"]!] = changes as string; - - if (existingTweak[tw][template["name"]!] == template.value) { - tweak.forEach((element) => { - if (element[tw] && Object.keys(element[tw])?.length === 0) { - const filteredTweaks = tweak.filter((obj) => { - const prop = obj[Object.keys(obj)[0]].prop; - return prop !== undefined && prop !== null && prop !== ""; - }); - addTweaks(filteredTweaks); - } - }); - } - } else { - const newTweak = { - [tw]: { - [template["name"]!]: changes, - }, - } as uniqueTweakType; - tweak.push(newTweak); - } - - if (tweak && tweak.length > 0) { - const cloneTweak = cloneDeep(tweak); - addCodes(cloneTweak); - addTweaks(cloneTweak); - } - } - - const addCodes = (cloneTweak) => { - const pythonApiCode = getPythonApiCode(flow?.id, autoLogin, cloneTweak); - const curl_code = getCurlRunCode( - flow?.id, - autoLogin, - cloneTweak, - flow?.endpoint_name, - ); - const pythonCode = getPythonCode(flow?.name, cloneTweak); - const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin); - - if (tabs && tabs?.length > 0) { - tabs![0].code = curl_code; - tabs![1].code = pythonApiCode; - tabs![2].code = pythonCode; - tabs![3].code = widgetCode; - } - }; - - return ( - - {children} - - API - - - - - - ); - }, -); - -export default ApiModal; From b38e8d375ffe5566c5a744b52fed14db28861d49 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 10 Jun 2024 17:24:57 -0300 Subject: [PATCH 3/4] Fixed API modal overflow --- src/frontend/src/modals/apiModal/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/modals/apiModal/index.tsx b/src/frontend/src/modals/apiModal/index.tsx index c6fed4175..ead038ad2 100644 --- a/src/frontend/src/modals/apiModal/index.tsx +++ b/src/frontend/src/modals/apiModal/index.tsx @@ -215,7 +215,7 @@ const ApiModal = forwardRef( aria-hidden="true" /> - + Date: Mon, 10 Jun 2024 17:29:20 -0300 Subject: [PATCH 4/4] Added type to global variables --- .../src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx index 3c5d797b7..5530c8468 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx @@ -81,6 +81,7 @@ export default function GlobalVariablesPage() { flex: 2, }, //This column will be twice as wide as the others { + headerName: "Type", field: "type", cellRenderer: BadgeRenderer, cellEditor: DropdownEditor,