Merge branch 'zustand/io/migration' of personal:logspace-ai/langflow into zustand/io/migration

This commit is contained in:
anovazzi1 2024-03-30 17:55:36 -03:00
commit d86ca92b7d
31 changed files with 149 additions and 128 deletions

View file

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

View file

@ -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": {

View file

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

View file

@ -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."

View file

@ -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 {

View file

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

View file

@ -403,7 +403,9 @@ export default function ParameterComponent({
{title}
</span>
)}
<span className={(info === "" ? "" : "ml-1 ") + " text-status-red pl-1"}>
<span
className={(info === "" ? "" : "ml-1 ") + " pl-1 text-status-red"}
>
{required ? "*" : ""}
</span>
<div className="">

View file

@ -345,29 +345,40 @@ export default function GenericNode({
return (
<NodeToolbar>
<NodeToolbarComponent
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={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}
/>
</NodeToolbar>
)
}, [data, deleteNode, takeSnapshot, setNode, setShowNode, handles, showNode, updateNodeCode, isOutdated, selected]);
);
}, [
data,
deleteNode,
takeSnapshot,
setNode,
setShowNode,
handles,
showNode,
updateNodeCode,
isOutdated,
selected,
]);
return (
<>

View file

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

View file

@ -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..."}
<ForwardedIconComponent

View file

@ -43,17 +43,17 @@ export interface ButtonProps
function toTitleCase(text: string) {
return text
.split(' ')
.map(word => 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<HTMLButtonElement, ButtonProps>(
({ 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 (
<Comp
@ -61,7 +61,6 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
ref={ref}
children={newChildren}
{...props}
/>
);
}

View file

@ -18,4 +18,4 @@ export enum BuildStatus {
export enum InputOutput {
INPUT = "input",
OUTPUT = "output",
}
}

View file

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

View file

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

View file

@ -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,

View file

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

View file

@ -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,

View file

@ -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,
@ -315,7 +315,10 @@ export default function IOModal({
className="h-6 w-6"
></IconComponent>
</button>
{selectedViewField.type}
{
nodes.find((node) => node.id === selectedViewField.id)
?.data.node.display_name
}
</div>
<div className="h-full w-full">
{inputs.some(

View file

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

View file

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

View file

@ -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 (

View file

@ -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<HTMLDivElement>(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 (
<div className="h-full w-full" ref={reactFlowWrapper}>
{showCanvas ? (
<div id="react-flow-id" className="h-full w-full">
@ -491,8 +492,7 @@ export default function Page({
</div>
) : (
<></>
)}
)}
</div>
);
}

View file

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

View file

@ -631,22 +631,24 @@ export default function NodeToolbarComponent({
)}
{hasCode && (
<div className="hidden">
{openModal&& <CodeAreaComponent
open={openModal}
setOpen={setOpenModal}
readonly={
data.node?.flow && data.node.template[name].dynamic
? true
: false
}
dynamic={data.node?.template[name].dynamic ?? false}
setNodeClass={handleNodeClass}
nodeClass={data.node}
disabled={false}
value={data.node?.template[name].value ?? ""}
onChange={handleOnNewValue}
id={"code-input-node-toolbar-" + name}
/>}
{openModal && (
<CodeAreaComponent
open={openModal}
setOpen={setOpenModal}
readonly={
data.node?.flow && data.node.template[name].dynamic
? true
: false
}
dynamic={data.node?.template[name].dynamic ?? false}
setNodeClass={handleNodeClass}
nodeClass={data.node}
disabled={false}
value={data.node?.template[name].value ?? ""}
onChange={handleOnNewValue}
id={"code-input-node-toolbar-" + name}
/>
)}
</div>
)}
</span>

View file

@ -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 {
<>
<Header />
<div className="flow-page-positioning">
{currentFlow &&
{currentFlow && (
<div className="flex h-full overflow-hidden">
{!view && <ExtraSidebar />}
<main className="flex flex-1">
@ -32,10 +32,9 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
<Page flow={currentFlow} />
</div>
{!view && <FlowToolbar />}
</main>
</div>
}
)}
<a
target={"_blank"}
href="https://logspace.ai/"

View file

@ -2,22 +2,19 @@ import { Group, ToyBrick } from "lucide-react";
import { useEffect, useState } from "react";
import { Outlet, useLocation, useNavigate } from "react-router-dom";
import DropdownButton from "../../components/DropdownButtonComponent";
import NewFlowCardComponent from "../../modals/NewFlowModal/components/NewFlowCardComponent";
import IconComponent from "../../components/genericIconComponent";
import PageLayout from "../../components/pageLayout";
import SidebarNav from "../../components/sidebarComponent";
import { Button } from "../../components/ui/button";
import UndrawCardComponent from "../../modals/NewFlowModal/components/undrawCards";
import { CONSOLE_ERROR_MSG } from "../../constants/alerts_constants";
import {
MY_COLLECTION_DESC,
USER_PROJECTS_HEADER,
} from "../../constants/constants";
import BaseModal from "../../modals/baseModal";
import NewFlowModal from "../../modals/NewFlowModal";
import useAlertStore from "../../stores/alertStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { downloadFlows } from "../../utils/reactflowUtils";
import NewFlowModal from "../../modals/NewFlowModal";
export default function HomePage(): JSX.Element {
const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow);
const setCurrentFlowId = useFlowsManagerStore(

View file

@ -72,7 +72,7 @@ const useFlowStore = create<FlowStoreType>((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,
@ -529,9 +529,9 @@ const useFlowStore = create<FlowStoreType>((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

View file

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

View file

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

View file

@ -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.