From 35bdfafa4ff48ea65a4c93f5ec44e73ed83641cf Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Wed, 17 Jan 2024 19:59:22 -0300 Subject: [PATCH 0001/1878] Refactor: Change context to zustand store --- src/frontend/src/constants/constants.ts | 3 + src/frontend/src/stores/flowsIOStore.ts | 255 ++++++++++++++++++ .../src/types/zustand/flowIOStore/index.ts | 61 +++++ src/frontend/src/utils/reactflowUtils.ts | 10 + 4 files changed, 329 insertions(+) create mode 100644 src/frontend/src/stores/flowsIOStore.ts create mode 100644 src/frontend/src/types/zustand/flowIOStore/index.ts diff --git a/src/frontend/src/constants/constants.ts b/src/frontend/src/constants/constants.ts index f1026fec2..95c8625b8 100644 --- a/src/frontend/src/constants/constants.ts +++ b/src/frontend/src/constants/constants.ts @@ -677,3 +677,6 @@ export const LANGFLOW_SUPPORTED_TYPES = new Set([ ]); export const priorityFields = new Set(["code", "template"]); + +export const INPUT_TYPES = new Set(["ChatInput","TextInput"]); +export const OUTPUT_TYPES = new Set(["ChatOutput"]); diff --git a/src/frontend/src/stores/flowsIOStore.ts b/src/frontend/src/stores/flowsIOStore.ts new file mode 100644 index 000000000..cc6efb5f2 --- /dev/null +++ b/src/frontend/src/stores/flowsIOStore.ts @@ -0,0 +1,255 @@ +import { cloneDeep } from "lodash"; +import { create } from "zustand"; +import { FlowType, NodeDataType, NodeType } from "../types/flow"; +import useFlowStore from "./flowStore"; +import { isInputNode, isOutputNode } from "../utils/reactflowUtils"; +import useFlowsManagerStore from "./flowsManagerStore"; +import useAlertStore from "./alertStore"; +import { flowIOStoreType } from "../types/zustand/flowIOStore"; +/* const { getNodeId, saveFlow } = useContext(FlowsContext); +const { setErrorData, setNoticeData } = useContext(alertContext); */ + +const { reactFlowInstance, paste } = useFlowStore(); +const { saveFlow } = useFlowsManagerStore(); +const { setErrorData, setNoticeData } = useAlertStore(); + +const useFlowIOStore = create((set, get) => ({ + flowPool: {}, + getFilterEdge: [], + isBuilt: false, + outputTypes: [], + inputTypes: [], + inputIds: [], + outputIds: [], + isBuilding: true, + + setFilterEdge: (filterEdge) => { set({getFilterEdge: filterEdge}) }, + setFlowPool: (flowPool) => { set({flowPool}) }, + setIsBuilt: (isBuilt) => { set({isBuilt}) }, + setOutputTypes: (outputTypes) => { set({outputTypes}) }, + setInputTypes: (inputTypes) => { set({inputTypes}) }, + setInputIds: (inputIds) => { set({ inputIds }) }, + setOutputIds: (outputIds) => { set({outputIds}) }, + setIsBuilding: (isBuilding) => { set({isBuilding}) }, + + updateFlowPoolNodes: (nodes: NodeType[]) => { + //this function will update the removing the old ones + const nodeIdsSet = new Set(nodes.map((node) => node.id)); + set((state) => { + let newFlowPool = cloneDeep({ ...state.flowPool }); + Object.keys(newFlowPool).forEach((nodeId) => { + if (!nodeIdsSet.has(nodeId)) { + delete newFlowPool[nodeId]; + } + }); + return { flowPool: newFlowPool }; + }); + }, + addDataToFlowPool: (data: any, nodeId: string) => { + set((state) => { + let newFlowPool = cloneDeep({ ...state.flowPool }); + if (!newFlowPool[nodeId]) newFlowPool[nodeId] = [data]; + else { + newFlowPool[nodeId].push(data); + } + return { flowPool: newFlowPool }; + }); + }, + CleanFlowPool: () => { + set({ flowPool: {} }); + }, + updateNodeFlowData: (nodeId: string, newData: NodeDataType) => { + let oldNodes = reactFlowInstance?.getNodes(); + let targetNode = oldNodes?.find((node) => node.id === nodeId); + if (targetNode) { + targetNode.data = cloneDeep(newData); + reactFlowInstance?.setNodes([...oldNodes!]); + console.log( + "after reactflow update", + JSON.parse(JSON.stringify(reactFlowInstance?.toObject())) + ); + } + }, + checkInputandOutput: (flow?: FlowType) => { + let has_input = false; + let has_output = false; + if (!flow && !reactFlowInstance) { + return false; + } + const nodes = flow?.data?.nodes + ? flow.data.nodes + : reactFlowInstance!.getNodes(); + nodes.forEach((node) => { + const nodeData: NodeDataType = node.data as NodeDataType; + if (isInputNode(nodeData)) { + has_input = true; + } + if (isOutputNode(nodeData)) { + has_output = true; + } + }); + return has_input && has_output; + }, + getInputTypes: (flow?: FlowType) => { + let inputType: string[] = []; + if (!flow && !reactFlowInstance) { + return []; + } + const nodes = flow?.data?.nodes + ? flow.data.nodes + : reactFlowInstance!.getNodes(); + nodes.forEach((node) => { + const nodeData: NodeDataType = node.data as NodeDataType; + if (isInputNode(nodeData)) { + // TODO remove count and ramdom key from type before pushing + inputType.push(nodeData.type); + } + }); + set({ inputTypes: inputType }); + return inputType; + }, + getOutputTypes: (flow?: FlowType) => { + let outputType: string[] = []; + if (!flow && !reactFlowInstance) { + return []; + } + const nodes = flow?.data?.nodes + ? flow.data.nodes + : reactFlowInstance!.getNodes(); + nodes.forEach((node) => { + const nodeData: NodeDataType = node.data as NodeDataType; + if (isOutputNode(nodeData)) { + // TODO remove count and ramdom key from type before pushing + outputType.push(nodeData.type); + } + }); + set({ outputTypes: outputType }); + return outputType; + }, + getInputIds: (flow?: FlowType) => { + let inputIds: string[] = []; + if (!flow && !reactFlowInstance) { + return []; + } + const nodes = flow?.data?.nodes + ? flow.data.nodes + : reactFlowInstance!.getNodes(); + nodes.forEach((node) => { + const nodeData: NodeDataType = node.data as NodeDataType; + if (isInputNode(nodeData)) { + inputIds.push(nodeData.id); + } + }); + set({ inputIds }); + return inputIds; + }, + getOutputIds: (flow?: FlowType) => { + let outputIds: string[] = []; + if (!flow && !reactFlowInstance) { + return []; + } + const nodes = flow?.data?.nodes + ? flow.data.nodes + : reactFlowInstance!.getNodes(); + + nodes.forEach((node) => { + const nodeData: NodeDataType = node.data as NodeDataType; + if (isOutputNode(nodeData)) { + outputIds.push(nodeData.id); + } + }); + set({ outputIds }); + return outputIds; + }, + pasteFileOnFLow: async (file?: File) => { + if (file) { + const text = await file.text(); + let fileData = JSON.parse(text); + if (fileData.flows) { + fileData.flows.forEach((flow: FlowType) => { + paste( + { nodes: flow!.data!.nodes, edges: flow!.data!.edges }, + { x: 10, y: 10 } + ); + }); + } else { + let flow: FlowType = JSON.parse(text); + paste( + { nodes: flow.data!.nodes, edges: flow.data!.edges }, + { x: 10, y: 10 } + ); + } + } else { + const input = document.createElement("input"); + input.type = "file"; + input.accept = ".json"; + // add a change event listener to the file input + input.onchange = async (e: Event) => { + if ( + (e.target as HTMLInputElement).files![0].type === "application/json" + ) { + const currentfile = (e.target as HTMLInputElement).files![0]; + get().pasteFileOnFLow(currentfile); + } + }; + // trigger the file input click event to open the file dialog + input.click(); + } + }, + downloadFlow: ( + flow: FlowType, + flowName: string, + flowDescription?: string + ) => { + // create a data URI with the current flow data + const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent( + JSON.stringify({ ...flow, name: flowName, description: flowDescription }) + )}`; + + // create a link element and set its properties + const link = document.createElement("a"); + link.href = jsonString; + link.download = `${flowName && flowName != "" ? flowName : "flow"}.json`; + + // simulate a click on the link element to trigger the download + link.click(); + }, + /* buildFlow: async (nodeId?: string) => { + function handleBuildUpdate(data: any) { + get().addDataToFlowPool(data.data[data.id], data.id); + } + console.log( + "building flow before save", + JSON.parse(JSON.stringify(actualFlow)) + ); + console.log(saveFlow); + await saveFlow( + { ...actualFlow!, data: reactFlowInstance!.toObject()! }, + true + ); + console.log( + "building flow AFTER save", + JSON.parse(JSON.stringify(actualFlow)) + ); + return buildVertices({ + flow: { + data: reactFlowInstance?.toObject()!, + description: actualFlow!.description, + id: actualFlow!.id, + name: actualFlow!.name, + }, + nodeId, + onBuildComplete: () => { + if (nodeId) { + setNoticeData({ title: `${nodeId} built successfully` }); + } + }, + onBuildUpdate: handleBuildUpdate, + onBuildError: (title, list) => { + setErrorData({ list, title }); + }, + }); + }, */ +})); + +export default useFlowIOStore; diff --git a/src/frontend/src/types/zustand/flowIOStore/index.ts b/src/frontend/src/types/zustand/flowIOStore/index.ts new file mode 100644 index 000000000..00fbcd6ed --- /dev/null +++ b/src/frontend/src/types/zustand/flowIOStore/index.ts @@ -0,0 +1,61 @@ +import { ReactFlowInstance } from "reactflow"; +import { tweakType } from "../../components"; +import { FlowType, NodeDataType, NodeType } from "../../flow"; + +export type chatInputType = { + result: string; +}; + +export type ChatOutputType = { + message: string; + sender: string; + sender_name: string; +}; + +export type FlowPoolObjectType = { + timestamp: string; + valid: boolean; + params: any; + data: { artifacts: any; results: any | ChatOutputType | chatInputType }; + id: string; +}; + +export type FlowPoolType = { + [key: string]: Array; +}; + +export type flowIOStoreType = { + flowPool: FlowPoolType; + getFilterEdge: any[]; + isBuilt: boolean; + inputTypes: string[]; + outputTypes: string[]; + inputIds: string[]; + outputIds: string[]; + isBuilding: boolean; + setFlowPool: (flowPool: FlowPoolType) => void; + setIsBuilding: (state: boolean) => void; + setIsBuilt: (state: boolean) => void; + setOutputTypes: (outputTypes: string[]) => void; + setInputTypes: (inputTypes: string[]) => void; + setInputIds: (inputIds: string[]) => void; + setOutputIds: (outputIds: string[]) => void; + setFilterEdge: (newState) => void; + updateFlowPoolNodes: (nodes: NodeType[]) => void; + addDataToFlowPool: (data: any, nodeId: string) => void; + CleanFlowPool: () => void; + updateNodeFlowData: (nodeId: string, newData: NodeDataType) => void; + checkInputandOutput: (flow?: FlowType) => boolean; + getInputTypes: (flow?: FlowType) => string[]; + getOutputTypes: (flow?: FlowType) => string[]; + getInputIds: (flow?: FlowType) => string[]; + getOutputIds: (flow?: FlowType) => string[]; + pasteFileOnFLow: (file?: File) => Promise; + downloadFlow: ( + flow: FlowType, + flowName: string, + flowDescription?: string + ) => void; + + /* buildFlow: (nodeId?:string) => Promise; */ +}; \ No newline at end of file diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts index 8d222349a..350e24987 100644 --- a/src/frontend/src/utils/reactflowUtils.ts +++ b/src/frontend/src/utils/reactflowUtils.ts @@ -9,7 +9,9 @@ import { } from "reactflow"; import ShortUniqueId from "short-unique-id"; import { + INPUT_TYPES, LANGFLOW_SUPPORTED_TYPES, + OUTPUT_TYPES, specialCharsRegex, } from "../constants/constants"; import { downloadFlowsFromDatabase } from "../controllers/API"; @@ -1286,3 +1288,11 @@ export const createNewFlow = ( is_component: flow?.is_component ?? false, }; }; + +export function isInputNode(nodeData: NodeDataType): boolean { + return INPUT_TYPES.has(nodeData.type); +} + +export function isOutputNode(nodeData: NodeDataType): boolean { + return OUTPUT_TYPES.has(nodeData.type); +} From 30940cb85304d1a0dbe72a44dec9a60a40af0a10 Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Thu, 18 Jan 2024 14:57:17 -0300 Subject: [PATCH 0002/1878] Refactor: Make IOView component use zustand store --- src/frontend/src/components/IOview/index.tsx | 93 +++++++ .../newChatView/chatInput/index.tsx | 127 ++++++++++ .../chatMessage/codeBlock/index.tsx | 79 ++++++ .../newChatView/chatMessage/index.tsx | 234 ++++++++++++++++++ .../newChatView/fileComponent/index.tsx | 87 +++++++ .../src/components/newChatView/index.tsx | 193 +++++++++++++++ .../components/textInputComponent/index.tsx | 15 ++ .../components/textOutputComponent/index.tsx | 15 ++ src/frontend/src/controllers/API/index.ts | 19 ++ src/frontend/src/stores/flowsIOStore.ts | 18 +- src/frontend/src/types/api/index.ts | 12 + src/frontend/src/types/chat/index.ts | 21 +- src/frontend/src/types/components/index.ts | 2 +- src/frontend/src/types/flow/index.ts | 6 +- .../src/types/zustand/flowIOStore/index.ts | 4 +- src/frontend/src/utils/buildUtils.ts | 81 ++++++ src/frontend/src/utils/utils.ts | 5 + 17 files changed, 994 insertions(+), 17 deletions(-) create mode 100644 src/frontend/src/components/IOview/index.tsx create mode 100644 src/frontend/src/components/newChatView/chatInput/index.tsx create mode 100644 src/frontend/src/components/newChatView/chatMessage/codeBlock/index.tsx create mode 100644 src/frontend/src/components/newChatView/chatMessage/index.tsx create mode 100644 src/frontend/src/components/newChatView/fileComponent/index.tsx create mode 100644 src/frontend/src/components/newChatView/index.tsx create mode 100644 src/frontend/src/components/textInputComponent/index.tsx create mode 100644 src/frontend/src/components/textOutputComponent/index.tsx create mode 100644 src/frontend/src/utils/buildUtils.ts diff --git a/src/frontend/src/components/IOview/index.tsx b/src/frontend/src/components/IOview/index.tsx new file mode 100644 index 000000000..85587f8eb --- /dev/null +++ b/src/frontend/src/components/IOview/index.tsx @@ -0,0 +1,93 @@ +import { ReactNode, useContext, useState } from "react"; +import NewChatView from "../newChatView"; +import { extractTypeFromLongId, removeCountFromString } from "../../utils/utils"; +import AccordionComponent from "../AccordionComponent"; +import { Badge } from "../ui/badge"; +import ShadTooltip from "../ShadTooltipComponent"; +import IconComponent from "../genericIconComponent"; +import { Textarea } from "../ui/textarea"; +import { NodeDataType } from "../../types/flow"; +import useFlowStore from "../../stores/flowStore"; +import useFlowsManagerStore from "../../stores/flowsManagerStore"; +import useFlowIOStore from "../../stores/flowsIOStore"; + + +export default function IOView(): JSX.Element { + const {inputIds, outputIds, updateNodeFlowData } = + useFlowIOStore(); + const { reactFlowInstance } = useFlowStore(); + const options = inputIds.concat(outputIds); + const [selectedView, setSelectedView] = useState(handleSelectChange(options[0])); + // if (outputTypes.includes("ChatOutput")) { + // return ; + // } + function handleSelectChange(selected: string) { + const type = extractTypeFromLongId(selected); + return + switch (type) { + case "ChatOutput": + return ; + break; + } + } + + + return ( +
+
+
+ + + Inputs + +
+ { + inputIds.filter(input=>extractTypeFromLongId(input)!=="ChatInput").map((inputId,index) => { + const nodeData:NodeDataType = reactFlowInstance?.getNodes().find(node=>node.id===inputId)?.data; + return ( +
+ + + {inputId} + +
{ + event.stopPropagation(); + }} + > +
+
+ } + key={index} + keyValue={inputId} + > +
+ +
+ +
+ ) + }) + } +
+ {selectedView} + + ); +} diff --git a/src/frontend/src/components/newChatView/chatInput/index.tsx b/src/frontend/src/components/newChatView/chatInput/index.tsx new file mode 100644 index 000000000..7ae0a0915 --- /dev/null +++ b/src/frontend/src/components/newChatView/chatInput/index.tsx @@ -0,0 +1,127 @@ +import { useEffect, useState } from "react"; +import IconComponent from "../../../components/genericIconComponent"; +import { Textarea } from "../../../components/ui/textarea"; +import { chatInputType } from "../../../types/components"; +import { classNames } from "../../../utils/utils"; + +export default function ChatInput({ + lockChat, + chatValue, + sendMessage, + setChatValue, + inputRef, + noInput, +}: chatInputType): JSX.Element { + const [repeate, setRepeate] = useState(1); + useEffect(() => { + if (!lockChat && inputRef.current) { + inputRef.current.focus(); + } + }, [lockChat, inputRef]); + + + function handleChange(value:number){ + console.log(value) + if(value>0){ + setRepeate(value); + } + else{ + setRepeate(1); + } + } + + + useEffect(() => { + if (inputRef.current) { + inputRef.current.style.height = "inherit"; // Reset the height + inputRef.current.style.height = `${inputRef.current.scrollHeight}px`; // Set it to the scrollHeight + } + }, [chatValue]); + + + return ( +
+
+ repeate + { + handleChange(parseInt(e.target.value)); + }} className="bg-background" type="number" min={0}/> + + +
+ -
- - - ) - }) - } - - {selectedView} - - ); + return ( +
+
+
+ + Inputs +
+ {inputIds + .filter((input) => extractTypeFromLongId(input) !== "ChatInput") + .map((inputId, index) => { + const nodeData: NodeDataType = reactFlowInstance + ?.getNodes() + .find((node) => node.id === inputId)?.data; + return ( +
+ + + {inputId} + +
{ + event.stopPropagation(); + }} + >
+
+ } + key={index} + keyValue={inputId} + > +
+ +
+ +
+ ); + })} +
+ {selectedView} + + ); } diff --git a/src/frontend/src/components/newChatView/chatInput/index.tsx b/src/frontend/src/components/newChatView/chatInput/index.tsx index 7ae0a0915..2a4d39f4b 100644 --- a/src/frontend/src/components/newChatView/chatInput/index.tsx +++ b/src/frontend/src/components/newChatView/chatInput/index.tsx @@ -5,123 +5,121 @@ import { chatInputType } from "../../../types/components"; import { classNames } from "../../../utils/utils"; export default function ChatInput({ - lockChat, - chatValue, - sendMessage, - setChatValue, - inputRef, - noInput, + lockChat, + chatValue, + sendMessage, + setChatValue, + inputRef, + noInput, }: chatInputType): JSX.Element { - const [repeate, setRepeate] = useState(1); - useEffect(() => { - if (!lockChat && inputRef.current) { - inputRef.current.focus(); - } - }, [lockChat, inputRef]); + const [repeate, setRepeate] = useState(1); + useEffect(() => { + if (!lockChat && inputRef.current) { + inputRef.current.focus(); + } + }, [lockChat, inputRef]); + function handleChange(value: number) { + console.log(value); + if (value > 0) { + setRepeate(value); + } else { + setRepeate(1); + } + } - function handleChange(value:number){ - console.log(value) - if(value>0){ - setRepeate(value); - } - else{ - setRepeate(1); - } - } + useEffect(() => { + if (inputRef.current) { + inputRef.current.style.height = "inherit"; // Reset the height + inputRef.current.style.height = `${inputRef.current.scrollHeight}px`; // Set it to the scrollHeight + } + }, [chatValue]); + return ( +
+
+ repeate + { + handleChange(parseInt(e.target.value)); + }} + className="bg-background" + type="number" + min={0} + /> +
+ + }} + />
diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index f414db1eb..e761c76d2 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -856,7 +856,6 @@ export async function requestLogout() { export async function getVerticesOrder( flowId: string ): Promise> { - console.log; return await api.get(`${BASE_URL_API}build/${flowId}/vertices`); } diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index 7b1322f1b..e641ef1a3 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -1,4 +1,4 @@ -import { ReactElement, ReactNode } from "react"; +import { ChangeEvent, ReactElement, ReactNode } from "react"; import { ReactFlowJsonObject, XYPosition } from "reactflow"; import { APIClassType, APITemplateType, TemplateVariableType } from "../api"; import { ChatMessageType } from "../chat"; @@ -645,3 +645,11 @@ export type dropdownButtonPropsType = { onFirstBtnClick: () => void; options: Array<{ name: string; onBtnClick: () => void }>; }; + +export type IOInputProps = { + inputType: string; + value: string; + onChange: (e: ChangeEvent) => void; + styleClasses: string; + placeholder: string; +} From 4af5aa56c279fcd5fdd2380f2676ea07556d0795 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Fri, 26 Jan 2024 14:23:39 -0300 Subject: [PATCH 0100/1878] chore(IOInputField): rename onChange prop to updateValue for better semantics chore(IOInputField): remove styleClasses and placeholder props as they are not used chore(IOView): remove TODO comment for extending and improving view mode and adding other types of views chore(IOView): remove unused onChange prop from IOInputProps type --- .../src/components/IOInputField/index.tsx | 25 ++++++++--------- src/frontend/src/components/IOview/index.tsx | 28 ++++++++++--------- src/frontend/src/types/components/index.ts | 8 ++---- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/frontend/src/components/IOInputField/index.tsx b/src/frontend/src/components/IOInputField/index.tsx index 68d442648..feec2ce3b 100644 --- a/src/frontend/src/components/IOInputField/index.tsx +++ b/src/frontend/src/components/IOInputField/index.tsx @@ -1,23 +1,20 @@ -import { Textarea } from "../ui/textarea"; -import InputFileComponent from "../inputFileComponent"; import { IOInputProps } from "../../types/components"; +import { Textarea } from "../ui/textarea"; export default function IOInputField({ inputType, value, - onChange, - styleClasses, - placeholder, + updateValue, }: IOInputProps): JSX.Element | undefined { - switch (inputType) { + switch (inputType) { case "TextInput": - return ( - - - - - )) - : null} - {flowState?.memory_keys!.map((key, index) => ( -
- - - {key} - -
- {}} - size="small" - disabled={true} - /> -
-
- } - key={index} - keyValue={key} - > -
-
- Source: Memory -
-
- - - ))} - -
-
-
- -
-
- {chatHistory.length > 0 ? ( - chatHistory.map((chat, index) => ( - {}} - /> - )) - ) : ( -
- - 👋{" "} - - {LANGFLOW_CHAT_TITLE} - - -
-
- - {CHAT_FIRST_INITIAL_TEXT}{" "} - - - {" "} - {CHAT_SECOND_INITIAL_TEXT} - -
-
- )} -
-
-
-
- { - setChatValue(value); - if (flowState && chatKey) { - setFlowState((old: FlowState | undefined) => { - let newFlowState = cloneDeep(old!); - newFlowState.input_keys![chatKey] = value; - return newFlowState; - }); - } - }} - inputRef={ref} - /> -
-
-
-
- - - )} - - ); -} diff --git a/src/frontend/src/modals/shareModal/index.tsx b/src/frontend/src/modals/shareModal/index.tsx index d5ba63c8c..2dddbe232 100644 --- a/src/frontend/src/modals/shareModal/index.tsx +++ b/src/frontend/src/modals/shareModal/index.tsx @@ -141,6 +141,7 @@ export default function ShareModal({ }); }); }; + console.log("ShareModal"); const handleUpdateComponent = () => { handleShareComponent(true); diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index d4927f2d9..19f245dd5 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -38,7 +38,6 @@ import { import { getRandomName, isWrappedWithClass } from "../../../../utils/utils"; import ConnectionLineComponent from "../ConnectionLineComponent"; import SelectionMenu from "../SelectionMenuComponent"; -import ExtraSidebar from "../extraSidebarComponent"; const nodeTypes = { genericNode: GenericNode, @@ -59,6 +58,8 @@ export default function Page({ const templates = useTypesStore((state) => state.templates); const setFilterEdge = useFlowStore((state) => state.setFilterEdge); const reactFlowWrapper = useRef(null); + const [showCanvas, setSHowCanvas] = useState(Object.keys(templates).length > 0 && + Object.keys(types).length > 0) const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance); const setReactFlowInstance = useFlowStore( @@ -271,6 +272,10 @@ export default function Page({ }; }, []); + useEffect(() => { + setSHowCanvas(Object.keys(templates).length > 0 && Object.keys(types).length > 0) + }, [templates, types]) + const onConnectMod = useCallback( (params: Connection) => { takeSnapshot(); @@ -432,71 +437,62 @@ export default function Page({ } return ( -
- {!view && } - {/* Main area */} -
- {/* Primary column */} -
-
- {Object.keys(templates).length > 0 && - Object.keys(types).length > 0 ? ( -
- - - {!view && ( - + {showCanvas ? ( +
+ + + {!view && ( + - )} - { - handleGroupNode(); - }} - /> - - {!view && } -
- ) : ( - <> + >
)} -
+ { + handleGroupNode(); + }} + /> +
-
+ ) : ( + <> + )}
+ ); } diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index 7643e66c9..bb4253a64 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -1,6 +1,7 @@ import { cloneDeep } from "lodash"; import { LinkIcon, SparklesIcon } from "lucide-react"; import { useEffect, useMemo, useState } from "react"; +import AccordionComponent from "../../../../components/AccordionComponent"; import ShadTooltip from "../../../../components/ShadTooltipComponent"; import IconComponent from "../../../../components/genericIconComponent"; import { Input } from "../../../../components/ui/input"; @@ -234,6 +235,20 @@ export default function ExtraSidebar(): JSX.Element { [] ); + const getIcon = useMemo(() => { + return (SBSectionName: string) => { + if (nodeIconsLucide[SBSectionName]) { + return ( + + ); + } + }; + }, []); + return (
@@ -310,7 +325,7 @@ export default function ExtraSidebar(): JSX.Element { onDragStart(event, { //split type to remove type in nodes saved with same name removing it's diff --git a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx index 6653e1532..763211e32 100644 --- a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx @@ -35,7 +35,6 @@ import ToolbarSelectItem from "./toolbarSelectItem"; export default function NodeToolbarComponent({ data, deleteNode, - position, setShowNode, numberOfHandles, showNode, @@ -79,6 +78,7 @@ export default function NodeToolbarComponent({ const setEdges = useFlowStore((state) => state.setEdges); const unselectAll = useFlowStore((state) => state.unselectAll); const saveComponent = useFlowsManagerStore((state) => state.saveComponent); + const getNodePosition = useFlowStore((state) => state.getNodePosition); const flows = useFlowsManagerStore((state) => state.flows); const version = useDarkStore((state) => state.version); const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); @@ -146,7 +146,7 @@ export default function NodeToolbarComponent({ takeSnapshot(); expandGroupNode( data.id, - updateFlowPosition(position, data.node?.flow!), + updateFlowPosition(getNodePosition(data.id), data.node?.flow!), data.node!.template, nodes, edges, @@ -631,7 +631,7 @@ export default function NodeToolbarComponent({ )} {hasCode && (
- + />}
)} diff --git a/src/frontend/src/pages/FlowPage/index.tsx b/src/frontend/src/pages/FlowPage/index.tsx index 9aa88a6e2..960e71af4 100644 --- a/src/frontend/src/pages/FlowPage/index.tsx +++ b/src/frontend/src/pages/FlowPage/index.tsx @@ -4,8 +4,10 @@ import Header from "../../components/headerComponent"; import { useDarkStore } from "../../stores/darkStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore"; import Page from "./components/PageComponent"; +import ExtraSidebar from "./components/extraSidebarComponent"; +import FlowToolbar from "../../components/chatComponent"; -export default function FlowPage(): JSX.Element { +export default function FlowPage({ view }: { view?: boolean }): JSX.Element { const setCurrentFlowId = useFlowsManagerStore( (state) => state.setCurrentFlowId ); @@ -17,12 +19,23 @@ export default function FlowPage(): JSX.Element { useEffect(() => { setCurrentFlowId(id!); }, [id]); - return ( <>
- - - - Get Started - - {/* - -
- - {examples.map((example, idx) => { - return ; - })} -
-
-
+ ); } diff --git a/src/frontend/src/pages/deleteAccountPage/index.tsx b/src/frontend/src/pages/deleteAccountPage/index.tsx index af219209b..c82cc1cc7 100644 --- a/src/frontend/src/pages/deleteAccountPage/index.tsx +++ b/src/frontend/src/pages/deleteAccountPage/index.tsx @@ -10,7 +10,6 @@ export default function DeleteAccountPage() { // Implement your account deletion logic here // For example, make an API call to delete the account // Upon successful deletion, you can redirect the user to another page - console.log("Account deleted!"); // Implement the logic to redirect the user after account deletion. // For example, use react-router-dom's useHistory hook. }; diff --git a/src/frontend/src/stores/flowStore.ts b/src/frontend/src/stores/flowStore.ts index 54b71f1ea..4a7b30b6b 100644 --- a/src/frontend/src/stores/flowStore.ts +++ b/src/frontend/src/stores/flowStore.ts @@ -70,6 +70,10 @@ const useFlowStore = create((set, get) => ({ } get().setFlowPool(newFlowPool); }, + getNodePosition: (nodeId: string) => { + const node = get().nodes.find((node) => node.id === nodeId); + return node?.position||{x:0,y:0}; + }, updateFlowPool: ( nodeId: string, data: FlowPoolObjectType | ChatOutputType | chatInputType, diff --git a/src/frontend/src/stores/flowsManagerStore.ts b/src/frontend/src/stores/flowsManagerStore.ts index 2ca51a4c4..56ff43d01 100644 --- a/src/frontend/src/stores/flowsManagerStore.ts +++ b/src/frontend/src/stores/flowsManagerStore.ts @@ -56,7 +56,7 @@ const useFlowsManagerStore = create((set, get) => ({ setFlows: (flows: FlowType[]) => { set({ flows, - currentFlow: flows.find((flow) => flow.id === get().currentFlowId), + // currentFlow: flows.find((flow) => flow.id === get().currentFlowId), }); }, currentFlow: undefined, diff --git a/src/frontend/src/style/applies.css b/src/frontend/src/style/applies.css index 5b1928e76..5104301e3 100644 --- a/src/frontend/src/style/applies.css +++ b/src/frontend/src/style/applies.css @@ -187,7 +187,7 @@ @apply flex w-full select-none items-center justify-between border-y border-y-input bg-background px-3 py-2; } .components-disclosure-arrangement { - @apply -mt-px flex w-full select-none items-center justify-between border-y border-y-input bg-muted px-3 py-2; + @apply -mt-px flex w-full select-none items-center justify-between border-y border-t-2 border-y-input bg-muted px-3 py-2; } .components-disclosure-arrangement-child { /* different color than the non child */ diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index c3e9ab499..03578e224 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -1,5 +1,6 @@ import { ReactElement, ReactNode, SetStateAction } from "react"; import { ReactFlowJsonObject, XYPosition } from "reactflow"; +import { InputOutput } from "../../constants/enums"; import { APIClassType, APITemplateType, TemplateVariableType } from "../api"; import { ChatMessageType } from "../chat"; import { FlowStyleType, FlowType, NodeDataType, NodeType } from "../flow/index"; @@ -217,6 +218,8 @@ export type AccordionComponentType = { open?: string[]; trigger?: string | ReactElement; keyValue?: string; + openDisc?: boolean; + sideBar?: boolean; }; export type Side = "top" | "right" | "bottom" | "left"; @@ -498,7 +501,6 @@ export type fileCardPropsType = { export type nodeToolbarPropsType = { data: NodeDataType; deleteNode: (idx: string) => void; - position: XYPosition; setShowNode: (boolean: any) => void; numberOfHandles: number; showNode: boolean; @@ -563,12 +565,6 @@ export type chatMessagePropsType = { ) => void; }; -export type formModalPropsType = { - open: boolean; - setOpen: Function; - flow: FlowType; -}; - export type genericModalPropsType = { field_name?: string; setValue: (value: string) => void; @@ -583,6 +579,18 @@ export type genericModalPropsType = { readonly?: boolean; }; +export type newFlowModalPropsType = { + open: boolean; + setOpen: (open: boolean) => void; +}; + +export type IOModalPropsType = { + children: JSX.Element; + open: boolean; + setOpen: (open: boolean) => void; + disable?: boolean; +}; + export type buttonBoxPropsType = { onClick: () => void; title: string; @@ -693,15 +701,21 @@ export type dropdownButtonPropsType = { dropdownOptions?: boolean; }; -export type IOInputProps = { - inputType: string; - inputId: string; +export type IOFieldViewProps = { + type: InputOutput; + fieldType: string; + fieldId: string; left?: boolean; }; -export type IOOutputProps = { - outputType: string; - outputId: string; - left?: boolean; + +export type UndrawCardComponentProps = { flow: FlowType }; + +export type chatViewProps = { + sendMessage: (count?: number) => void; + chatValue: string; + setChatValue: (value: string) => void; + lockChat: boolean; + setLockChat: (lock: boolean) => void; }; export type IOFileInputProps = { diff --git a/src/frontend/src/types/zustand/flow/index.ts b/src/frontend/src/types/zustand/flow/index.ts index 71853c5a7..d88504909 100644 --- a/src/frontend/src/types/zustand/flow/index.ts +++ b/src/frontend/src/types/zustand/flow/index.ts @@ -131,4 +131,5 @@ export type FlowStoreType = { data: FlowPoolObjectType | ChatOutputType | chatInputType, buildId?: string ) => void; + getNodePosition: (nodeId: string) => { x: number; y: number }; }; diff --git a/src/frontend/vite.config.ts b/src/frontend/vite.config.ts index b513e36bb..479a98202 100644 --- a/src/frontend/vite.config.ts +++ b/src/frontend/vite.config.ts @@ -1,6 +1,7 @@ import react from "@vitejs/plugin-react-swc"; import { defineConfig } from "vite"; import svgr from "vite-plugin-svgr"; +import MillionCompiler from "@million/lint"; const apiRoutes = ["^/api/v1/", "/health"]; // Use environment variable to determine the target. From f0e50e36d59fbf8fde9685f439b6337f4a6194bf Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Sat, 30 Mar 2024 17:21:27 -0300 Subject: [PATCH 1572/1878] Fix openDisc prop value in ExtraSidebar component --- .../pages/FlowPage/components/extraSidebarComponent/index.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index bb4253a64..efaf26f38 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -359,9 +359,7 @@ export default function ExtraSidebar(): JSX.Element { ) )}{" "} Date: Sat, 30 Mar 2024 17:29:05 -0300 Subject: [PATCH 1573/1878] Fix alignment issue in extra sidebar component --- .../pages/FlowPage/components/extraSidebarComponent/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index efaf26f38..c5a0765d6 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -444,7 +444,7 @@ export default function ExtraSidebar(): JSX.Element { href="https://langflow.store" className="components-disclosure-arrangement" > -
+
{/* BUG ON THIS ICON */} Date: Sat, 30 Mar 2024 17:32:44 -0300 Subject: [PATCH 1574/1878] Refactor RetrievalQAComponent and RetrievalQAWithSourcesChainComponent --- .../langflow/components/chains/RetrievalQA.py | 20 ++++++++++++------- .../chains/RetrievalQAWithSourcesChain.py | 3 ++- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/backend/base/langflow/components/chains/RetrievalQA.py b/src/backend/base/langflow/components/chains/RetrievalQA.py index 4ac514ec5..7b6ba49e4 100644 --- a/src/backend/base/langflow/components/chains/RetrievalQA.py +++ b/src/backend/base/langflow/components/chains/RetrievalQA.py @@ -1,11 +1,11 @@ from typing import Optional -from langchain.chains.combine_documents.base import BaseCombineDocumentsChain from langchain.chains.retrieval_qa.base import RetrievalQA from langchain_core.documents import Document -from langflow.field_typing import BaseMemory, BaseRetriever, Text +from langflow.field_typing import BaseLanguageModel, BaseMemory, BaseRetriever, Text from langflow.interface.custom.custom_component import CustomComponent +from langflow.schema.schema import Record class RetrievalQAComponent(CustomComponent): @@ -14,7 +14,8 @@ class RetrievalQAComponent(CustomComponent): def build_config(self): return { - "combine_documents_chain": {"display_name": "Combine Documents Chain"}, + "llm": {"display_name": "LLM"}, + "chain_type": {"display_name": "Chain Type", "options": ["Stuff", "Map Reduce", "Refine", "Map Rerank"]}, "retriever": {"display_name": "Retriever"}, "memory": {"display_name": "Memory", "required": False}, "input_key": {"display_name": "Input Key", "advanced": True}, @@ -22,13 +23,14 @@ class RetrievalQAComponent(CustomComponent): "return_source_documents": {"display_name": "Return Source Documents"}, "input_value": { "display_name": "Input", - "input_types": ["Text", "Document"], + "input_types": ["Record", "Document"], }, } def build( self, - combine_documents_chain: BaseCombineDocumentsChain, + llm: BaseLanguageModel, + chain_type: str, retriever: BaseRetriever, input_value: str = "", memory: Optional[BaseMemory] = None, @@ -36,8 +38,10 @@ class RetrievalQAComponent(CustomComponent): output_key: str = "result", return_source_documents: bool = True, ) -> Text: - runnable = RetrievalQA( - combine_documents_chain=combine_documents_chain, + chain_type = chain_type.lower().replace(" ", "_") + runnable = RetrievalQA.from_chain_type( + llm=llm, + chain_type=chain_type, retriever=retriever, memory=memory, input_key=input_key, @@ -46,6 +50,8 @@ class RetrievalQAComponent(CustomComponent): ) if isinstance(input_value, Document): input_value = input_value.page_content + if isinstance(input_value, Record): + input_value = input_value.get_text() self.status = runnable result = runnable.invoke({input_key: input_value}) result = result.content if hasattr(result, "content") else result diff --git a/src/backend/base/langflow/components/chains/RetrievalQAWithSourcesChain.py b/src/backend/base/langflow/components/chains/RetrievalQAWithSourcesChain.py index 0c98a16ec..75a9131f5 100644 --- a/src/backend/base/langflow/components/chains/RetrievalQAWithSourcesChain.py +++ b/src/backend/base/langflow/components/chains/RetrievalQAWithSourcesChain.py @@ -16,7 +16,7 @@ class RetrievalQAWithSourcesChainComponent(CustomComponent): "llm": {"display_name": "LLM"}, "chain_type": { "display_name": "Chain Type", - "options": ["stuff", "map_reduce", "map_rerank", "refine"], + "options": ["Stuff", "Map Reduce", "Refine", "Map Rerank"], "info": "The type of chain to use to combined Documents.", }, "memory": {"display_name": "Memory"}, @@ -37,6 +37,7 @@ class RetrievalQAWithSourcesChainComponent(CustomComponent): memory: Optional[BaseMemory] = None, return_source_documents: Optional[bool] = True, ) -> Text: + chain_type = chain_type.lower().replace(" ", "_") runnable = RetrievalQAWithSourcesChain.from_chain_type( llm=llm, chain_type=chain_type, From 4428c36bfa58926bebd47fad889cb2b1c34bf043 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sat, 30 Mar 2024 17:33:00 -0300 Subject: [PATCH 1575/1878] Refactor SubFlowComponent display name --- src/backend/base/langflow/components/experimental/SubFlow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/base/langflow/components/experimental/SubFlow.py b/src/backend/base/langflow/components/experimental/SubFlow.py index af309fa88..72e07c8e8 100644 --- a/src/backend/base/langflow/components/experimental/SubFlow.py +++ b/src/backend/base/langflow/components/experimental/SubFlow.py @@ -1,19 +1,19 @@ from typing import Any, List, Optional -from langflow.helpers.flow import get_flow_inputs from loguru import logger from langflow.custom import CustomComponent from langflow.graph.graph.base import Graph from langflow.graph.schema import ResultData, RunOutputs from langflow.graph.vertex.base import Vertex +from langflow.helpers.flow import get_flow_inputs from langflow.schema import Record from langflow.schema.dotdict import dotdict from langflow.template.field.base import TemplateField class SubFlowComponent(CustomComponent): - display_name = "SubFlow" + display_name = "Sub Flow" description = "Dynamically Generates a Component from a Flow. The output is a list of records with keys 'result' and 'message'." beta: bool = True field_order = ["flow_name"] From 4f1b7bc3f38432e4b76c97bd0ed85c65c53b7032 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Sat, 30 Mar 2024 17:40:16 -0300 Subject: [PATCH 1576/1878] Add parent disclosure for core components --- .../extraSidebarComponent/index.tsx | 68 +++++++++++-------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index c5a0765d6..43cbc0137 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -277,15 +277,23 @@ export default function ExtraSidebar(): JSX.Element { >
+
+
+ + Core Components + +
+
{Object.keys(dataFilter) .sort(sortKeys) .filter((x) => PRIORITY_SIDEBAR_ORDER.includes(x)) @@ -325,7 +333,7 @@ export default function ExtraSidebar(): JSX.Element { onDragStart(event, { //split type to remove type in nodes saved with same name removing it's @@ -344,7 +352,7 @@ export default function ExtraSidebar(): JSX.Element { } official={ dataFilter[SBSectionName][SBItemName].official === - false + false ? false : true } @@ -436,33 +444,33 @@ export default function ExtraSidebar(): JSX.Element { {index === Object.keys(dataFilter).length - - PRIORITY_SIDEBAR_ORDER.length + - 1 && ( - <> -
-
- {/* BUG ON THIS ICON */} - + PRIORITY_SIDEBAR_ORDER.length + + 1 && ( + <> + +
+ {/* BUG ON THIS ICON */} + - - Discover More - -
-
-
- + + Discover More +
-
-
- - )} +
+
+ +
+
+ + + )} ) : (
From 8651850803116afc570e871f20f56c83213bcd19 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sat, 30 Mar 2024 17:42:38 -0300 Subject: [PATCH 1577/1878] Refactor data and helper components --- src/backend/base/langflow/components/data/Directory.py | 2 +- src/backend/base/langflow/components/data/File.py | 2 +- src/backend/base/langflow/components/data/URL.py | 2 +- src/backend/base/langflow/components/helpers/CombineText.py | 1 + src/backend/base/langflow/components/helpers/RecordsToText.py | 1 - src/backend/base/langflow/components/helpers/SearchApi.py | 0 6 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 src/backend/base/langflow/components/helpers/SearchApi.py diff --git a/src/backend/base/langflow/components/data/Directory.py b/src/backend/base/langflow/components/data/Directory.py index a40e63711..87dc99287 100644 --- a/src/backend/base/langflow/components/data/Directory.py +++ b/src/backend/base/langflow/components/data/Directory.py @@ -9,7 +9,7 @@ class DirectoryComponent(CustomComponent): display_name = "Directory" description = "Recursively load files from a directory." icon = "folder" - + def build_config(self) -> Dict[str, Any]: return { "path": {"display_name": "Path"}, diff --git a/src/backend/base/langflow/components/data/File.py b/src/backend/base/langflow/components/data/File.py index a01d84528..fe3b08066 100644 --- a/src/backend/base/langflow/components/data/File.py +++ b/src/backend/base/langflow/components/data/File.py @@ -10,7 +10,7 @@ class FileComponent(CustomComponent): display_name = "File" description = "A generic file loader." icon = "file-text" - + def build_config(self) -> Dict[str, Any]: return { "paths": { diff --git a/src/backend/base/langflow/components/data/URL.py b/src/backend/base/langflow/components/data/URL.py index 6b9413354..2b286e126 100644 --- a/src/backend/base/langflow/components/data/URL.py +++ b/src/backend/base/langflow/components/data/URL.py @@ -10,7 +10,7 @@ class URLComponent(CustomComponent): display_name = "URL" description = "Fetch content from one or more URLs." icon = "layout-template" - + def build_config(self) -> Dict[str, Any]: return { "urls": {"display_name": "URL"}, diff --git a/src/backend/base/langflow/components/helpers/CombineText.py b/src/backend/base/langflow/components/helpers/CombineText.py index 1f8ac5e13..fcd23c188 100644 --- a/src/backend/base/langflow/components/helpers/CombineText.py +++ b/src/backend/base/langflow/components/helpers/CombineText.py @@ -1,6 +1,7 @@ from langflow.interface.custom.custom_component import CustomComponent from langflow.field_typing import Text + class CombineTextComponent(CustomComponent): display_name = "Combine Text" description = "Concatenate two text sources into a single text chunk using a specified delimiter." diff --git a/src/backend/base/langflow/components/helpers/RecordsToText.py b/src/backend/base/langflow/components/helpers/RecordsToText.py index 1a35c1c80..8f4fed311 100644 --- a/src/backend/base/langflow/components/helpers/RecordsToText.py +++ b/src/backend/base/langflow/components/helpers/RecordsToText.py @@ -7,7 +7,6 @@ from langflow.schema import Record class RecordsToTextComponent(CustomComponent): display_name = "Records To Text" description = "Convert Records into plain text following a specified template." - def build_config(self): return { diff --git a/src/backend/base/langflow/components/helpers/SearchApi.py b/src/backend/base/langflow/components/helpers/SearchApi.py deleted file mode 100644 index e69de29bb..000000000 From fd580b75681fa53b2502aab7bb8ca67ae40d930f Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sat, 30 Mar 2024 17:43:02 -0300 Subject: [PATCH 1578/1878] Update ESLint configuration --- src/frontend/.eslintrc.json | 59 ++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/src/frontend/.eslintrc.json b/src/frontend/.eslintrc.json index c9ec184fd..682c7fc87 100644 --- a/src/frontend/.eslintrc.json +++ b/src/frontend/.eslintrc.json @@ -1,32 +1,29 @@ { - "extends": [ - "eslint:recommended", - "plugin:node/recommended" - ], - "parserOptions": { - "ecmaVersion": 2018 - }, - "rules": { - "no-console": "warn", - "no-self-assign": "warn", - "no-self-compare":"warn", - "complexity": ["error", { "max": 15 }], - "indent": ["error", 2, { "SwitchCase": 1 }], - "no-dupe-keys": "error", - "no-invalid-regexp": "error", - "no-undef": "error", - "no-return-assign": "error", - "no-redeclare": "error", - "no-empty": "error", - "no-await-in-loop": "error", - "node/exports-style": ["error", "module.exports"], - "node/file-extension-in-import": ["error", "always"], - "node/prefer-global/buffer": ["error", "always"], - "node/prefer-global/console": ["error", "always"], - "node/prefer-global/process": ["error", "always"], - "node/prefer-global/url-search-params": ["error", "always"], - "node/prefer-global/url": ["error", "always"], - "node/prefer-promises/dns": "error", - "node/prefer-promises/fs": "error" - } -} \ No newline at end of file + "extends": ["eslint:recommended", "plugin:node/recommended"], + "parserOptions": { + "ecmaVersion": 2018 + }, + "rules": { + "no-console": "warn", + "no-self-assign": "warn", + "no-self-compare": "warn", + "complexity": ["error", { "max": 15 }], + "indent": ["error", 2, { "SwitchCase": 1 }], + "no-dupe-keys": "error", + "no-invalid-regexp": "error", + "no-undef": "error", + "no-return-assign": "error", + "no-redeclare": "error", + "no-empty": "error", + "no-await-in-loop": "error", + "node/exports-style": ["error", "module.exports"], + "node/file-extension-in-import": ["error", "always"], + "node/prefer-global/buffer": ["error", "always"], + "node/prefer-global/console": ["error", "always"], + "node/prefer-global/process": ["error", "always"], + "node/prefer-global/url-search-params": ["error", "always"], + "node/prefer-global/url": ["error", "always"], + "node/prefer-promises/dns": "error", + "node/prefer-promises/fs": "error" + } +} From e9cb84a933e1d9a5838e902b5b6b732d0dee6ce4 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sat, 30 Mar 2024 17:43:12 -0300 Subject: [PATCH 1579/1878] Fix formatting issues and update dependencies --- .../components/parameterComponent/index.tsx | 4 +- .../src/CustomNodes/GenericNode/index.tsx | 55 +++++++++++-------- .../src/components/chatComponent/index.tsx | 3 +- .../components/dropdownComponent/index.tsx | 4 +- src/frontend/src/components/ui/button.tsx | 13 ++--- src/frontend/src/constants/enums.ts | 2 +- src/frontend/src/index.tsx | 2 +- .../components/FileInput/index.tsx | 2 +- .../IOModal/components/IOFieldView/index.tsx | 2 +- .../components/chatView/chatInput/index.tsx | 4 +- .../IOModal/components/chatView/index.tsx | 2 +- src/frontend/src/modals/IOModal/index.tsx | 6 +- .../components/NewFlowCardComponent/index.tsx | 7 ++- .../components/undrawCards/index.tsx | 14 +++-- .../src/modals/NewFlowModal/index.tsx | 11 ++-- .../components/PageComponent/index.tsx | 16 +++--- .../extraSidebarComponent/index.tsx | 1 - .../components/nodeToolbarComponent/index.tsx | 34 ++++++------ src/frontend/src/pages/FlowPage/index.tsx | 7 +-- src/frontend/src/pages/MainPage/index.tsx | 5 +- src/frontend/src/stores/flowStore.ts | 2 +- src/frontend/src/types/components/index.ts | 2 +- src/frontend/src/utils/reactflowUtils.ts | 2 +- src/frontend/vite.config.ts | 1 - 24 files changed, 111 insertions(+), 90 deletions(-) diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 041c26fc4..c9b8e901f 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -402,7 +402,9 @@ export default function ParameterComponent({ {title} )} - + {required ? "*" : ""}
diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index c9a8e463a..1e8d15451 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -345,29 +345,40 @@ export default function GenericNode({ return ( { - takeSnapshot(); - deleteNode(id); - }} - setShowNode={(show) => { - setNode(data.id, (old) => ({ - ...old, - data: { ...old.data, showNode: show }, - })); - }} - setShowState={setShowNode} - numberOfHandles={handles} - showNode={showNode} - openAdvancedModal={false} - onCloseAdvancedModal={() => {}} - updateNodeCode={updateNodeCode} - isOutdated={isOutdated} - selected={selected} - /> + data={data} + deleteNode={(id) => { + takeSnapshot(); + deleteNode(id); + }} + setShowNode={(show) => { + setNode(data.id, (old) => ({ + ...old, + data: { ...old.data, showNode: show }, + })); + }} + setShowState={setShowNode} + numberOfHandles={handles} + showNode={showNode} + openAdvancedModal={false} + onCloseAdvancedModal={() => {}} + updateNodeCode={updateNodeCode} + isOutdated={isOutdated} + selected={selected} + /> - ) - }, [data, deleteNode, takeSnapshot, setNode, setShowNode, handles, showNode, updateNodeCode, isOutdated, selected]); + ); + }, [ + data, + deleteNode, + takeSnapshot, + setNode, + setShowNode, + handles, + showNode, + updateNodeCode, + isOutdated, + selected, + ]); return ( <> diff --git a/src/frontend/src/components/chatComponent/index.tsx b/src/frontend/src/components/chatComponent/index.tsx index b387a2ae8..66ff2b609 100644 --- a/src/frontend/src/components/chatComponent/index.tsx +++ b/src/frontend/src/components/chatComponent/index.tsx @@ -1,13 +1,12 @@ import { Transition } from "@headlessui/react"; import { useEffect, useMemo, useRef, useState } from "react"; import ApiModal from "../../modals/ApiModal"; +import IOModal from "../../modals/IOModal"; import ShareModal from "../../modals/shareModal"; import useFlowStore from "../../stores/flowStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore"; import { useStoreStore } from "../../stores/storeStore"; -import { ChatType } from "../../types/chat"; import { classNames } from "../../utils/utils"; -import IOModal from "../../modals/IOModal"; import ForwardedIconComponent from "../genericIconComponent"; import { Separator } from "../ui/separator"; diff --git a/src/frontend/src/components/dropdownComponent/index.tsx b/src/frontend/src/components/dropdownComponent/index.tsx index 729b11a55..e0c0d39cf 100644 --- a/src/frontend/src/components/dropdownComponent/index.tsx +++ b/src/frontend/src/components/dropdownComponent/index.tsx @@ -52,9 +52,9 @@ export default function Dropdown({ editNode ? "input-edit-node" : "py-2" )} > - {(value && + {value && value !== "" && - options.find((option) => option === value)) + options.find((option) => option === value) ? options.find((option) => option === value) : "Choose an option..."} word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) - .join(' '); + .split(" ") + .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join(" "); } const Button = React.forwardRef( - ({ className, variant, size, asChild = false,children, ...props }, ref) => { + ({ className, variant, size, asChild = false, children, ...props }, ref) => { const Comp = asChild ? Slot : "button"; let newChildren = children; - if (typeof(children)==="string"){ - newChildren = toTitleCase(children) + if (typeof children === "string") { + newChildren = toTitleCase(children); } return ( ( ref={ref} children={newChildren} {...props} - /> ); } diff --git a/src/frontend/src/constants/enums.ts b/src/frontend/src/constants/enums.ts index d7d3ac334..2573b5194 100644 --- a/src/frontend/src/constants/enums.ts +++ b/src/frontend/src/constants/enums.ts @@ -18,4 +18,4 @@ export enum BuildStatus { export enum InputOutput { INPUT = "input", OUTPUT = "output", -} \ No newline at end of file +} diff --git a/src/frontend/src/index.tsx b/src/frontend/src/index.tsx index 051908e3b..62e73f091 100644 --- a/src/frontend/src/index.tsx +++ b/src/frontend/src/index.tsx @@ -8,8 +8,8 @@ import "./style/index.css"; // @ts-ignore import "./style/applies.css"; // @ts-ignore -import "./style/classes.css"; import { StrictMode } from "react"; +import "./style/classes.css"; const root = ReactDOM.createRoot( document.getElementById("root") as HTMLElement diff --git a/src/frontend/src/modals/IOModal/components/IOFieldView/components/FileInput/index.tsx b/src/frontend/src/modals/IOModal/components/IOFieldView/components/FileInput/index.tsx index 90bf6e974..935db2644 100644 --- a/src/frontend/src/modals/IOModal/components/IOFieldView/components/FileInput/index.tsx +++ b/src/frontend/src/modals/IOModal/components/IOFieldView/components/FileInput/index.tsx @@ -1,11 +1,11 @@ import { Button } from "../../../../../../components/ui/button"; import { useEffect, useState } from "react"; +import IconComponent from "../../../../../../components/genericIconComponent"; import { BASE_URL_API } from "../../../../../../constants/constants"; import { uploadFile } from "../../../../../../controllers/API"; import useFlowsManagerStore from "../../../../../../stores/flowsManagerStore"; import { IOFileInputProps } from "../../../../../../types/components"; -import IconComponent from "../../../../../../components/genericIconComponent"; export default function IOFileInput({ field, updateValue }: IOFileInputProps) { //component to handle file upload from chatIO diff --git a/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx b/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx index cbb81cc0e..25f9deeaa 100644 --- a/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx +++ b/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx @@ -1,9 +1,9 @@ import { cloneDeep } from "lodash"; +import { Textarea } from "../../../../components/ui/textarea"; import { InputOutput } from "../../../../constants/enums"; import useFlowStore from "../../../../stores/flowStore"; import { IOFieldViewProps } from "../../../../types/components"; import IOFileInput from "./components/FileInput"; -import { Textarea } from "../../../../components/ui/textarea"; export default function IOFieldView({ type, diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx index fd9baa39e..30d609f8c 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx @@ -25,7 +25,6 @@ export default function ChatInput({ } }, [lockChat, inputRef]); - useEffect(() => { if (inputRef.current) { inputRef.current.style.height = "inherit"; // Reset the height @@ -42,7 +41,8 @@ export default function ChatInput({ event.key === "Enter" && !lockChat && !saveLoading && - !event.shiftKey && !event.nativeEvent.isComposing + !event.shiftKey && + !event.nativeEvent.isComposing ) { sendMessage(repeat); } diff --git a/src/frontend/src/modals/IOModal/components/chatView/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/index.tsx index f439fe283..e655f22a5 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/index.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/index.tsx @@ -15,10 +15,10 @@ import { ChatOutputType, FlowPoolObjectType, } from "../../../../types/chat"; +import { chatViewProps } from "../../../../types/components"; import { classNames } from "../../../../utils/utils"; import ChatInput from "./chatInput"; import ChatMessage from "./chatMessage"; -import { chatViewProps } from "../../../../types/components"; export default function ChatView({ sendMessage, diff --git a/src/frontend/src/modals/IOModal/index.tsx b/src/frontend/src/modals/IOModal/index.tsx index 30a753ecf..e5b1c885c 100644 --- a/src/frontend/src/modals/IOModal/index.tsx +++ b/src/frontend/src/modals/IOModal/index.tsx @@ -1,9 +1,7 @@ import { useEffect, useState } from "react"; import AccordionComponent from "../../components/AccordionComponent"; -import IOFieldView from "./components/IOFieldView"; import ShadTooltip from "../../components/ShadTooltipComponent"; import IconComponent from "../../components/genericIconComponent"; -import ChatView from "./components/chatView"; import { Badge } from "../../components/ui/badge"; import { Button } from "../../components/ui/button"; import { @@ -20,11 +18,13 @@ import { import { InputOutput } from "../../constants/enums"; import useFlowStore from "../../stores/flowStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore"; +import { IOModalPropsType } from "../../types/components"; import { NodeType } from "../../types/flow"; import { updateVerticesOrder } from "../../utils/buildUtils"; import { cn } from "../../utils/utils"; import BaseModal from "../baseModal"; -import { IOModalPropsType } from "../../types/components"; +import IOFieldView from "./components/IOFieldView"; +import ChatView from "./components/chatView"; export default function IOModal({ children, diff --git a/src/frontend/src/modals/NewFlowModal/components/NewFlowCardComponent/index.tsx b/src/frontend/src/modals/NewFlowModal/components/NewFlowCardComponent/index.tsx index bbc6e6111..8fbd8ab8f 100644 --- a/src/frontend/src/modals/NewFlowModal/components/NewFlowCardComponent/index.tsx +++ b/src/frontend/src/modals/NewFlowModal/components/NewFlowCardComponent/index.tsx @@ -1,6 +1,11 @@ import { useNavigate } from "react-router-dom"; +import { + Card, + CardContent, + CardDescription, + CardTitle, +} from "../../../../components/ui/card"; import useFlowsManagerStore from "../../../../stores/flowsManagerStore"; -import { Card, CardContent, CardDescription, CardTitle } from "../../../../components/ui/card"; export default function NewFlowCardComponent() { const addFlow = useFlowsManagerStore((state) => state.addFlow); diff --git a/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx b/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx index aeed1351e..a98413dcb 100644 --- a/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx +++ b/src/frontend/src/modals/NewFlowModal/components/undrawCards/index.tsx @@ -10,13 +10,19 @@ import { ReactComponent as ChatWithHistory } from "../../../../assets/undraw_mob import { ReactComponent as Assistant } from "../../../../assets/undraw_team_collaboration_re_ow29.svg"; //@ts-ignore import { ReactComponent as APIRequest } from "../../../../assets/undraw_real_time_analytics_re_yliv.svg"; +import { + Card, + CardContent, + CardDescription, + CardTitle, +} from "../../../../components/ui/card"; import useFlowsManagerStore from "../../../../stores/flowsManagerStore"; -import { FlowType } from "../../../../types/flow"; -import { updateIds } from "../../../../utils/reactflowUtils"; -import { Card, CardContent, CardDescription, CardTitle } from "../../../../components/ui/card"; import { UndrawCardComponentProps } from "../../../../types/components"; +import { updateIds } from "../../../../utils/reactflowUtils"; -export default function UndrawCardComponent({ flow }: UndrawCardComponentProps): JSX.Element { +export default function UndrawCardComponent({ + flow, +}: UndrawCardComponentProps): JSX.Element { const addFlow = useFlowsManagerStore((state) => state.addFlow); const navigate = useNavigate(); diff --git a/src/frontend/src/modals/NewFlowModal/index.tsx b/src/frontend/src/modals/NewFlowModal/index.tsx index d318475c3..5ad736247 100644 --- a/src/frontend/src/modals/NewFlowModal/index.tsx +++ b/src/frontend/src/modals/NewFlowModal/index.tsx @@ -1,10 +1,13 @@ +import useFlowsManagerStore from "../../stores/flowsManagerStore"; +import { newFlowModalPropsType } from "../../types/components"; +import BaseModal from "../baseModal"; import NewFlowCardComponent from "./components/NewFlowCardComponent"; import UndrawCardComponent from "./components/undrawCards"; -import useFlowsManagerStore from "../../stores/flowsManagerStore"; -import BaseModal from "../baseModal"; -import { newFlowModalPropsType } from "../../types/components"; -export default function NewFlowModal({ open, setOpen }: newFlowModalPropsType): JSX.Element { +export default function NewFlowModal({ + open, + setOpen, +}: newFlowModalPropsType): JSX.Element { const examples = useFlowsManagerStore((state) => state.examples); return ( diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index 19f245dd5..32dc23f89 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -12,7 +12,6 @@ import ReactFlow, { updateEdge, } from "reactflow"; import GenericNode from "../../../../CustomNodes/GenericNode"; -import FlowToolbar from "../../../../components/chatComponent"; import { INVALID_SELECTION_ERROR_ALERT, UPLOAD_ALERT_LIST, @@ -58,8 +57,9 @@ export default function Page({ const templates = useTypesStore((state) => state.templates); const setFilterEdge = useFlowStore((state) => state.setFilterEdge); const reactFlowWrapper = useRef(null); - const [showCanvas, setSHowCanvas] = useState(Object.keys(templates).length > 0 && - Object.keys(types).length > 0) + const [showCanvas, setSHowCanvas] = useState( + Object.keys(templates).length > 0 && Object.keys(types).length > 0 + ); const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance); const setReactFlowInstance = useFlowStore( @@ -273,8 +273,10 @@ export default function Page({ }, []); useEffect(() => { - setSHowCanvas(Object.keys(templates).length > 0 && Object.keys(types).length > 0) - }, [templates, types]) + setSHowCanvas( + Object.keys(templates).length > 0 && Object.keys(types).length > 0 + ); + }, [templates, types]); const onConnectMod = useCallback( (params: Connection) => { @@ -437,7 +439,6 @@ export default function Page({ } return ( -
{showCanvas ? (
@@ -491,8 +492,7 @@ export default function Page({
) : ( <> - )} + )}
- ); } diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index 43cbc0137..9b057fde7 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -1,7 +1,6 @@ import { cloneDeep } from "lodash"; import { LinkIcon, SparklesIcon } from "lucide-react"; import { useEffect, useMemo, useState } from "react"; -import AccordionComponent from "../../../../components/AccordionComponent"; import ShadTooltip from "../../../../components/ShadTooltipComponent"; import IconComponent from "../../../../components/genericIconComponent"; import { Input } from "../../../../components/ui/input"; diff --git a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx index 763211e32..c507a541f 100644 --- a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx @@ -631,22 +631,24 @@ export default function NodeToolbarComponent({ )} {hasCode && (
- {openModal&& } + {openModal && ( + + )}
)} diff --git a/src/frontend/src/pages/FlowPage/index.tsx b/src/frontend/src/pages/FlowPage/index.tsx index 960e71af4..a222dddcc 100644 --- a/src/frontend/src/pages/FlowPage/index.tsx +++ b/src/frontend/src/pages/FlowPage/index.tsx @@ -1,11 +1,11 @@ import { useEffect } from "react"; import { useParams } from "react-router-dom"; +import FlowToolbar from "../../components/chatComponent"; import Header from "../../components/headerComponent"; import { useDarkStore } from "../../stores/darkStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore"; import Page from "./components/PageComponent"; import ExtraSidebar from "./components/extraSidebarComponent"; -import FlowToolbar from "../../components/chatComponent"; export default function FlowPage({ view }: { view?: boolean }): JSX.Element { const setCurrentFlowId = useFlowsManagerStore( @@ -23,7 +23,7 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element { <>
- {currentFlow && + {currentFlow && (
{!view && }
@@ -32,10 +32,9 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
{!view && } -
- } + )} state.uploadFlow); const setCurrentFlowId = useFlowsManagerStore( diff --git a/src/frontend/src/stores/flowStore.ts b/src/frontend/src/stores/flowStore.ts index 4a7b30b6b..15ee69169 100644 --- a/src/frontend/src/stores/flowStore.ts +++ b/src/frontend/src/stores/flowStore.ts @@ -72,7 +72,7 @@ const useFlowStore = create((set, get) => ({ }, getNodePosition: (nodeId: string) => { const node = get().nodes.find((node) => node.id === nodeId); - return node?.position||{x:0,y:0}; + return node?.position || { x: 0, y: 0 }; }, updateFlowPool: ( nodeId: string, diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index 03578e224..378fa8674 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -1,5 +1,5 @@ import { ReactElement, ReactNode, SetStateAction } from "react"; -import { ReactFlowJsonObject, XYPosition } from "reactflow"; +import { ReactFlowJsonObject } from "reactflow"; import { InputOutput } from "../../constants/enums"; import { APIClassType, APITemplateType, TemplateVariableType } from "../api"; import { ChatMessageType } from "../chat"; diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts index 1a803bf82..f9de6099b 100644 --- a/src/frontend/src/utils/reactflowUtils.ts +++ b/src/frontend/src/utils/reactflowUtils.ts @@ -1170,7 +1170,7 @@ export function downloadNode(NodeFLow: FlowType) { type: "application/json", }); element.href = URL.createObjectURL(file); - element.download = `${NodeFLow?.name??"node"}.json`; + element.download = `${NodeFLow?.name ?? "node"}.json`; element.click(); } diff --git a/src/frontend/vite.config.ts b/src/frontend/vite.config.ts index 479a98202..b513e36bb 100644 --- a/src/frontend/vite.config.ts +++ b/src/frontend/vite.config.ts @@ -1,7 +1,6 @@ import react from "@vitejs/plugin-react-swc"; import { defineConfig } from "vite"; import svgr from "vite-plugin-svgr"; -import MillionCompiler from "@million/lint"; const apiRoutes = ["^/api/v1/", "/health"]; // Use environment variable to determine the target. From f381d0f065378f082349cf8e1cb2b9be57893de5 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Sat, 30 Mar 2024 22:46:40 +0200 Subject: [PATCH 1580/1878] Fixed display name of IOView --- src/frontend/src/modals/IOModal/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/modals/IOModal/index.tsx b/src/frontend/src/modals/IOModal/index.tsx index e5b1c885c..707d039c1 100644 --- a/src/frontend/src/modals/IOModal/index.tsx +++ b/src/frontend/src/modals/IOModal/index.tsx @@ -315,7 +315,10 @@ export default function IOModal({ className="h-6 w-6" > - {selectedViewField.type} + { + nodes.find((node) => node.id === selectedViewField.id) + ?.data.node.display_name + }
{inputs.some( From 70135e7353b35b12b83ffa7eed7e6d386e5c2a85 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sat, 30 Mar 2024 17:51:55 -0300 Subject: [PATCH 1581/1878] Refactor onBuildComplete in flowStore.ts to include allNodesValid parameter --- src/frontend/src/stores/flowStore.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/stores/flowStore.ts b/src/frontend/src/stores/flowStore.ts index 15ee69169..bcc8f6309 100644 --- a/src/frontend/src/stores/flowStore.ts +++ b/src/frontend/src/stores/flowStore.ts @@ -529,9 +529,9 @@ const useFlowStore = create((set, get) => ({ onGetOrderSuccess: () => { setNoticeData({ title: "Running components" }); }, - onBuildComplete: () => { + onBuildComplete: (allNodesValid) => { const nodeId = startNodeId || stopNodeId; - if (nodeId) { + if (nodeId && allNodesValid) { setSuccessData({ title: `${ get().nodes.find((node) => node.id === nodeId)?.data.node From f65b7680ba723e06cc05281da4074fd63d3b20db Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Sat, 30 Mar 2024 17:55:33 -0300 Subject: [PATCH 1582/1878] Add console.log for title and color in ParameterComponent --- .../GenericNode/components/parameterComponent/index.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 041c26fc4..04350aa27 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -88,6 +88,7 @@ export default function ParameterComponent({ const myData = useTypesStore((state) => state.data); const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); + console.log(title, color); const handleRefreshButtonPress = async (name, data) => { setIsLoading(true); @@ -358,7 +359,7 @@ export default function ParameterComponent({ !showNode ? "mt-0" : "" )} style={{ - borderColor: color, + borderColor: color??nodeColors.unknown, }} onClick={() => { setFilterEdge(groupedEdge.current); @@ -451,7 +452,7 @@ export default function ParameterComponent({ "h-3 w-3 rounded-full border-2 bg-background" )} style={{ - borderColor: color, + borderColor: color?? nodeColors.unknown, }} onClick={() => { setFilterEdge(groupedEdge.current); From 5e9e6dc54d7900594258c8c96a2f4f4c13a335cb Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Sat, 30 Mar 2024 22:53:19 +0200 Subject: [PATCH 1583/1878] Filled chat message button --- src/frontend/src/style/applies.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/style/applies.css b/src/frontend/src/style/applies.css index 5104301e3..2cf6754b3 100644 --- a/src/frontend/src/style/applies.css +++ b/src/frontend/src/style/applies.css @@ -917,7 +917,7 @@ @apply mr-2 h-5 w-5 rotate-[44deg]; } .form-modal-play-icon { - @apply mx-1 h-5 w-5; + @apply mx-1 h-5 w-5 fill-inherit; } .form-modal-chat-position { @apply flex-max-width px-2 py-6 pl-4 pr-9; From 08252710c41a0ce85efd1252894fdecd1d9a70c8 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Sat, 30 Mar 2024 22:57:22 +0200 Subject: [PATCH 1584/1878] Made icon be the same to inputs and outputs --- src/frontend/src/modals/IOModal/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/modals/IOModal/index.tsx b/src/frontend/src/modals/IOModal/index.tsx index 707d039c1..b337b7a7e 100644 --- a/src/frontend/src/modals/IOModal/index.tsx +++ b/src/frontend/src/modals/IOModal/index.tsx @@ -232,7 +232,7 @@ export default function IOModal({ className="api-modal-tabs-content mt-4" >
- + {OUTPUTS_MODAL_TITLE}
{nodes From f9cb449c4f5459fac3aab31f54e0bd3f6669464b Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sat, 30 Mar 2024 17:58:01 -0300 Subject: [PATCH 1585/1878] Set onBuildComplete to run after all layers --- src/frontend/src/utils/buildUtils.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/frontend/src/utils/buildUtils.ts b/src/frontend/src/utils/buildUtils.ts index 46b81ba9d..bc2cc62e7 100644 --- a/src/frontend/src/utils/buildUtils.ts +++ b/src/frontend/src/utils/buildUtils.ts @@ -204,12 +204,11 @@ export async function buildVertices({ if (stop) { break; } - - if (onBuildComplete) { - const allNodesValid = buildResults.every((result) => result); - onBuildComplete(allNodesValid); - useFlowStore.getState().setIsBuilding(false); - } + } + if (onBuildComplete) { + const allNodesValid = buildResults.every((result) => result); + onBuildComplete(allNodesValid); + useFlowStore.getState().setIsBuilding(false); } } async function buildVertex({ From 1510f55efee62d20999c66797650f23f7589d107 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sat, 30 Mar 2024 17:58:11 -0300 Subject: [PATCH 1586/1878] Refactor ExtraSidebar component --- .../extraSidebarComponent/index.tsx | 67 +++++++++---------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index 9b057fde7..6711396a8 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -276,21 +276,18 @@ export default function ExtraSidebar(): JSX.Element { >
-
-
- - Core Components - +
+
+ Core Components
{Object.keys(dataFilter) @@ -351,7 +348,7 @@ export default function ExtraSidebar(): JSX.Element { } official={ dataFilter[SBSectionName][SBItemName].official === - false + false ? false : true } @@ -443,33 +440,33 @@ export default function ExtraSidebar(): JSX.Element { {index === Object.keys(dataFilter).length - - PRIORITY_SIDEBAR_ORDER.length + - 1 && ( - <> -
-
- {/* BUG ON THIS ICON */} - + PRIORITY_SIDEBAR_ORDER.length + + 1 && ( + <> + +
+ {/* BUG ON THIS ICON */} + - - Discover More - + + Discover More + +
+
+ + + )} ) : (
From de1e22001d6fdfcfba138a4dff60dae9c2bfa353 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sat, 30 Mar 2024 17:59:08 -0300 Subject: [PATCH 1587/1878] Fix border color in parameterComponent --- .../GenericNode/components/parameterComponent/index.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 38be043cd..f2d3a1886 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -88,7 +88,6 @@ export default function ParameterComponent({ const myData = useTypesStore((state) => state.data); const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); - console.log(title, color); const handleRefreshButtonPress = async (name, data) => { setIsLoading(true); @@ -359,7 +358,7 @@ export default function ParameterComponent({ !showNode ? "mt-0" : "" )} style={{ - borderColor: color??nodeColors.unknown, + borderColor: color ?? nodeColors.unknown, }} onClick={() => { setFilterEdge(groupedEdge.current); @@ -454,7 +453,7 @@ export default function ParameterComponent({ "h-3 w-3 rounded-full border-2 bg-background" )} style={{ - borderColor: color?? nodeColors.unknown, + borderColor: color ?? nodeColors.unknown, }} onClick={() => { setFilterEdge(groupedEdge.current); From 5e8b957cf522e5d64f948e716687ed8db95c39b0 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Sat, 30 Mar 2024 17:59:41 -0300 Subject: [PATCH 1588/1878] Update EditFlowSettingsComponent textarea styling --- .../src/components/EditFlowSettingsComponent/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/components/EditFlowSettingsComponent/index.tsx b/src/frontend/src/components/EditFlowSettingsComponent/index.tsx index 0e927f24f..919a2e68a 100644 --- a/src/frontend/src/components/EditFlowSettingsComponent/index.tsx +++ b/src/frontend/src/components/EditFlowSettingsComponent/index.tsx @@ -74,11 +74,12 @@ export const EditFlowSettings: React.FC = ({ onChange={handleDescriptionChange} value={description!} placeholder="Flow description" - className="mt-2 max-h-[100px] font-normal" + className="mt-2 max-h-[100px] font-normal resize-none" rows={3} onDoubleClickCapture={(event) => { handleFocus(event); }} + /> ) : ( Date: Sat, 30 Mar 2024 18:06:32 -0300 Subject: [PATCH 1589/1878] Add SplitTextComponent to split text into chunks --- .../langflow/components/helpers/SplitText.py | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/backend/base/langflow/components/helpers/SplitText.py diff --git a/src/backend/base/langflow/components/helpers/SplitText.py b/src/backend/base/langflow/components/helpers/SplitText.py new file mode 100644 index 000000000..ad80c4947 --- /dev/null +++ b/src/backend/base/langflow/components/helpers/SplitText.py @@ -0,0 +1,87 @@ +from typing import Optional + +from langchain.text_splitter import ( + RecursiveCharacterTextSplitter, + CharacterTextSplitter, +) +from langchain_core.documents import Document + +from langflow.interface.custom.custom_component import CustomComponent +from langflow.schema import Record +from langflow.field_typing import Text +from langflow.utils.util import build_loader_repr_from_records, unescape_string + + +class SplitTextComponent(CustomComponent): + display_name: str = "Split Text" + description: str = "Split text into chunks of a specified length." + + def build_config(self): + return { + "texts": { + "display_name": "Texts", + "info": "Texts to split.", + "input_types": ["Text"], + }, + "separators": { + "display_name": "Separators", + "info": 'The characters to split on.\nIf left empty defaults to [" "].', + "is_list": True, + }, + "chunk_size": { + "display_name": "Chunk Size", + "info": "The maximum length of each chunk.", + "field_type": "int", + "value": 1000, + }, + "chunk_overlap": { + "display_name": "Chunk Overlap", + "info": "The amount of overlap between chunks.", + "field_type": "int", + "value": 200, + }, + "recursive": { + "display_name": "Recursive", + }, + "code": {"show": False}, + } + + def build( + self, + texts: list[Text], + separators: Optional[list[str]] = [" "], + chunk_size: Optional[int] = 1000, + chunk_overlap: Optional[int] = 200, + recursive: bool = False, + ) -> list[Record]: + + separators = [unescape_string(x) for x in separators] + + # Make sure chunk_size and chunk_overlap are ints + if isinstance(chunk_size, str): + chunk_size = int(chunk_size) + if isinstance(chunk_overlap, str): + chunk_overlap = int(chunk_overlap) + + if recursive: + splitter = RecursiveCharacterTextSplitter( + separators=separators, + chunk_size=chunk_size, + chunk_overlap=chunk_overlap, + ) + + else: + splitter = CharacterTextSplitter( + separator=separators[0], + chunk_size=chunk_size, + chunk_overlap=chunk_overlap, + ) + + documents = [] + for _text in texts: + # documents.append(_input.to_lc_document()) + documents.append(Document(page_content=_text)) + + records = self.to_records(splitter.split_documents(documents)) + self.status = records + return records From 2b638634876e59ac955e01d8963e5074e7ef92b6 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Sat, 30 Mar 2024 23:07:17 +0200 Subject: [PATCH 1590/1878] disabled size change at IO view --- src/frontend/src/modals/IOModal/index.tsx | 109 +++++++++++----------- 1 file changed, 52 insertions(+), 57 deletions(-) diff --git a/src/frontend/src/modals/IOModal/index.tsx b/src/frontend/src/modals/IOModal/index.tsx index b337b7a7e..42c64d5a4 100644 --- a/src/frontend/src/modals/IOModal/index.tsx +++ b/src/frontend/src/modals/IOModal/index.tsx @@ -106,13 +106,7 @@ export default function IOModal({ return ( )} - {haveChat || selectedViewField ? ( -
- {selectedViewField && ( -
-
- - { - nodes.find((node) => node.id === selectedViewField.id) - ?.data.node.display_name - } -
-
- {inputs.some( - (input) => input.id === selectedViewField.id - ) ? ( - - ) : ( - - )} -
-
- )} +
+ {selectedViewField && (
+
+ + { + nodes.find((node) => node.id === selectedViewField.id) + ?.data.node.display_name + } +
+
+ {inputs.some( + (input) => input.id === selectedViewField.id + ) ? ( + + ) : ( + + )} +
+
+ )} +
+ {haveChat ? ( -
+ ) : ( + + Select an IO component to view + + )}
- ) : ( -
- )} +
From f7342b5be66f8e3e664a50492200a0d3073e6271 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Sat, 30 Mar 2024 23:11:18 +0200 Subject: [PATCH 1591/1878] fixed spacing at required and info --- .../GenericNode/components/parameterComponent/index.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index f2d3a1886..347bbbb20 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -402,9 +402,7 @@ export default function ParameterComponent({ {title} )} - + {required ? "*" : ""}
From a53c81271658ce32612b97cc97a5ed4798993a8e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Sat, 30 Mar 2024 18:12:52 -0300 Subject: [PATCH 1592/1878] Add order parameter to MessageHistoryComponent and MonitorService --- .../base/langflow/components/helpers/MessageHistory.py | 9 +++++++++ src/backend/base/langflow/memory.py | 2 ++ src/backend/base/langflow/services/monitor/service.py | 4 +++- src/backend/base/langflow/services/monitor/utils.py | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/backend/base/langflow/components/helpers/MessageHistory.py b/src/backend/base/langflow/components/helpers/MessageHistory.py index 0a1724267..c36fa4e0e 100644 --- a/src/backend/base/langflow/components/helpers/MessageHistory.py +++ b/src/backend/base/langflow/components/helpers/MessageHistory.py @@ -26,6 +26,12 @@ class MessageHistoryComponent(CustomComponent): "info": "Session ID of the chat history.", "input_types": ["Text"], }, + "order": { + "options": ["Ascending", "Descending"], + "display_name": "Order", + "info": "Order of the messages.", + "advanced": True, + }, } def build( @@ -34,7 +40,9 @@ class MessageHistoryComponent(CustomComponent): sender_name: Optional[str] = None, session_id: Optional[str] = None, n_messages: int = 5, + order: Optional[str] = "Descending", ) -> List[Record]: + order = "DESC" if order == "Descending" else "ASC" if sender == "Machine and User": sender = None messages = get_messages( @@ -42,6 +50,7 @@ class MessageHistoryComponent(CustomComponent): sender_name=sender_name, session_id=session_id, limit=n_messages, + order=order, ) self.status = messages return messages diff --git a/src/backend/base/langflow/memory.py b/src/backend/base/langflow/memory.py index b0ec04f1c..a1c21f243 100644 --- a/src/backend/base/langflow/memory.py +++ b/src/backend/base/langflow/memory.py @@ -12,6 +12,7 @@ def get_messages( sender_name: Optional[str] = None, session_id: Optional[str] = None, order_by: Optional[str] = "timestamp", + order: Optional[str] = "DESC", limit: Optional[int] = None, ): """ @@ -34,6 +35,7 @@ def get_messages( session_id=session_id, order_by=order_by, limit=limit, + order=order, ) records: list[Record] = [] diff --git a/src/backend/base/langflow/services/monitor/service.py b/src/backend/base/langflow/services/monitor/service.py index ecf710eea..68cf839e5 100644 --- a/src/backend/base/langflow/services/monitor/service.py +++ b/src/backend/base/langflow/services/monitor/service.py @@ -113,6 +113,7 @@ class MonitorService(Service): sender_name: Optional[str] = None, session_id: Optional[str] = None, order_by: Optional[str] = "timestamp", + order: Optional[str] = "DESC", limit: Optional[int] = None, ): query = "SELECT sender_name, sender, session_id, message, artifacts, timestamp FROM messages" @@ -128,7 +129,8 @@ class MonitorService(Service): query += " WHERE " + " AND ".join(conditions) if order_by: - query += f" ORDER BY {order_by}" + # Make sure the order is from newest to oldest + query += f" ORDER BY {order_by} {order.upper()}" if limit is not None: query += f" LIMIT {limit}" diff --git a/src/backend/base/langflow/services/monitor/utils.py b/src/backend/base/langflow/services/monitor/utils.py index 1febdd589..a71653e82 100644 --- a/src/backend/base/langflow/services/monitor/utils.py +++ b/src/backend/base/langflow/services/monitor/utils.py @@ -86,7 +86,7 @@ def add_row_to_table( validated_data = model(**monitor_data) # Extract data for the insert statement - validated_dict = validated_data.model_dump(exclude_unset=True) + validated_dict = validated_data.model_dump() keys = [key for key in validated_dict.keys() if key != INDEX_KEY] columns = ", ".join(keys) From e2c9d0b7de9763faad48690e74a5c5f17714c123 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Sat, 30 Mar 2024 18:14:47 -0300 Subject: [PATCH 1593/1878] Update chat input and modal icons --- .../modals/IOModal/components/chatView/chatInput/index.tsx | 2 +- src/frontend/src/modals/IOModal/index.tsx | 4 ++-- src/frontend/src/style/applies.css | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx index 30d609f8c..52af7a987 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx @@ -100,7 +100,7 @@ export default function ChatInput({ /> ) : noInput ? (