diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, World).json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, World).json index c41428891..8e5c0dad0 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, World).json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, World).json @@ -678,7 +678,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json index a341db0f3..972a5c90a 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json @@ -189,13 +189,13 @@ "show": true, "title_case": false, "type": "code", - "value": "import re\n\nfrom langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.io import MessageTextInput, Output\nfrom langflow.schema import Data\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n name = \"URL\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(https?:\\/\\/)?\" # optional protocol\n r\"(www\\.)?\" # optional www\n r\"([a-zA-Z0-9.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,})?\" # top-level domain\n r\"(:\\d+)?\" # optional port\n r\"(\\/[^\\s]*)?$\", # optional path\n re.IGNORECASE,\n )\n\n if not url_regex.match(string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> list[Data]:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(text=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n" + "value": "import re\n\nfrom langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.io import MessageTextInput, Output\nfrom langflow.schema import Data\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n name = \"URL\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, by clicking the '+' button.\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(https?:\\/\\/)?\" # optional protocol\n r\"(www\\.)?\" # optional www\n r\"([a-zA-Z0-9.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,})?\" # top-level domain\n r\"(:\\d+)?\" # optional port\n r\"(\\/[^\\s]*)?$\", # optional path\n re.IGNORECASE,\n )\n\n if not url_regex.match(string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> list[Data]:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(text=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n" }, "urls": { "advanced": false, "display_name": "URLs", "dynamic": false, - "info": "Enter one or more URLs, separated by commas.", + "info": "Enter one or more URLs, by clicking the '+' button.", "input_types": [ "Message" ], @@ -866,7 +866,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Complex Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Complex Agent.json index a6ab3af9c..628ba2045 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Complex Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Complex Agent.json @@ -908,7 +908,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -2033,7 +2035,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -2731,7 +2735,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -3149,7 +3155,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -3592,7 +3600,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -4051,7 +4061,9 @@ "display_name": "SearchAPI API Key", "dynamic": false, "info": "", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json b/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json index 94a094f9d..02a8a5c95 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json @@ -756,7 +756,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Hierarchical Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Hierarchical Agent.json index 3daf51e9e..8a0e18ee2 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Hierarchical Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Hierarchical Agent.json @@ -607,7 +607,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -1752,7 +1754,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -2635,7 +2639,9 @@ "display_name": "SearchAPI API Key", "dynamic": false, "info": "", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json index 9641e99ab..9c29c48fc 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json @@ -536,7 +536,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Sequential Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Sequential Agent.json index ee1986dac..b1a70afc6 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Sequential Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Sequential Agent.json @@ -2054,7 +2054,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -2975,7 +2977,9 @@ "display_name": "SearchAPI API Key", "dynamic": false, "info": "", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json index 399732cb9..d0bbe2ff2 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json @@ -569,7 +569,9 @@ "display_name": "API Endpoint", "dynamic": false, "info": "API endpoint URL for the Astra DB service.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_endpoint", "password": true, @@ -919,7 +921,9 @@ "display_name": "Astra DB Application Token", "dynamic": false, "info": "Authentication token for accessing Astra DB.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "token", "password": true, @@ -1779,7 +1783,9 @@ "display_name": "API Endpoint", "dynamic": false, "info": "API endpoint URL for the Astra DB service.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_endpoint", "password": true, @@ -2129,7 +2135,9 @@ "display_name": "Astra DB Application Token", "dynamic": false, "info": "Authentication token for accessing Astra DB.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "token", "password": true, @@ -2404,7 +2412,9 @@ "display_name": "OpenAI API Base", "dynamic": false, "info": "", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "openai_api_base", "password": true, @@ -2420,7 +2430,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "openai_api_key", "password": true, @@ -2436,7 +2448,9 @@ "display_name": "OpenAI API Type", "dynamic": false, "info": "", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "openai_api_type", "password": true, @@ -2851,7 +2865,9 @@ "display_name": "OpenAI API Base", "dynamic": false, "info": "", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "openai_api_base", "password": true, @@ -2867,7 +2883,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "openai_api_key", "password": true, @@ -2883,7 +2901,9 @@ "display_name": "OpenAI API Type", "dynamic": false, "info": "", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "openai_api_type", "password": true, @@ -3119,7 +3139,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 3485d47bf..e0038e2ae 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -14,7 +14,7 @@ import { LANGFLOW_AUTO_LOGIN_OPTION, } from "./constants/constants"; import { AuthContext } from "./contexts/authContext"; -import { autoLogin } from "./controllers/API"; +import { useAutoLogin } from "./controllers/API/queries/auth"; import { useGetHealthQuery } from "./controllers/API/queries/health"; import { useGetGlobalVariables } from "./controllers/API/queries/variables"; import { useGetVersionQuery } from "./controllers/API/queries/version"; @@ -38,6 +38,8 @@ export default function App() { const dark = useDarkStore((state) => state.dark); const isAuthenticated = useAuthStore((state) => state.isAuthenticated); + const { mutate: mutateAutoLogin } = useAutoLogin(); + useGetVersionQuery(); const cookies = new Cookies(); @@ -61,11 +63,10 @@ export default function App() { }, [dark]); useEffect(() => { - const abortController = new AbortController(); const isLoginPage = location.pathname.includes("login"); - autoLogin(abortController.signal) - .then(async (user) => { + mutateAutoLogin(undefined, { + onSuccess: async (user) => { if (user && user["access_token"]) { user["refresh_token"] = "auto"; login(user["access_token"], "auto"); @@ -74,8 +75,8 @@ export default function App() { setAutoLogin(true); fetchAllData(); } - }) - .catch(async (error) => { + }, + onError: (error) => { if (error.name !== "CanceledError") { setAutoLogin(false); if ( @@ -94,14 +95,8 @@ export default function App() { useFlowsManagerStore.setState({ isLoading: false }); } } - }); - - /* - Abort the request as it isn't needed anymore, the component being - unmounted. It helps avoid, among other things, the well-known "can't - perform a React state update on an unmounted component" warning. - */ - return () => abortController.abort(); + }, + }); }, []); const fetchAllData = async () => { diff --git a/src/frontend/src/components/authGuard/index.tsx b/src/frontend/src/components/authGuard/index.tsx index 039894e5f..8bfacbd6c 100644 --- a/src/frontend/src/components/authGuard/index.tsx +++ b/src/frontend/src/components/authGuard/index.tsx @@ -1,3 +1,4 @@ +import { LANGFLOW_AUTO_LOGIN_OPTION } from "@/constants/constants"; import useAuthStore from "@/stores/authStore"; import { useContext } from "react"; import { AuthContext } from "../../contexts/authContext"; @@ -5,8 +6,9 @@ import { AuthContext } from "../../contexts/authContext"; export const ProtectedRoute = ({ children }) => { const { logout } = useContext(AuthContext); const isAuthenticated = useAuthStore((state) => state.isAuthenticated); + const hasToken = !!localStorage.getItem(LANGFLOW_AUTO_LOGIN_OPTION); - if (!isAuthenticated) { + if (!isAuthenticated && hasToken) { logout(); } else { return children; diff --git a/src/frontend/src/constants/constants.ts b/src/frontend/src/constants/constants.ts index 2a3859cbb..a4d74462c 100644 --- a/src/frontend/src/constants/constants.ts +++ b/src/frontend/src/constants/constants.ts @@ -1,7 +1,6 @@ // src/constants/constants.ts import { languageMap } from "../types/components"; -import { nodeNames } from "../utils/styleUtils"; /** * invalid characters for flow name diff --git a/src/frontend/src/contexts/authContext.tsx b/src/frontend/src/contexts/authContext.tsx index 907ca0fd6..735b912bb 100644 --- a/src/frontend/src/contexts/authContext.tsx +++ b/src/frontend/src/contexts/authContext.tsx @@ -48,6 +48,10 @@ export function AuthProvider({ children }): React.ReactElement { const fetchApiData = useStoreStore((state) => state.fetchApiData); const setAllFlows = useFlowsManagerStore((state) => state.setAllFlows); const setSelectedFolder = useFolderStore((state) => state.setSelectedFolder); + const setIsAuthenticated = useAuthStore((state) => state.setIsAuthenticated); + const setIsAdmin = useAuthStore((state) => state.setIsAdmin); + const setIsLoading = useFlowsManagerStore((state) => state.setIsLoading); + const autoLogin = useAuthStore((state) => state.autoLogin); useEffect(() => { const storedAccessToken = cookies.get(LANGFLOW_ACCESS_TOKEN); @@ -82,26 +86,27 @@ export function AuthProvider({ children }): React.ReactElement { function login(newAccessToken: string, autoLogin: string) { cookies.set(LANGFLOW_AUTO_LOGIN_OPTION, autoLogin, { path: "/" }); setAccessToken(newAccessToken); - useAuthStore.getState().setIsAuthenticated(true); + setIsAuthenticated(true); getUser(); } async function logout() { - if (useAuthStore.getState().autoLogin) { + if (autoLogin) { return; } try { await requestLogout(); cookies.remove(LANGFLOW_API_TOKEN, { path: "/" }); cookies.remove(LANGFLOW_AUTO_LOGIN_OPTION, { path: "/" }); - useAuthStore.getState().setIsAdmin(false); + setIsAdmin(false); setUserData(null); setAccessToken(null); - useAuthStore.getState().setIsAuthenticated(false); + setIsAuthenticated(false); + setIsAuthenticated(false); setAllFlows([]); setSelectedFolder(null); navigate("/login"); - useFlowsManagerStore.setState({ isLoading: false }); + setIsLoading(false); } catch (error) { console.error(error); throw error; diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index 52ca5ba55..039f0a30c 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -349,19 +349,6 @@ export async function uploadFile( return await api.post(`${BASE_URL_API}files/upload/${id}`, formData); } -export async function getProfilePictures(): Promise { - try { - const res = await api.get(`${BASE_URL_API}files/profile_pictures/list`); - - if (res.status === 200) { - return res.data; - } - } catch (error) { - throw error; - } - return null; -} - export async function postCustomComponent( code: string, apiClass: APIClassType, @@ -387,45 +374,6 @@ export async function postCustomComponentUpdate( }); } -export async function onLogin(user: LoginType) { - try { - const response = await api.post( - `${BASE_URL_API}login`, - new URLSearchParams({ - username: user.username, - password: user.password, - }).toString(), - { - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - }, - ); - - if (response.status === 200) { - const data = response?.data; - return data; - } - } catch (error) { - throw error; - } -} - -export async function autoLogin(abortSignal) { - try { - const response = await api.get(`${BASE_URL_API}auto_login`, { - signal: abortSignal, - }); - - if (response.status === 200) { - const data = response?.data; - return data; - } - } catch (error) { - throw error; - } -} - export async function renewAccessToken() { try { return await api.post(`${BASE_URL_API}refresh`); diff --git a/src/frontend/src/controllers/API/queries/auth/use-get-autologin.ts b/src/frontend/src/controllers/API/queries/auth/use-get-autologin.ts index f1f9a63bb..a05311268 100644 --- a/src/frontend/src/controllers/API/queries/auth/use-get-autologin.ts +++ b/src/frontend/src/controllers/API/queries/auth/use-get-autologin.ts @@ -1,20 +1,24 @@ -import { keepPreviousData } from "@tanstack/react-query"; -import { Users, useQueryFunctionType } from "../../../../types/api"; +import { UseMutationResult } from "@tanstack/react-query"; +import { useMutationFunctionType } from "../../../../types/api"; import { api } from "../../api"; import { getURL } from "../../helpers/constants"; import { UseRequestProcessor } from "../../services/request-processor"; -export const useGetAutoLogin: useQueryFunctionType = () => { - const { query } = UseRequestProcessor(); +export const useAutoLogin: useMutationFunctionType = ( + options?, +) => { + const { mutate } = UseRequestProcessor(); - const getIsAutoLogin = async () => { - const response = await api.get(`${getURL("AUTOLOGIN")}`); - return response["data"]; + const autoLoginFn = async (): Promise => { + const res = await api.get(`${getURL("AUTOLOGIN")}`); + return res.data; }; - const queryResult = query(["useGetAutoLogin"], getIsAutoLogin, { - placeholderData: keepPreviousData, - }); + const mutation: UseMutationResult = mutate( + ["useAutoLogin"], + autoLoginFn, + options, + ); - return queryResult; + return mutation; }; diff --git a/src/frontend/src/controllers/API/queries/auth/use-post-login-user.ts b/src/frontend/src/controllers/API/queries/auth/use-post-login-user.ts index 27c1ca5e2..1053a04af 100644 --- a/src/frontend/src/controllers/API/queries/auth/use-post-login-user.ts +++ b/src/frontend/src/controllers/API/queries/auth/use-post-login-user.ts @@ -9,7 +9,7 @@ export const useLoginUser: useMutationFunctionType = ( ) => { const { mutate } = UseRequestProcessor(); - async function updateUser({ password, username }: LoginType): Promise { + async function loginUserFn({ password, username }: LoginType): Promise { const res = await api.post( `${getURL("LOGIN")}`, new URLSearchParams({ @@ -27,7 +27,7 @@ export const useLoginUser: useMutationFunctionType = ( const mutation: UseMutationResult = mutate( ["useLoginUser"], - updateUser, + loginUserFn, options, ); diff --git a/src/frontend/src/pages/AdminPage/LoginPage/index.tsx b/src/frontend/src/pages/AdminPage/LoginPage/index.tsx index e4cccd574..e0119ca6a 100644 --- a/src/frontend/src/pages/AdminPage/LoginPage/index.tsx +++ b/src/frontend/src/pages/AdminPage/LoginPage/index.tsx @@ -1,3 +1,4 @@ +import { useLoginUser } from "@/controllers/API/queries/auth"; import { useGetGlobalVariables } from "@/controllers/API/queries/variables"; import { useContext, useState } from "react"; import { useNavigate } from "react-router-dom"; @@ -6,7 +7,6 @@ import { Input } from "../../../components/ui/input"; import { SIGNIN_ERROR_ALERT } from "../../../constants/alerts_constants"; import { CONTROL_LOGIN_STATE } from "../../../constants/constants"; import { AuthContext } from "../../../contexts/authContext"; -import { onLogin } from "../../../controllers/API"; import useAlertStore from "../../../stores/alertStore"; import { LoginType } from "../../../types/api"; import { @@ -32,28 +32,30 @@ export default function LoginAdminPage() { setInputState((prev) => ({ ...prev, [name]: value })); } + const { mutate } = useLoginUser(); + function signIn() { const user: LoginType = { username: username, password: password, }; - onLogin(user) - .then((user) => { - console.log("admin page"); + mutate(user, { + onSuccess: (res) => { setLoading(true); - login(user.access_token, "login"); + login(res.access_token, "login"); mutateGetGlobalVariables(); navigate("/admin/"); - }) - .catch((error) => { + }, + onError: (error) => { setErrorData({ title: SIGNIN_ERROR_ALERT, list: [error["response"]["data"]["detail"]], }); - }); + }, + }); } return ( diff --git a/src/frontend/src/pages/LoginPage/index.tsx b/src/frontend/src/pages/LoginPage/index.tsx index ea2e0b553..7c8fece04 100644 --- a/src/frontend/src/pages/LoginPage/index.tsx +++ b/src/frontend/src/pages/LoginPage/index.tsx @@ -1,3 +1,4 @@ +import { useLoginUser } from "@/controllers/API/queries/auth"; import * as Form from "@radix-ui/react-form"; import { useContext, useState } from "react"; import { Link, useNavigate } from "react-router-dom"; @@ -7,7 +8,6 @@ import { Input } from "../../components/ui/input"; import { SIGNIN_ERROR_ALERT } from "../../constants/alerts_constants"; import { CONTROL_LOGIN_STATE } from "../../constants/constants"; import { AuthContext } from "../../contexts/authContext"; -import { onLogin } from "../../controllers/API"; import useAlertStore from "../../stores/alertStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore"; import { LoginType } from "../../types/api"; @@ -32,23 +32,28 @@ export default function LoginPage(): JSX.Element { setInputState((prev) => ({ ...prev, [name]: value })); } + const { mutate } = useLoginUser(); + function signIn() { const user: LoginType = { username: username.trim(), password: password.trim(), }; - onLogin(user) - .then((user) => { + + mutate(user, { + onSuccess: (data) => { + console.log("admin page"); setLoading(true); - login(user.access_token, "login"); - navigate("/"); - }) - .catch((error) => { + login(data.access_token, "login"); + navigate("/admin/"); + }, + onError: (error) => { setErrorData({ title: SIGNIN_ERROR_ALERT, list: [error["response"]["data"]["detail"]], }); - }); + }, + }); } return ( diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures.ts b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures.ts deleted file mode 100644 index 684fd5e38..000000000 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures.ts +++ /dev/null @@ -1,25 +0,0 @@ -import axios from "axios"; -import { PROFILE_PICTURES_GET_ERROR_ALERT } from "../../../../../../../../../constants/alerts_constants"; -import { getProfilePictures } from "../../../../../../../../../controllers/API"; - -const useGetProfilePictures = (setErrorData) => { - const handleGetProfilePictures = async () => { - try { - const profilePictures = await getProfilePictures(); - return profilePictures!.files; - } catch (error) { - if (axios.isCancel(error)) { - console.warn("Request canceled: ", error.message); - } else { - setErrorData({ - title: PROFILE_PICTURES_GET_ERROR_ALERT, - list: [(error as any)?.response?.data?.detail], - }); - } - } - }; - - return { handleGetProfilePictures }; -}; - -export default useGetProfilePictures; diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx index 020972b11..2b2c4a489 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx @@ -2,9 +2,9 @@ import { useEffect } from "react"; import { BASE_URL_API } from "../../../../../../../../../constants/constants"; const usePreloadImages = ( - profilePictures?: { [key: string]: string[] }, setImagesLoaded: (value: boolean) => void, loading: boolean, + profilePictures?: { [key: string]: string[] }, ) => { const preloadImages = async (imageUrls) => { return Promise.all( diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx index ed5f2c2c2..32a6057bd 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx @@ -30,7 +30,7 @@ export default function ProfilePictureChooserComponent({ } }, [ref, value]); - usePreloadImages(profilePictures, setImagesLoaded, loading); + usePreloadImages(setImagesLoaded, loading, profilePictures); return (
diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/index.tsx index cd800e2b3..348e556d3 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/index.tsx @@ -1,4 +1,7 @@ -import { ProfilePicturesQueryResponse } from "@/controllers/API/queries/files"; +import { + ProfilePicturesQueryResponse, + useGetProfilePicturesQuery, +} from "@/controllers/API/queries/files"; import * as Form from "@radix-ui/react-form"; import { UseQueryResult } from "@tanstack/react-query"; import { Button } from "../../../../../../components/ui/button"; @@ -27,7 +30,7 @@ const ProfilePictureFormComponent = ({ handleGetProfilePictures, userData, }: ProfilePictureFormComponentProps) => { - const { data: response, isFetching } = handleGetProfilePictures; + const { isLoading, data, isFetching } = useGetProfilePicturesQuery(); return (
((set, get) => ({ isAdmin: false, isAuthenticated: !!cookies.get(LANGFLOW_ACCESS_TOKEN),