Refactor utils file

This commit is contained in:
igorrCarvalho 2024-05-15 21:51:32 -03:00
commit 5e8cec40c9
14 changed files with 175 additions and 162 deletions

View file

@ -19,15 +19,15 @@ import Router from "./routes";
import useAlertStore from "./stores/alertStore"; import useAlertStore from "./stores/alertStore";
import { useDarkStore } from "./stores/darkStore"; import { useDarkStore } from "./stores/darkStore";
import useFlowsManagerStore from "./stores/flowsManagerStore"; import useFlowsManagerStore from "./stores/flowsManagerStore";
import { useGlobalVariablesStore } from "./stores/globalVariables"; import { useGlobalVariablesStore } from "./stores/globalVariablesStore/globalVariables";
import { useStoreStore } from "./stores/storeStore"; import { useStoreStore } from "./stores/storeStore";
import { useTypesStore } from "./stores/typesStore"; import { useTypesStore } from "./stores/typesStore";
export default function App() { export default function App() {
const removeFromTempNotificationList = useAlertStore( const removeFromTempNotificationList = useAlertStore(
(state) => state.removeFromTempNotificationList (state) => state.removeFromTempNotificationList,
); );
const tempNotificationList = useAlertStore( const tempNotificationList = useAlertStore(
(state) => state.tempNotificationList (state) => state.tempNotificationList,
); );
const [fetchError, setFetchError] = useState(false); const [fetchError, setFetchError] = useState(false);
const isLoading = useFlowsManagerStore((state) => state.isLoading); const isLoading = useFlowsManagerStore((state) => state.isLoading);
@ -45,10 +45,10 @@ export default function App() {
const refreshVersion = useDarkStore((state) => state.refreshVersion); const refreshVersion = useDarkStore((state) => state.refreshVersion);
const refreshStars = useDarkStore((state) => state.refreshStars); const refreshStars = useDarkStore((state) => state.refreshStars);
const setGlobalVariables = useGlobalVariablesStore( const setGlobalVariables = useGlobalVariablesStore(
(state) => state.setGlobalVariables (state) => state.setGlobalVariables,
); );
const setUnavailableFields = useGlobalVariablesStore( const setUnavailableFields = useGlobalVariablesStore(
(state) => state.setUnavaliableFields (state) => state.setUnavaliableFields,
); );
const checkHasStore = useStoreStore((state) => state.checkHasStore); const checkHasStore = useStoreStore((state) => state.checkHasStore);
const navigate = useNavigate(); const navigate = useNavigate();

View file

@ -2,7 +2,7 @@ import { useState } from "react";
import { registerGlobalVariable } from "../../controllers/API"; import { registerGlobalVariable } from "../../controllers/API";
import BaseModal from "../../modals/baseModal"; import BaseModal from "../../modals/baseModal";
import useAlertStore from "../../stores/alertStore"; import useAlertStore from "../../stores/alertStore";
import { useGlobalVariablesStore } from "../../stores/globalVariables"; import { useGlobalVariablesStore } from "../../stores/globalVariablesStore/globalVariables";
import { useTypesStore } from "../../stores/typesStore"; import { useTypesStore } from "../../stores/typesStore";
import { ResponseErrorDetailAPI } from "../../types/api"; import { ResponseErrorDetailAPI } from "../../types/api";
import { sortByName } from "../../utils/utils"; import { sortByName } from "../../utils/utils";

View file

@ -2,7 +2,7 @@ import { useEffect } from "react";
import { deleteGlobalVariable } from "../../controllers/API"; import { deleteGlobalVariable } from "../../controllers/API";
import DeleteConfirmationModal from "../../modals/deleteConfirmationModal"; import DeleteConfirmationModal from "../../modals/deleteConfirmationModal";
import useAlertStore from "../../stores/alertStore"; import useAlertStore from "../../stores/alertStore";
import { useGlobalVariablesStore } from "../../stores/globalVariables"; import { useGlobalVariablesStore } from "../../stores/globalVariablesStore/globalVariables";
import { InputGlobalComponentType } from "../../types/components"; import { InputGlobalComponentType } from "../../types/components";
import { cn } from "../../utils/utils"; import { cn } from "../../utils/utils";
import AddNewVariableButton from "../addNewVariableButtonComponent/addNewVariableButton"; import AddNewVariableButton from "../addNewVariableButtonComponent/addNewVariableButton";

View file

@ -49,7 +49,8 @@ import {
nodeIconsLucide, nodeIconsLucide,
nodeNames, nodeNames,
} from "../../../../utils/styleUtils"; } 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({ export default function ParameterComponent({
left, left,

View file

@ -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(", "),
}));
}

View file

@ -24,8 +24,9 @@ import { postValidatePrompt } from "../../controllers/API";
import useAlertStore from "../../stores/alertStore"; import useAlertStore from "../../stores/alertStore";
import { genericModalPropsType } from "../../types/components"; import { genericModalPropsType } from "../../types/components";
import { handleKeyDown } from "../../utils/reactflowUtils"; import { handleKeyDown } from "../../utils/reactflowUtils";
import { classNames, varHighlightHTML } from "../../utils/utils"; import { classNames } from "../../utils/utils";
import BaseModal from "../baseModal"; import BaseModal from "../baseModal";
import varHighlightHTML from "./utils/var-highlight-html";
export default function GenericModal({ export default function GenericModal({
field_name = "", field_name = "",
@ -82,7 +83,7 @@ export default function GenericModal({
} }
const filteredWordsHighlight = matches.filter( const filteredWordsHighlight = matches.filter(
(word) => !invalid_chars.includes(word) (word) => !invalid_chars.includes(word),
); );
setWordsHighlight(filteredWordsHighlight); setWordsHighlight(filteredWordsHighlight);
@ -133,7 +134,7 @@ export default function GenericModal({
// to the first key of the custom_fields object // to the first key of the custom_fields object
if (field_name === "") { if (field_name === "") {
field_name = Array.isArray( 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?.[""][0] ?? ""
: apiReturn.data?.frontend_node?.custom_fields?.[""] ?? ""; : apiReturn.data?.frontend_node?.custom_fields?.[""] ?? "";
@ -209,7 +210,7 @@ export default function GenericModal({
<div <div
className={classNames( className={classNames(
!isEdit ? "rounded-lg border" : "", !isEdit ? "rounded-lg border" : "",
"flex h-full w-full" "flex h-full w-full",
)} )}
> >
{type === TypeModal.PROMPT && isEdit && !readonly ? ( {type === TypeModal.PROMPT && isEdit && !readonly ? (

View file

@ -0,0 +1,6 @@
import { IVarHighlightType } from "../../../types/components";
export default function varHighlightHTML({ name }: IVarHighlightType): string {
const html = `<span class="font-semibold chat-message-highlight">{${name}}</span>`;
return html;
}

View file

@ -34,9 +34,10 @@ import {
updateIds, updateIds,
validateSelection, validateSelection,
} from "../../../../utils/reactflowUtils"; } from "../../../../utils/reactflowUtils";
import { getRandomName, isWrappedWithClass } from "../../../../utils/utils"; import { getRandomName } from "../../../../utils/utils";
import ConnectionLineComponent from "../ConnectionLineComponent"; import ConnectionLineComponent from "../ConnectionLineComponent";
import SelectionMenu from "../SelectionMenuComponent"; import SelectionMenu from "../SelectionMenuComponent";
import isWrappedWithClass from "./utils/is-wrapped-with-class";
const nodeTypes = { const nodeTypes = {
genericNode: GenericNode, genericNode: GenericNode,

View file

@ -0,0 +1,4 @@
const isWrappedWithClass = (event: any, className: string | undefined) =>
event.target.closest(`.${className}`);
export default isWrappedWithClass;

View file

@ -11,7 +11,7 @@ import { Badge } from "../../../../components/ui/badge";
import { Card, CardContent } from "../../../../components/ui/card"; import { Card, CardContent } from "../../../../components/ui/card";
import { deleteGlobalVariable } from "../../../../controllers/API"; import { deleteGlobalVariable } from "../../../../controllers/API";
import useAlertStore from "../../../../stores/alertStore"; import useAlertStore from "../../../../stores/alertStore";
import { useGlobalVariablesStore } from "../../../../stores/globalVariables"; import { useGlobalVariablesStore } from "../../../../stores/globalVariablesStore/globalVariables";
import { cn } from "../../../../utils/utils"; import { cn } from "../../../../utils/utils";
export default function GlobalVariablesPage() { export default function GlobalVariablesPage() {

View file

@ -1,6 +1,6 @@
import { create } from "zustand"; import { create } from "zustand";
import { GlobalVariablesStore } from "../types/zustand/globalVariables"; import { GlobalVariablesStore } from "../../types/zustand/globalVariables";
import { getUnavailableFields } from "../utils/utils"; import getUnavailableFields from "./utils/get-unavailable-fields";
export const useGlobalVariablesStore = create<GlobalVariablesStore>( export const useGlobalVariablesStore = create<GlobalVariablesStore>(
(set, get) => ({ (set, get) => ({
@ -45,5 +45,5 @@ export const useGlobalVariablesStore = create<GlobalVariablesStore>(
getVariableId: (name) => { getVariableId: (name) => {
return get().globalVariables[name]?.id; return get().globalVariables[name]?.id;
}, },
}) }),
); );

View file

@ -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;
}

View file

@ -36,12 +36,8 @@ import {
unselectAllNodesType, unselectAllNodesType,
updateEdgesHandleIdsType, updateEdgesHandleIdsType,
} from "../types/utils/reactflowUtils"; } from "../types/utils/reactflowUtils";
import { import { createRandomKey, getFieldTitle, toTitleCase } from "./utils";
createRandomKey, import { DESCRIPTIONS } from "../flow_constants";
getFieldTitle,
getRandomDescription,
toTitleCase,
} from "./utils";
const uid = new ShortUniqueId({ length: 5 }); const uid = new ShortUniqueId({ length: 5 });
export function checkChatInput(nodes: Node[]) { export function checkChatInput(nodes: Node[]) {
@ -1286,6 +1282,14 @@ export function downloadFlows() {
}); });
} }
export function getRandomElement<T>(array: T[]): T {
return array[Math.floor(Math.random() * array.length)];
}
export function getRandomDescription(): string {
return getRandomElement(DESCRIPTIONS);
}
export const createNewFlow = ( export const createNewFlow = (
flowData: ReactFlowJsonObject, flowData: ReactFlowJsonObject,
flow: FlowType, flow: FlowType,

View file

@ -15,6 +15,7 @@ import {
} from "../types/components"; } from "../types/components";
import { NodeType } from "../types/flow"; import { NodeType } from "../types/flow";
import { FlowState } from "../types/tabs"; import { FlowState } from "../types/tabs";
import { getRandomElement } from "./reactflowUtils";
export function classNames(...classes: Array<string>): string { export function classNames(...classes: Array<string>): string {
return classes.filter(Boolean).join(" "); return classes.filter(Boolean).join(" ");
@ -90,20 +91,6 @@ export function toTitleCase(
.join(" "); .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 const upperCaseWords: string[] = ["llm", "uri"];
export function checkUpperWords(str: string): string { export function checkUpperWords(str: string): string {
const words = str.split(" ").map((word) => { const words = str.split(" ").map((word) => {
@ -115,133 +102,10 @@ export function checkUpperWords(str: string): string {
return words.join(" "); 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 { export function buildInputs(): string {
return '{"input_value": "message"}'; return '{"input_value": "message"}';
} }
export function getRandomElement<T>(array: T[]): T {
return array[Math.floor(Math.random() * array.length)];
}
export function getRandomDescription(): string {
return getRandomElement(DESCRIPTIONS);
}
export function getRandomName( export function getRandomName(
retry: number = 0, retry: number = 0,
noSpace: boolean = false, noSpace: boolean = false,