diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx
index 2d8fc3caa..88d990c93 100644
--- a/src/frontend/src/App.tsx
+++ b/src/frontend/src/App.tsx
@@ -19,15 +19,15 @@ import Router from "./routes";
import useAlertStore from "./stores/alertStore";
import { useDarkStore } from "./stores/darkStore";
import useFlowsManagerStore from "./stores/flowsManagerStore";
-import { useGlobalVariablesStore } from "./stores/globalVariables";
+import { useGlobalVariablesStore } from "./stores/globalVariablesStore/globalVariables";
import { useStoreStore } from "./stores/storeStore";
import { useTypesStore } from "./stores/typesStore";
export default function App() {
const removeFromTempNotificationList = useAlertStore(
- (state) => state.removeFromTempNotificationList
+ (state) => state.removeFromTempNotificationList,
);
const tempNotificationList = useAlertStore(
- (state) => state.tempNotificationList
+ (state) => state.tempNotificationList,
);
const [fetchError, setFetchError] = useState(false);
const isLoading = useFlowsManagerStore((state) => state.isLoading);
@@ -45,10 +45,10 @@ export default function App() {
const refreshVersion = useDarkStore((state) => state.refreshVersion);
const refreshStars = useDarkStore((state) => state.refreshStars);
const setGlobalVariables = useGlobalVariablesStore(
- (state) => state.setGlobalVariables
+ (state) => state.setGlobalVariables,
);
const setUnavailableFields = useGlobalVariablesStore(
- (state) => state.setUnavaliableFields
+ (state) => state.setUnavaliableFields,
);
const checkHasStore = useStoreStore((state) => state.checkHasStore);
const navigate = useNavigate();
@@ -92,8 +92,8 @@ export default function App() {
}
});
- /*
- Abort the request as it isn't needed anymore, the component being
+ /*
+ Abort the request as it isn't needed anymore, the component being
unmounted. It helps avoid, among other things, the well-known "can't
perform a React state update on an unmounted component" warning.
*/
diff --git a/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx b/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx
index 2745ba1bf..1ea7142ab 100644
--- a/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx
+++ b/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx
@@ -2,7 +2,7 @@ import { useState } from "react";
import { registerGlobalVariable } from "../../controllers/API";
import BaseModal from "../../modals/baseModal";
import useAlertStore from "../../stores/alertStore";
-import { useGlobalVariablesStore } from "../../stores/globalVariables";
+import { useGlobalVariablesStore } from "../../stores/globalVariablesStore/globalVariables";
import { useTypesStore } from "../../stores/typesStore";
import { ResponseErrorDetailAPI } from "../../types/api";
import { sortByName } from "../../utils/utils";
diff --git a/src/frontend/src/components/inputGlobalComponent/index.tsx b/src/frontend/src/components/inputGlobalComponent/index.tsx
index 2ca1aed22..7ab3cae33 100644
--- a/src/frontend/src/components/inputGlobalComponent/index.tsx
+++ b/src/frontend/src/components/inputGlobalComponent/index.tsx
@@ -2,7 +2,7 @@ import { useEffect } from "react";
import { deleteGlobalVariable } from "../../controllers/API";
import DeleteConfirmationModal from "../../modals/deleteConfirmationModal";
import useAlertStore from "../../stores/alertStore";
-import { useGlobalVariablesStore } from "../../stores/globalVariables";
+import { useGlobalVariablesStore } from "../../stores/globalVariablesStore/globalVariables";
import { InputGlobalComponentType } from "../../types/components";
import { cn } from "../../utils/utils";
import AddNewVariableButton from "../addNewVariableButtonComponent/addNewVariableButton";
diff --git a/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx b/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx
index dbcb1e3dc..c77d7308c 100644
--- a/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx
+++ b/src/frontend/src/customNodes/genericNode/components/parameterComponent/index.tsx
@@ -49,7 +49,8 @@ import {
nodeIconsLucide,
nodeNames,
} from "../../../../utils/styleUtils";
-import { classNames, groupByFamily } from "../../../../utils/utils";
+import { classNames } from "../../../../utils/utils";
+import groupByFamily from "./utils/group-by-family";
export default function ParameterComponent({
left,
diff --git a/src/frontend/src/customNodes/genericNode/components/parameterComponent/utils/group-by-family.tsx b/src/frontend/src/customNodes/genericNode/components/parameterComponent/utils/group-by-family.tsx
new file mode 100644
index 000000000..a38a31b59
--- /dev/null
+++ b/src/frontend/src/customNodes/genericNode/components/parameterComponent/utils/group-by-family.tsx
@@ -0,0 +1,119 @@
+import { APIDataType, TemplateVariableType } from "../../../../../types/api";
+import {
+ groupedObjType,
+ nodeGroupedObjType,
+} from "../../../../../types/components";
+import { NodeType } from "../../../../../types/flow";
+
+export default function groupByFamily(
+ data: APIDataType,
+ baseClasses: string,
+ left: boolean,
+ flow?: NodeType[],
+): groupedObjType[] {
+ const baseClassesSet = new Set(baseClasses.split("\n"));
+ let arrOfPossibleInputs: Array<{
+ category: string;
+ nodes: nodeGroupedObjType[];
+ full: boolean;
+ display_name?: string;
+ }> = [];
+ let arrOfPossibleOutputs: Array<{
+ category: string;
+ nodes: nodeGroupedObjType[];
+ full: boolean;
+ display_name?: string;
+ }> = [];
+ let checkedNodes = new Map();
+ const excludeTypes = new Set(["bool", "float", "code", "file", "int"]);
+
+ const checkBaseClass = (template: TemplateVariableType) => {
+ return (
+ template.type &&
+ template.show &&
+ ((!excludeTypes.has(template.type) &&
+ baseClassesSet.has(template.type)) ||
+ (template.input_types &&
+ template.input_types.some((inputType) =>
+ baseClassesSet.has(inputType),
+ )))
+ );
+ };
+
+ if (flow) {
+ // se existir o flow
+ for (const node of flow) {
+ // para cada node do flow
+ if (node!.data!.node!.flow || !node!.data!.node!.template) break; // não faz nada se o node for um group
+ const nodeData = node.data;
+
+ const foundNode = checkedNodes.get(nodeData.type); // verifica se o tipo do node já foi checado
+ checkedNodes.set(nodeData.type, {
+ hasBaseClassInTemplate:
+ foundNode?.hasBaseClassInTemplate ||
+ Object.values(nodeData.node!.template).some(checkBaseClass),
+ hasBaseClassInBaseClasses:
+ foundNode?.hasBaseClassInBaseClasses ||
+ nodeData.node!.base_classes.some((baseClass) =>
+ baseClassesSet.has(baseClass),
+ ), //seta como anterior ou verifica se o node tem base class
+ displayName: nodeData.node?.display_name,
+ });
+ }
+ }
+
+ for (const [d, nodes] of Object.entries(data)) {
+ let tempInputs: nodeGroupedObjType[] = [],
+ tempOutputs: nodeGroupedObjType[] = [];
+
+ for (const [n, node] of Object.entries(nodes!)) {
+ let foundNode = checkedNodes.get(n);
+
+ if (!foundNode) {
+ foundNode = {
+ hasBaseClassInTemplate: Object.values(node!.template).some(
+ checkBaseClass,
+ ),
+ hasBaseClassInBaseClasses: node!.base_classes.some((baseClass) =>
+ baseClassesSet.has(baseClass),
+ ),
+ displayName: node?.display_name,
+ };
+ }
+
+ if (foundNode.hasBaseClassInTemplate)
+ tempInputs.push({ node: n, displayName: foundNode.displayName });
+ if (foundNode.hasBaseClassInBaseClasses)
+ tempOutputs.push({ node: n, displayName: foundNode.displayName });
+ }
+
+ const totalNodes = Object.keys(nodes!).length;
+
+ if (tempInputs.length)
+ arrOfPossibleInputs.push({
+ category: d,
+ nodes: tempInputs,
+ full: tempInputs.length === totalNodes,
+ });
+ if (tempOutputs.length)
+ arrOfPossibleOutputs.push({
+ category: d,
+ nodes: tempOutputs,
+ full: tempOutputs.length === totalNodes,
+ });
+ }
+
+ return left
+ ? arrOfPossibleOutputs.map((output) => ({
+ family: output.category,
+ type: output.full
+ ? ""
+ : output.nodes.map((item) => item.node).join(", "),
+ display_name: "",
+ }))
+ : arrOfPossibleInputs.map((input) => ({
+ family: input.category,
+ type: input.full ? "" : input.nodes.map((item) => item.node).join(", "),
+ display_name: input.nodes.map((item) => item.displayName).join(", "),
+ }));
+}
diff --git a/src/frontend/src/modals/genericModal/index.tsx b/src/frontend/src/modals/genericModal/index.tsx
index 02000df4d..0e111c548 100644
--- a/src/frontend/src/modals/genericModal/index.tsx
+++ b/src/frontend/src/modals/genericModal/index.tsx
@@ -24,8 +24,9 @@ import { postValidatePrompt } from "../../controllers/API";
import useAlertStore from "../../stores/alertStore";
import { genericModalPropsType } from "../../types/components";
import { handleKeyDown } from "../../utils/reactflowUtils";
-import { classNames, varHighlightHTML } from "../../utils/utils";
+import { classNames } from "../../utils/utils";
import BaseModal from "../baseModal";
+import varHighlightHTML from "./utils/var-highlight-html";
export default function GenericModal({
field_name = "",
@@ -82,7 +83,7 @@ export default function GenericModal({
}
const filteredWordsHighlight = matches.filter(
- (word) => !invalid_chars.includes(word)
+ (word) => !invalid_chars.includes(word),
);
setWordsHighlight(filteredWordsHighlight);
@@ -133,7 +134,7 @@ export default function GenericModal({
// to the first key of the custom_fields object
if (field_name === "") {
field_name = Array.isArray(
- apiReturn.data?.frontend_node?.custom_fields?.[""]
+ apiReturn.data?.frontend_node?.custom_fields?.[""],
)
? apiReturn.data?.frontend_node?.custom_fields?.[""][0] ?? ""
: apiReturn.data?.frontend_node?.custom_fields?.[""] ?? "";
@@ -209,7 +210,7 @@ export default function GenericModal({
{type === TypeModal.PROMPT && isEdit && !readonly ? (
diff --git a/src/frontend/src/modals/genericModal/utils/var-highlight-html.tsx b/src/frontend/src/modals/genericModal/utils/var-highlight-html.tsx
new file mode 100644
index 000000000..d88be4965
--- /dev/null
+++ b/src/frontend/src/modals/genericModal/utils/var-highlight-html.tsx
@@ -0,0 +1,6 @@
+import { IVarHighlightType } from "../../../types/components";
+
+export default function varHighlightHTML({ name }: IVarHighlightType): string {
+ const html = `{${name}}`;
+ return html;
+}
diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx
index bc0a0e362..3a456f540 100644
--- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx
+++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx
@@ -34,9 +34,10 @@ import {
updateIds,
validateSelection,
} from "../../../../utils/reactflowUtils";
-import { getRandomName, isWrappedWithClass } from "../../../../utils/utils";
+import { getRandomName } from "../../../../utils/utils";
import ConnectionLineComponent from "../ConnectionLineComponent";
import SelectionMenu from "../SelectionMenuComponent";
+import isWrappedWithClass from "./utils/is-wrapped-with-class";
const nodeTypes = {
genericNode: GenericNode,
diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/utils/is-wrapped-with-class.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/utils/is-wrapped-with-class.tsx
new file mode 100644
index 000000000..eff34d330
--- /dev/null
+++ b/src/frontend/src/pages/FlowPage/components/PageComponent/utils/is-wrapped-with-class.tsx
@@ -0,0 +1,4 @@
+const isWrappedWithClass = (event: any, className: string | undefined) =>
+ event.target.closest(`.${className}`);
+
+export default isWrappedWithClass;
diff --git a/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx
index 0ecdd588b..148f4359f 100644
--- a/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx
+++ b/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx
@@ -11,7 +11,7 @@ import { Badge } from "../../../../components/ui/badge";
import { Card, CardContent } from "../../../../components/ui/card";
import { deleteGlobalVariable } from "../../../../controllers/API";
import useAlertStore from "../../../../stores/alertStore";
-import { useGlobalVariablesStore } from "../../../../stores/globalVariables";
+import { useGlobalVariablesStore } from "../../../../stores/globalVariablesStore/globalVariables";
import { cn } from "../../../../utils/utils";
export default function GlobalVariablesPage() {
diff --git a/src/frontend/src/stores/globalVariables.ts b/src/frontend/src/stores/globalVariablesStore/globalVariables.ts
similarity index 91%
rename from src/frontend/src/stores/globalVariables.ts
rename to src/frontend/src/stores/globalVariablesStore/globalVariables.ts
index 3adf8cbf8..873e6e899 100644
--- a/src/frontend/src/stores/globalVariables.ts
+++ b/src/frontend/src/stores/globalVariablesStore/globalVariables.ts
@@ -1,6 +1,6 @@
import { create } from "zustand";
-import { GlobalVariablesStore } from "../types/zustand/globalVariables";
-import { getUnavailableFields } from "../utils/utils";
+import { GlobalVariablesStore } from "../../types/zustand/globalVariables";
+import getUnavailableFields from "./utils/get-unavailable-fields";
export const useGlobalVariablesStore = create(
(set, get) => ({
@@ -45,5 +45,5 @@ export const useGlobalVariablesStore = create(
getVariableId: (name) => {
return get().globalVariables[name]?.id;
},
- })
+ }),
);
diff --git a/src/frontend/src/stores/globalVariablesStore/utils/get-unavailable-fields.tsx b/src/frontend/src/stores/globalVariablesStore/utils/get-unavailable-fields.tsx
new file mode 100644
index 000000000..63da1dbe2
--- /dev/null
+++ b/src/frontend/src/stores/globalVariablesStore/utils/get-unavailable-fields.tsx
@@ -0,0 +1,13 @@
+export default function getUnavailableFields(variables: {
+ [key: string]: { default_fields?: string[] };
+}): { [name: string]: string } {
+ const unVariables: { [name: string]: string } = {};
+ Object.keys(variables).forEach((key) => {
+ if (variables[key].default_fields) {
+ variables[key].default_fields!.forEach((field) => {
+ unVariables[field] = key;
+ });
+ }
+ });
+ return unVariables;
+}
diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts
index 65a85960b..64008aa68 100644
--- a/src/frontend/src/utils/reactflowUtils.ts
+++ b/src/frontend/src/utils/reactflowUtils.ts
@@ -36,12 +36,8 @@ import {
unselectAllNodesType,
updateEdgesHandleIdsType,
} from "../types/utils/reactflowUtils";
-import {
- createRandomKey,
- getFieldTitle,
- getRandomDescription,
- toTitleCase,
-} from "./utils";
+import { createRandomKey, getFieldTitle, toTitleCase } from "./utils";
+import { DESCRIPTIONS } from "../flow_constants";
const uid = new ShortUniqueId({ length: 5 });
export function checkChatInput(nodes: Node[]) {
@@ -1286,6 +1282,14 @@ export function downloadFlows() {
});
}
+export function getRandomElement(array: T[]): T {
+ return array[Math.floor(Math.random() * array.length)];
+}
+
+export function getRandomDescription(): string {
+ return getRandomElement(DESCRIPTIONS);
+}
+
export const createNewFlow = (
flowData: ReactFlowJsonObject,
flow: FlowType,
diff --git a/src/frontend/src/utils/utils.ts b/src/frontend/src/utils/utils.ts
index 5e1786404..23bd275ea 100644
--- a/src/frontend/src/utils/utils.ts
+++ b/src/frontend/src/utils/utils.ts
@@ -15,6 +15,7 @@ import {
} from "../types/components";
import { NodeType } from "../types/flow";
import { FlowState } from "../types/tabs";
+import { getRandomElement } from "./reactflowUtils";
export function classNames(...classes: Array): string {
return classes.filter(Boolean).join(" ");
@@ -90,20 +91,6 @@ export function toTitleCase(
.join(" ");
}
-export function getUnavailableFields(variables: {
- [key: string]: { default_fields?: string[] };
-}): { [name: string]: string } {
- const unVariables: { [name: string]: string } = {};
- Object.keys(variables).forEach((key) => {
- if (variables[key].default_fields) {
- variables[key].default_fields!.forEach((field) => {
- unVariables[field] = key;
- });
- }
- });
- return unVariables;
-}
-
export const upperCaseWords: string[] = ["llm", "uri"];
export function checkUpperWords(str: string): string {
const words = str.split(" ").map((word) => {
@@ -115,133 +102,10 @@ export function checkUpperWords(str: string): string {
return words.join(" ");
}
-export const isWrappedWithClass = (event: any, className: string | undefined) =>
- event.target.closest(`.${className}`);
-
-export function groupByFamily(
- data: APIDataType,
- baseClasses: string,
- left: boolean,
- flow?: NodeType[],
-): groupedObjType[] {
- const baseClassesSet = new Set(baseClasses.split("\n"));
- let arrOfPossibleInputs: Array<{
- category: string;
- nodes: nodeGroupedObjType[];
- full: boolean;
- display_name?: string;
- }> = [];
- let arrOfPossibleOutputs: Array<{
- category: string;
- nodes: nodeGroupedObjType[];
- full: boolean;
- display_name?: string;
- }> = [];
- let checkedNodes = new Map();
- const excludeTypes = new Set(["bool", "float", "code", "file", "int"]);
-
- const checkBaseClass = (template: TemplateVariableType) => {
- return (
- template.type &&
- template.show &&
- ((!excludeTypes.has(template.type) &&
- baseClassesSet.has(template.type)) ||
- (template.input_types &&
- template.input_types.some((inputType) =>
- baseClassesSet.has(inputType),
- )))
- );
- };
-
- if (flow) {
- // se existir o flow
- for (const node of flow) {
- // para cada node do flow
- if (node!.data!.node!.flow || !node!.data!.node!.template) break; // não faz nada se o node for um group
- const nodeData = node.data;
-
- const foundNode = checkedNodes.get(nodeData.type); // verifica se o tipo do node já foi checado
- checkedNodes.set(nodeData.type, {
- hasBaseClassInTemplate:
- foundNode?.hasBaseClassInTemplate ||
- Object.values(nodeData.node!.template).some(checkBaseClass),
- hasBaseClassInBaseClasses:
- foundNode?.hasBaseClassInBaseClasses ||
- nodeData.node!.base_classes.some((baseClass) =>
- baseClassesSet.has(baseClass),
- ), //seta como anterior ou verifica se o node tem base class
- displayName: nodeData.node?.display_name,
- });
- }
- }
-
- for (const [d, nodes] of Object.entries(data)) {
- let tempInputs: nodeGroupedObjType[] = [],
- tempOutputs: nodeGroupedObjType[] = [];
-
- for (const [n, node] of Object.entries(nodes!)) {
- let foundNode = checkedNodes.get(n);
-
- if (!foundNode) {
- foundNode = {
- hasBaseClassInTemplate: Object.values(node!.template).some(
- checkBaseClass,
- ),
- hasBaseClassInBaseClasses: node!.base_classes.some((baseClass) =>
- baseClassesSet.has(baseClass),
- ),
- displayName: node?.display_name,
- };
- }
-
- if (foundNode.hasBaseClassInTemplate)
- tempInputs.push({ node: n, displayName: foundNode.displayName });
- if (foundNode.hasBaseClassInBaseClasses)
- tempOutputs.push({ node: n, displayName: foundNode.displayName });
- }
-
- const totalNodes = Object.keys(nodes!).length;
-
- if (tempInputs.length)
- arrOfPossibleInputs.push({
- category: d,
- nodes: tempInputs,
- full: tempInputs.length === totalNodes,
- });
- if (tempOutputs.length)
- arrOfPossibleOutputs.push({
- category: d,
- nodes: tempOutputs,
- full: tempOutputs.length === totalNodes,
- });
- }
-
- return left
- ? arrOfPossibleOutputs.map((output) => ({
- family: output.category,
- type: output.full
- ? ""
- : output.nodes.map((item) => item.node).join(", "),
- display_name: "",
- }))
- : arrOfPossibleInputs.map((input) => ({
- family: input.category,
- type: input.full ? "" : input.nodes.map((item) => item.node).join(", "),
- display_name: input.nodes.map((item) => item.displayName).join(", "),
- }));
-}
-
export function buildInputs(): string {
return '{"input_value": "message"}';
}
-export function getRandomElement(array: T[]): T {
- return array[Math.floor(Math.random() * array.length)];
-}
-export function getRandomDescription(): string {
- return getRandomElement(DESCRIPTIONS);
-}
-
export function getRandomName(
retry: number = 0,
noSpace: boolean = false,