diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 46a2e89d2..467e15ed8 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -9,6 +9,7 @@ import ErrorAlert from "./alerts/error"; import NoticeAlert from "./alerts/notice"; import SuccessAlert from "./alerts/success"; import CrashErrorComponent from "./components/CrashErrorComponent"; +import LoadingComponent from "./components/loadingComponent"; import { alertContext } from "./contexts/alertContext"; import { locationContext } from "./contexts/locationContext"; import { TabsContext } from "./contexts/tabsContext"; @@ -47,10 +48,6 @@ export default function App() { }> >([]); - const isLoginPage = location.pathname.includes("login"); - const isAdminPage = location.pathname.includes("admin"); - const isSignUpPage = location.pathname.includes("signup"); - // Use effect hook to update alertsList when a new alert is added useEffect(() => { // If there is an error alert open with data, add it to the alertsList @@ -138,8 +135,15 @@ export default function App() { }} FallbackComponent={CrashErrorComponent} > - {!isLoginPage && !isSignUpPage &&
} - + {loading ? ( +
+ +
+ ) : ( + <> + + + )}
diff --git a/src/frontend/src/components/EditFlowSettingsComponent/index.tsx b/src/frontend/src/components/EditFlowSettingsComponent/index.tsx index b641be41b..77fd64819 100644 --- a/src/frontend/src/components/EditFlowSettingsComponent/index.tsx +++ b/src/frontend/src/components/EditFlowSettingsComponent/index.tsx @@ -34,6 +34,13 @@ export const EditFlowSettings: React.FC = ({ } else { setIsMaxLength(false); } + if (invalidName !== undefined) { + if (!nameLists.current.includes(value)) { + setInvalidName(false); + } else { + setInvalidName(true); + } + } if (!nameLists.current.includes(value)) { setInvalidName!(false); } else { @@ -43,13 +50,18 @@ export const EditFlowSettings: React.FC = ({ setCurrentName(value); }; - const [desc, setDesc] = useState( - flows.find((flow) => flow.id === tabId)?.description - ); + const [currentName, setCurrentName] = useState(name); + + const [currentDescription, setCurrentDescription] = useState(description); + + useEffect(() => { + setCurrentName(name); + setCurrentDescription(description); + }, [name, description]); const handleDescriptionChange = (event: ChangeEvent) => { - flows.find((flow) => flow.id === tabId)!.description = event.target.value; - setDesc(flows.find((flow) => flow.id === tabId)?.description); + flows.find((f) => f.id === tabId).description = event.target.value; + setCurrentDescription(flows.find((f) => f.id === tabId).description); setDescription(event.target.value); }; diff --git a/src/frontend/src/components/inputComponent/index.tsx b/src/frontend/src/components/inputComponent/index.tsx index 47e04811b..287ceac63 100644 --- a/src/frontend/src/components/inputComponent/index.tsx +++ b/src/frontend/src/components/inputComponent/index.tsx @@ -1,6 +1,7 @@ import * as Form from "@radix-ui/react-form"; import { useEffect, useState } from "react"; import { InputComponentType } from "../../types/components"; +import { handleKeyDown } from "../../utils/reactflowUtils"; import { classNames } from "../../utils/utils"; import { Input } from "../ui/input"; @@ -45,6 +46,9 @@ export default function InputComponent({ onChange={(e) => { onChange(e.target.value); }} + onKeyDown={(e) => { + handleKeyDown(e, value, ""); + }} /> ) : ( @@ -65,6 +69,9 @@ export default function InputComponent({ onChange={(e) => { onChange(e.target.value); }} + onKeyDown={(e) => { + handleKeyDown(e, value, ""); + }} /> )} {password && ( diff --git a/src/frontend/src/constants/constants.ts b/src/frontend/src/constants/constants.ts index 7cc5f0d3a..7f6c7614c 100644 --- a/src/frontend/src/constants/constants.ts +++ b/src/frontend/src/constants/constants.ts @@ -509,6 +509,9 @@ export const URL_EXCLUDED_FROM_ERROR_RETRIES = [ "/api/v1/custom_component", "/api/v1/validate/prompt", ]; + +export const skipNodeUpdate = ["CustomComponent"]; + export const CONTROL_INPUT_STATE = { password: "", cnfPassword: "", diff --git a/src/frontend/src/contexts/typesContext.tsx b/src/frontend/src/contexts/typesContext.tsx index 936f6105e..52a5eea72 100644 --- a/src/frontend/src/contexts/typesContext.tsx +++ b/src/frontend/src/contexts/typesContext.tsx @@ -1,4 +1,10 @@ -import { createContext, ReactNode, useEffect, useState } from "react"; +import { + createContext, + ReactNode, + useContext, + useEffect, + useState, +} from "react"; import { Node, ReactFlowInstance } from "reactflow"; import { getAll } from "../controllers/API"; import { APIKindType } from "../types/api"; diff --git a/src/frontend/src/modals/exportModal/index.tsx b/src/frontend/src/modals/exportModal/index.tsx index a49d5e9a9..c296a1e2c 100644 --- a/src/frontend/src/modals/exportModal/index.tsx +++ b/src/frontend/src/modals/exportModal/index.tsx @@ -1,4 +1,4 @@ -import { ReactNode, forwardRef, useContext, useState } from "react"; +import { ReactNode, forwardRef, useContext, useEffect, useState } from "react"; import EditFlowSettings from "../../components/EditFlowSettingsComponent"; import IconComponent from "../../components/genericIconComponent"; import { Button } from "../../components/ui/button"; @@ -10,17 +10,17 @@ import BaseModal from "../baseModal"; const ExportModal = forwardRef( (props: { children: ReactNode }, ref): JSX.Element => { - const { flows, tabId, updateFlow, downloadFlow, saveFlow } = - useContext(TabsContext); + const { flows, tabId, updateFlow, downloadFlow } = useContext(TabsContext); const [checked, setChecked] = useState(false); - const [name, setName] = useState( - flows.find((flow) => flow.id === tabId)?.name - ); - const [invalidName, setInvalidName] = useState(false); - const [description, setDescription] = useState( - flows.find((flow) => flow.id === tabId)?.description - ); + const flow = flows.find((f) => f.id === tabId); + useEffect(() => { + setName(flow.name); + setDescription(flow.description); + }, [flow.name, flow.description]); + const [name, setName] = useState(flow.name); + const [description, setDescription] = useState(flow.description); const [open, setOpen] = useState(false); + return ( {props.children} @@ -34,19 +34,18 @@ const ExportModal = forwardRef(
{ + onCheckedChange={(event: boolean) => { setChecked(event); }} /> diff --git a/src/frontend/src/modals/flowSettingsModal/index.tsx b/src/frontend/src/modals/flowSettingsModal/index.tsx index 2faa5e204..075f0a651 100644 --- a/src/frontend/src/modals/flowSettingsModal/index.tsx +++ b/src/frontend/src/modals/flowSettingsModal/index.tsx @@ -1,4 +1,4 @@ -import { useContext, useState } from "react"; +import { useContext, useEffect, useState } from "react"; import EditFlowSettings from "../../components/EditFlowSettingsComponent"; import IconComponent from "../../components/genericIconComponent"; import { Button } from "../../components/ui/button"; @@ -12,16 +12,15 @@ export default function FlowSettingsModal({ open, setOpen, }: FlowSettingsPropsType): JSX.Element { - const { setErrorData, setSuccessData } = useContext(alertContext); - const ref = useRef(); + const { setSuccessData } = useContext(alertContext); const { flows, tabId, updateFlow, saveFlow } = useContext(TabsContext); - const maxLength = 50; - const [name, setName] = useState( - flows.find((flow) => flow.id === tabId)!.name - ); - const [description, setDescription] = useState( - flows.find((flow) => flow.id === tabId)!.description - ); + const flow = flows.find((f) => f.id === tabId); + useEffect(() => { + setName(flow.name); + setDescription(flow.description); + }, [flow.name, flow.description]); + const [name, setName] = useState(flow.name); + const [description, setDescription] = useState(flow.description); const [invalidName, setInvalidName] = useState(false); function handleClick(): void { diff --git a/src/frontend/src/modals/genericModal/index.tsx b/src/frontend/src/modals/genericModal/index.tsx index 29c2df909..9498bc941 100644 --- a/src/frontend/src/modals/genericModal/index.tsx +++ b/src/frontend/src/modals/genericModal/index.tsx @@ -16,6 +16,7 @@ import { TypeModal } from "../../constants/enums"; import { alertContext } from "../../contexts/alertContext"; import { postValidatePrompt } from "../../controllers/API"; import { genericModalPropsType } from "../../types/components"; +import { handleKeyDown } from "../../utils/reactflowUtils"; import { classNames, getRandomKeyByssmm, diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index 1f031d2ef..0a147373a 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -44,7 +44,13 @@ const nodeTypes = { genericNode: GenericNode, }; -export default function Page({ flow }: { flow: FlowType }): JSX.Element { +export default function Page({ + flow, + view, +}: { + flow: FlowType; + view?: boolean; +}): JSX.Element { let { updateFlow, uploadFlow, @@ -424,7 +430,9 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element { > )} - + {!view && ( + + )}
) : ( <> diff --git a/src/frontend/src/pages/FlowPage/index.tsx b/src/frontend/src/pages/FlowPage/index.tsx index c8231cfd2..e9e5c2f34 100644 --- a/src/frontend/src/pages/FlowPage/index.tsx +++ b/src/frontend/src/pages/FlowPage/index.tsx @@ -1,5 +1,6 @@ import { useContext, useEffect, useState } from "react"; import { useParams } from "react-router-dom"; +import Header from "../../components/headerComponent"; import { TabsContext } from "../../contexts/tabsContext"; import { getVersion } from "../../controllers/API"; import Page from "./components/PageComponent"; @@ -22,20 +23,23 @@ export default function FlowPage(): JSX.Element { }, []); return ( -
- {flows.length > 0 && - tabId !== "" && - flows.findIndex((flow) => flow.id === tabId) !== -1 && ( - flow.id === tabId)!} /> - )} - - {version &&
⛓️ Langflow v{version}
} -
Created by Logspace
-
-
+ <> +
+
+ {flows.length > 0 && + tabId !== "" && + flows.findIndex((flow) => flow.id === tabId) !== -1 && ( + flow.id === tabId)!} /> + )} + + {version &&
⛓️ Langflow v{version}
} +
Created by Logspace
+
+
+ ); } diff --git a/src/frontend/src/pages/MainPage/index.tsx b/src/frontend/src/pages/MainPage/index.tsx index e5394280b..67412401a 100644 --- a/src/frontend/src/pages/MainPage/index.tsx +++ b/src/frontend/src/pages/MainPage/index.tsx @@ -1,5 +1,6 @@ import { useContext, useEffect } from "react"; -import { useNavigate } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; +import { CardComponent } from "../../components/cardComponent"; import IconComponent from "../../components/genericIconComponent"; import Header from "../../components/headerComponent"; import { Button } from "../../components/ui/button"; @@ -47,7 +48,7 @@ export default function HomePage(): JSX.Element { - - +
+ {flows.map((flow, idx) => ( + + + + } + onDelete={() => { + removeFlow(flow.id); + }} + /> + ))}
diff --git a/src/frontend/src/routes.tsx b/src/frontend/src/routes.tsx index 2fd820862..0d023e360 100644 --- a/src/frontend/src/routes.tsx +++ b/src/frontend/src/routes.tsx @@ -4,6 +4,7 @@ import LoginAdminPage from "./pages/AdminPage/LoginPage"; import CommunityPage from "./pages/CommunityPage"; import FlowPage from "./pages/FlowPage"; import HomePage from "./pages/MainPage"; +import ViewPage from "./pages/ViewPage"; import DeleteAccountPage from "./pages/deleteAccountPage"; import LoginPage from "./pages/loginPage"; diff --git a/src/frontend/src/types/typesContext/index.ts b/src/frontend/src/types/typesContext/index.ts index 5c5d3daa6..9e57822b9 100644 --- a/src/frontend/src/types/typesContext/index.ts +++ b/src/frontend/src/types/typesContext/index.ts @@ -37,6 +37,8 @@ export type alertContextType = { pushNotificationList: (Object: AlertItemType) => void; clearNotificationList: () => void; removeFromNotificationList: (index: string) => void; + loading: boolean; + setLoading: (newState: boolean) => void; }; export type darkContextType = { diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts index 9c4811178..13c3973f1 100644 --- a/src/frontend/src/utils/reactflowUtils.ts +++ b/src/frontend/src/utils/reactflowUtils.ts @@ -5,6 +5,7 @@ import { ReactFlowInstance, ReactFlowJsonObject, } from "reactflow"; +import { specialCharsRegex } from "../constants/constants"; import { APITemplateType } from "../types/api"; import { FlowType, NodeType } from "../types/flow"; import { cleanEdgesType } from "../types/utils/reactflowUtils";