From bc50e010d4b88dc15c390b05aa74402c3cb8d101 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:43:35 -0300 Subject: [PATCH 01/22] feat: Add Case component to App for conditional rendering --- src/frontend/src/App.tsx | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 849244999..720ffb6b2 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -18,21 +18,21 @@ import { autoLogin, getGlobalVariables, getHealth } from "./controllers/API"; import { setupAxiosDefaults } from "./controllers/API/utils"; import useTrackLastVisitedPath from "./hooks/use-track-last-visited-path"; import Router from "./routes"; +import { Case } from "./shared/components/caseComponent"; import useAlertStore from "./stores/alertStore"; import { useDarkStore } from "./stores/darkStore"; import useFlowsManagerStore from "./stores/flowsManagerStore"; import { useFolderStore } from "./stores/foldersStore"; import { useGlobalVariablesStore } from "./stores/globalVariablesStore/globalVariables"; import { useStoreStore } from "./stores/storeStore"; -import { useTypesStore } from "./stores/typesStore"; export default function App() { useTrackLastVisitedPath(); const removeFromTempNotificationList = useAlertStore( - (state) => state.removeFromTempNotificationList + (state) => state.removeFromTempNotificationList, ); const tempNotificationList = useAlertStore( - (state) => state.tempNotificationList + (state) => state.tempNotificationList, ); const [fetchError, setFetchError] = useState(false); const isLoading = useFlowsManagerStore((state) => state.isLoading); @@ -43,21 +43,18 @@ export default function App() { const { isAuthenticated, login, setUserData, setAutoLogin, getUser } = useContext(AuthContext); - const refreshFlows = useFlowsManagerStore((state) => state.refreshFlows); const setLoading = useAlertStore((state) => state.setLoading); const fetchApiData = useStoreStore((state) => state.fetchApiData); - const getTypes = useTypesStore((state) => state.getTypes); const refreshVersion = useDarkStore((state) => state.refreshVersion); const refreshStars = useDarkStore((state) => state.refreshStars); const setGlobalVariables = useGlobalVariablesStore( - (state) => state.setGlobalVariables + (state) => state.setGlobalVariables, ); const checkHasStore = useStoreStore((state) => state.checkHasStore); const navigate = useNavigate(); const dark = useDarkStore((state) => state.dark); - const getFoldersApi = useFolderStore((state) => state.getFoldersApi); - const loadingFolders = useFolderStore((state) => state.loading); + const isLoadingFolders = useFolderStore((state) => state.isLoadingFolders); const [isLoadingHealth, setIsLoadingHealth] = useState(false); @@ -115,13 +112,13 @@ export default function App() { if (isAuthenticated) { try { await setupAxiosDefaults(); - await getFoldersApi(); - await getTypes(); - await refreshFlows(); + const res = await getGlobalVariables(); setGlobalVariables(res); + checkHasStore(); fetchApiData(); + resolve(); } catch (error) { console.error("Failed to fetch data:", error); @@ -174,6 +171,8 @@ export default function App() { } }; + const isLoadingApplication = isLoading || isLoadingFolders; + return ( //need parent component with width and height
@@ -196,15 +195,15 @@ export default function App() { > } - {isLoading || loadingFolders ? ( +
- ) : ( - <> - - - )} +
+ + + +
From 75c13f4f20e9d17e48a222c9f183c391babf7705 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:44:06 -0300 Subject: [PATCH 02/22] chore: Refactor loadingFolders variable name in SidebarNav component --- src/frontend/src/components/sidebarComponent/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/components/sidebarComponent/index.tsx b/src/frontend/src/components/sidebarComponent/index.tsx index efec5da1e..8cdbe5907 100644 --- a/src/frontend/src/components/sidebarComponent/index.tsx +++ b/src/frontend/src/components/sidebarComponent/index.tsx @@ -28,7 +28,7 @@ export default function SidebarNav({ }: SidebarNavProps) { const location = useLocation(); const pathname = location.pathname; - const loadingFolders = useFolderStore((state) => state.loading); + const loadingFolders = useFolderStore((state) => state.isLoadingFolders); const folders = useFolderStore((state) => state.folders); const pathValues = ["folder", "components", "flows", "all"]; From 0bbecc9bab4c428818021d99b5ae138494ecec96 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:44:12 -0300 Subject: [PATCH 03/22] refactor: Refresh folders after adding a new folder in SideBarFoldersButtonsComponent --- .../components/sideBarFolderButtons/index.tsx | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/frontend/src/components/sidebarComponent/components/sideBarFolderButtons/index.tsx b/src/frontend/src/components/sidebarComponent/components/sideBarFolderButtons/index.tsx index 234eb9304..1b538ba20 100644 --- a/src/frontend/src/components/sidebarComponent/components/sideBarFolderButtons/index.tsx +++ b/src/frontend/src/components/sidebarComponent/components/sideBarFolderButtons/index.tsx @@ -31,14 +31,14 @@ const SideBarFoldersButtonsComponent = ({ const [foldersNames, setFoldersNames] = useState({}); const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); const [editFolders, setEditFolderName] = useState( - folders.map((obj) => ({ name: obj.name, edit: false })) + folders.map((obj) => ({ name: obj.name, edit: false })), ); const uploadFolder = useFolderStore((state) => state.uploadFolder); const currentFolder = pathname.split("/"); const urlWithoutPath = pathname.split("/").length < 4; const myCollectionId = useFolderStore((state) => state.myCollectionId); - const getFoldersApi = useFolderStore((state) => state.getFoldersApi); const folderIdDragging = useFolderStore((state) => state.folderIdDragging); + const refreshFolders = useFolderStore((state) => state.refreshFolders); const checkPathName = (itemId: string) => { if (urlWithoutPath && itemId === myCollectionId) { @@ -58,7 +58,7 @@ const SideBarFoldersButtonsComponent = ({ const { dragOver, dragEnter, dragLeave, onDrop } = useFileDrop( folderId, - handleFolderChange + handleFolderChange, ); const handleUploadFlowsToFolder = () => { @@ -85,8 +85,8 @@ const SideBarFoldersButtonsComponent = ({ function addNewFolder() { addFolder({ name: "New Folder", parent_id: null, description: "" }).then( (res) => { - getFoldersApi(true); - } + refreshFolders(); + }, ); } @@ -132,7 +132,7 @@ const SideBarFoldersButtonsComponent = ({ <> {folders.map((item, index) => { const editFolderName = editFolders?.filter( - (folder) => folder.name === item.name + (folder) => folder.name === item.name, )[0]; return (
handleChangeFolder!(item.id!)} > @@ -218,7 +218,7 @@ const SideBarFoldersButtonsComponent = ({ folders.map((obj) => ({ name: obj.name, edit: false, - })) + })), ); } if (e.key === "Enter") { @@ -251,10 +251,10 @@ const SideBarFoldersButtonsComponent = ({ }; const updatedFolder = await updateFolder( body, - item.id! + item.id!, ); const updateFolders = folders.filter( - (f) => f.name !== item.name + (f) => f.name !== item.name, ); setFolders([...updateFolders, updatedFolder]); setFoldersNames({}); @@ -262,7 +262,7 @@ const SideBarFoldersButtonsComponent = ({ folders.map((obj) => ({ name: obj.name, edit: false, - })) + })), ); } else { setFoldersNames((old) => ({ From 9cd3bd751e1e93fad764775e91178303e57be7b2 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:44:21 -0300 Subject: [PATCH 04/22] chore: Update use-on-file-drop.tsx to use refreshFolders instead of getFoldersApi --- .../sidebarComponent/hooks/use-on-file-drop.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx b/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx index f10733468..c75bf4bec 100644 --- a/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx +++ b/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx @@ -12,11 +12,11 @@ import { addVersionToDuplicates } from "../../../utils/reactflowUtils"; const useFileDrop = (folderId, folderChangeCallback) => { const setFolderDragging = useFolderStore((state) => state.setFolderDragging); const setFolderIdDragging = useFolderStore( - (state) => state.setFolderIdDragging + (state) => state.setFolderIdDragging, ); const setErrorData = useAlertStore((state) => state.setErrorData); - const getFoldersApi = useFolderStore((state) => state.getFoldersApi); + const refreshFolders = useFolderStore((state) => state.refreshFolders); const flows = useFlowsManagerStore((state) => state.flows); const triggerFolderChange = (folderId) => { @@ -45,7 +45,7 @@ const useFileDrop = (folderId, folderChangeCallback) => { | React.DragEvent | React.DragEvent | React.DragEvent, - folderId: string + folderId: string, ) => { e.preventDefault(); @@ -60,7 +60,7 @@ const useFileDrop = (folderId, folderChangeCallback) => { | React.DragEvent | React.DragEvent | React.DragEvent, - folderId: string + folderId: string, ) => { if (e.dataTransfer.types.some((types) => types === "Files")) { setFolderDragging(true); @@ -73,7 +73,7 @@ const useFileDrop = (folderId, folderChangeCallback) => { e: | React.DragEvent | React.DragEvent - | React.DragEvent + | React.DragEvent, ) => { e.preventDefault(); if (e.target === e.currentTarget) { @@ -87,7 +87,7 @@ const useFileDrop = (folderId, folderChangeCallback) => { | React.DragEvent | React.DragEvent | React.DragEvent, - folderId: string + folderId: string, ) => { if (e?.dataTransfer?.getData("flow")) { const data = JSON.parse(e?.dataTransfer?.getData("flow")); @@ -118,7 +118,7 @@ const useFileDrop = (folderId, folderChangeCallback) => { setFolderIdDragging(""); updateFlowInDatabase(updatedFlow).then(() => { - getFoldersApi(true); + refreshFolders(); triggerFolderChange(folderId); }); }; @@ -129,7 +129,7 @@ const useFileDrop = (folderId, folderChangeCallback) => { setFolderDragging(false); setFolderIdDragging(""); uploadFlowsFromFolders(formData).then(() => { - getFoldersApi(true); + refreshFolders(); triggerFolderChange(folderId); }); }; From 8980b66bec682933baefc5e407d1e44b30c3a1fd Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:44:28 -0300 Subject: [PATCH 05/22] refactor: Update TableComponent to use optional chaining for hiding overlay --- src/frontend/src/components/tableComponent/index.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/frontend/src/components/tableComponent/index.tsx b/src/frontend/src/components/tableComponent/index.tsx index 126d4f3f2..e956d8795 100644 --- a/src/frontend/src/components/tableComponent/index.tsx +++ b/src/frontend/src/components/tableComponent/index.tsx @@ -35,7 +35,7 @@ const TableComponent = forwardRef< alertDescription = DEFAULT_TABLE_ALERT_MSG, ...props }, - ref + ref, ) => { let colDef = props.columnDefs.map((col, index) => { let newCol = { @@ -105,13 +105,13 @@ const TableComponent = forwardRef< } }, 50); setTimeout(() => { - realRef.current.api.hideOverlay(); + realRef?.current?.api?.hideOverlay(); }, 1000); if (props.onGridReady) props.onGridReady(params); }; const onColumnMoved = (params) => { const updatedColumnDefs = makeLastColumnNonResizable( - params.columnApi.getAllGridColumns().map((col) => col.getColDef()) + params.columnApi.getAllGridColumns().map((col) => col.getColDef()), ); params.api.setGridOption("columnDefs", updatedColumnDefs); if (props.onColumnMoved) props.onColumnMoved(params); @@ -135,7 +135,7 @@ const TableComponent = forwardRef< className={cn( dark ? "ag-theme-quartz-dark" : "ag-theme-quartz", "ag-theme-shadcn flex h-full flex-col", - "relative" + "relative", )} // applying the grid theme > source.includes("column"))) { localStorage.setItem( storeReference, - JSON.stringify(realRef.current?.api?.getColumnState()) + JSON.stringify(realRef.current?.api?.getColumnState()), ); setColumnStateChange(true); } @@ -175,7 +175,7 @@ const TableComponent = forwardRef< )}
); - } + }, ); export default TableComponent; From 4358ff52554e62beda6b288713189ae466d178e5 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:44:36 -0300 Subject: [PATCH 06/22] chore: Update authContext to useFolderStore for getting folders --- src/frontend/src/contexts/authContext.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/frontend/src/contexts/authContext.tsx b/src/frontend/src/contexts/authContext.tsx index 1817447f1..bd5c2d02c 100644 --- a/src/frontend/src/contexts/authContext.tsx +++ b/src/frontend/src/contexts/authContext.tsx @@ -3,6 +3,7 @@ import { useNavigate } from "react-router-dom"; import Cookies from "universal-cookie"; import { getLoggedUser, requestLogout } from "../controllers/API"; import useAlertStore from "../stores/alertStore"; +import { useFolderStore } from "../stores/foldersStore"; import { Users } from "../types/api"; import { AuthContextType } from "../types/contexts/auth"; @@ -30,19 +31,20 @@ export function AuthProvider({ children }): React.ReactElement { const navigate = useNavigate(); const cookies = new Cookies(); const [accessToken, setAccessToken] = useState( - cookies.get("access_token_lf") ?? null + cookies.get("access_token_lf") ?? null, ); const [isAuthenticated, setIsAuthenticated] = useState( - !!cookies.get("access_token_lf") + !!cookies.get("access_token_lf"), ); const [isAdmin, setIsAdmin] = useState(false); const [userData, setUserData] = useState(null); const [autoLogin, setAutoLogin] = useState(false); const setLoading = useAlertStore((state) => state.setLoading); const [apiKey, setApiKey] = useState( - cookies.get("apikey_tkn_lflw") + cookies.get("apikey_tkn_lflw"), ); - // const getFoldersApi = useFolderStore((state) => state.getFoldersApi); + + const getFoldersApi = useFolderStore((state) => state.getFoldersApi); useEffect(() => { const storedAccessToken = cookies.get("access_token_lf"); @@ -64,7 +66,8 @@ export function AuthProvider({ children }): React.ReactElement { setUserData(user); const isSuperUser = user!.is_superuser; setIsAdmin(isSuperUser); - // await getFoldersApi(true); + + getFoldersApi(true, true); }) .catch((error) => { setLoading(false); From b9e1a3c0c55fb6a1937499b6e3aa6dffdcd30f54 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:44:46 -0300 Subject: [PATCH 07/22] fix: Handle duplicate requests in ApiInterceptor --- src/frontend/src/controllers/API/api.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/frontend/src/controllers/API/api.tsx b/src/frontend/src/controllers/API/api.tsx index 2a305cf5a..0ac3efa6b 100644 --- a/src/frontend/src/controllers/API/api.tsx +++ b/src/frontend/src/controllers/API/api.tsx @@ -48,7 +48,7 @@ function ApiInterceptor() { } await clearBuildVerticesState(error); return Promise.reject(error); - } + }, ); const isAuthorizedURL = (url) => { @@ -65,10 +65,10 @@ function ApiInterceptor() { const parsedURL = new URL(url); const isDomainAllowed = authorizedDomains.some( - (domain) => parsedURL.origin === new URL(domain).origin + (domain) => parsedURL.origin === new URL(domain).origin, ); const isEndpointAllowed = authorizedEndpoints.some((endpoint) => - parsedURL.pathname.includes(endpoint) + parsedURL.pathname.includes(endpoint), ); return isDomainAllowed || isEndpointAllowed; @@ -87,6 +87,7 @@ function ApiInterceptor() { if (!checkRequest) { controller.abort("Duplicate Request"); + console.error("Duplicate Request"); } const accessToken = cookies.get("access_token_lf"); @@ -101,7 +102,7 @@ function ApiInterceptor() { }, (error) => { return Promise.reject(error); - } + }, ); return () => { @@ -133,7 +134,7 @@ function ApiInterceptor() { if (error?.config?.headers) { delete error.config.headers["Authorization"]; error.config.headers["Authorization"] = `Bearer ${cookies.get( - "access_token_lf" + "access_token_lf", )}`; const response = await axios.request(error.config); return response; From a49cd49eee35f310e26059695f1e0b3481898c87 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:45:02 -0300 Subject: [PATCH 08/22] refactor: Remove console.log statement in getMessagesTable function --- src/frontend/src/controllers/API/index.ts | 54 +++++++++++------------ 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index 07a9cd06d..104b815b0 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -63,7 +63,7 @@ export async function sendAll(data: sendAllProps) { } export async function postValidateCode( - code: string + code: string, ): Promise> { return await api.post(`${BASE_URL_API}validate/code`, { code }); } @@ -78,7 +78,7 @@ export async function postValidateCode( export async function postValidatePrompt( name: string, template: string, - frontend_node: APIClassType + frontend_node: APIClassType, ): Promise> { return api.post(`${BASE_URL_API}validate/prompt`, { name, @@ -151,7 +151,7 @@ export async function saveFlowToDatabase(newFlow: { * @throws Will throw an error if the update fails. */ export async function updateFlowInDatabase( - updatedFlow: FlowType + updatedFlow: FlowType, ): Promise { try { const response = await api.patch(`${BASE_URL_API}flows/${updatedFlow.id}`, { @@ -329,7 +329,7 @@ export async function getHealth() { * */ export async function getBuildStatus( - flowId: string + flowId: string, ): Promise> { return await api.get(`${BASE_URL_API}build/${flowId}/status`); } @@ -342,7 +342,7 @@ export async function getBuildStatus( * */ export async function postBuildInit( - flow: FlowType + flow: FlowType, ): Promise> { return await api.post(`${BASE_URL_API}build/init/${flow.id}`, flow); } @@ -358,7 +358,7 @@ export async function postBuildInit( */ export async function uploadFile( file: File, - id: string + id: string, ): Promise> { const formData = new FormData(); formData.append("file", file); @@ -380,7 +380,7 @@ export async function getProfilePictures(): Promise> { // let template = apiClass.template; return await api.post(`${BASE_URL_API}custom_component`, { @@ -393,7 +393,7 @@ export async function postCustomComponentUpdate( code: string, template: APITemplateType, field: string, - field_value: any + field_value: any, ): Promise> { return await api.post(`${BASE_URL_API}custom_component/update`, { code, @@ -415,7 +415,7 @@ export async function onLogin(user: LoginType) { headers: { "Content-Type": "application/x-www-form-urlencoded", }, - } + }, ); if (response.status === 200) { @@ -477,11 +477,11 @@ export async function addUser(user: UserInputType): Promise> { export async function getUsersPage( skip: number, - limit: number + limit: number, ): Promise> { try { const res = await api.get( - `${BASE_URL_API}users/?skip=${skip}&limit=${limit}` + `${BASE_URL_API}users/?skip=${skip}&limit=${limit}`, ); if (res.status === 200) { return res.data; @@ -518,7 +518,7 @@ export async function resetPassword(user_id: string, user: resetPasswordType) { try { const res = await api.patch( `${BASE_URL_API}users/${user_id}/reset-password`, - user + user, ); if (res.status === 200) { return res.data; @@ -592,7 +592,7 @@ export async function saveFlowStore( last_tested_version?: string; }, tags: string[], - publicFlow = false + publicFlow = false, ): Promise { try { const response = await api.post(`${BASE_URL_API}store/components/`, { @@ -721,7 +721,7 @@ export async function postStoreComponents(component: Component) { export async function getComponent(component_id: string) { try { const res = await api.get( - `${BASE_URL_API}store/components/${component_id}` + `${BASE_URL_API}store/components/${component_id}`, ); if (res.status === 200) { return res.data; @@ -736,7 +736,7 @@ export async function searchComponent( page?: number | null, limit?: number | null, status?: string | null, - tags?: string[] + tags?: string[], ): Promise { try { let url = `${BASE_URL_API}store/components/`; @@ -848,7 +848,7 @@ export async function updateFlowStore( }, tags: string[], publicFlow = false, - id: string + id: string, ): Promise { try { const response = await api.patch(`${BASE_URL_API}store/components/${id}`, { @@ -932,7 +932,7 @@ export async function deleteGlobalVariable(id: string) { export async function updateGlobalVariable( name: string, value: string, - id: string + id: string, ) { try { const response = api.patch(`${BASE_URL_API}variables/${id}`, { @@ -951,7 +951,7 @@ export async function getVerticesOrder( startNodeId?: string | null, stopNodeId?: string | null, nodes?: Node[], - Edges?: Edge[] + Edges?: Edge[], ): Promise> { // nodeId is optional and is a query parameter // if nodeId is not provided, the API will return all vertices @@ -971,7 +971,7 @@ export async function getVerticesOrder( return await api.post( `${BASE_URL_API}build/${flowId}/vertices`, data, - config + config, ); } @@ -979,7 +979,7 @@ export async function postBuildVertex( flowId: string, vertexId: string, input_value: string, - files?: string[] + files?: string[], ): Promise> { // input_value is optional and is a query parameter let data = {}; @@ -991,7 +991,7 @@ export async function postBuildVertex( } return await api.post( `${BASE_URL_API}build/${flowId}/vertices/${vertexId}`, - data + data, ); } @@ -1015,7 +1015,7 @@ export async function getFlowPool({ } export async function deleteFlowPool( - flowId: string + flowId: string, ): Promise> { const config = {}; config["params"] = { flow_id: flowId }; @@ -1029,7 +1029,7 @@ export async function deleteFlowPool( * @returns A promise that resolves to an array of AxiosResponse objects representing the delete responses. */ export async function multipleDeleteFlowsComponents( - flowIds: string[] + flowIds: string[], ): Promise[]> { const batches: string[][] = []; @@ -1052,7 +1052,7 @@ export async function multipleDeleteFlowsComponents( // Execute all delete requests const responses: Promise>[] = batches.map((batch) => - deleteBatch(batch) + deleteBatch(batch), ); // Return the responses after all requests are completed @@ -1062,7 +1062,7 @@ export async function multipleDeleteFlowsComponents( export async function getTransactionTable( id: string, mode: "intersection" | "union", - params = {} + params = {}, ): Promise<{ rows: Array; columns: Array }> { const config = {}; config["params"] = { flow_id: id }; @@ -1078,7 +1078,7 @@ export async function getMessagesTable( mode: "intersection" | "union", id?: string, excludedFields?: string[], - params = {} + params = {}, ): Promise<{ rows: Array; columns: Array }> { const config = {}; if (id) { @@ -1091,8 +1091,6 @@ export async function getMessagesTable( const rowsOrganized = rows.data; - console.log(rowsOrganized); - const columns = extractColumnsFromRows(rowsOrganized, mode, excludedFields); const sessions = new Set(); rowsOrganized.forEach((row) => { From e66286662e7ec990146b9c3ab94e2307057d6615 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:45:09 -0300 Subject: [PATCH 09/22] refactor: Improve duplicate request handling in checkDuplicateRequestAndStoreRequest function --- .../controllers/API/helpers/check-duplicate-requests.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts b/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts index 6486de541..85c6608ac 100644 --- a/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts +++ b/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts @@ -4,11 +4,12 @@ export function checkDuplicateRequestAndStoreRequest(config) { const lastUrl = localStorage.getItem("lastUrlCalled"); const lastMethodCalled = localStorage.getItem("lastMethodCalled"); const lastRequestTime = localStorage.getItem("lastRequestTime"); + const lastCurrentUrl = localStorage.getItem("lastCurrentUrl"); + const currentUrl = window.location.pathname; const currentTime = Date.now(); - const isContained = AUTHORIZED_DUPLICATE_REQUESTS.some((request) => - config?.url!.includes(request) + config?.url!.includes(request), ); if ( @@ -17,7 +18,8 @@ export function checkDuplicateRequestAndStoreRequest(config) { lastMethodCalled === config.method && lastMethodCalled === "get" && // Assuming you want to check only for GET requests lastRequestTime && - currentTime - parseInt(lastRequestTime, 10) < 800 + currentTime - parseInt(lastRequestTime, 10) < 300 && + lastCurrentUrl === currentUrl ) { return false; } @@ -25,6 +27,7 @@ export function checkDuplicateRequestAndStoreRequest(config) { localStorage.setItem("lastUrlCalled", config.url ?? ""); localStorage.setItem("lastMethodCalled", config.method ?? ""); localStorage.setItem("lastRequestTime", currentTime.toString()); + localStorage.setItem("lastCurrentUrl", currentUrl); return true; } From 68201bb0d500e95e48c1962fc7f842e179c8ac45 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:45:16 -0300 Subject: [PATCH 10/22] feat: Add setLoading to LoginAdminPage for displaying loading state during login --- src/frontend/src/pages/AdminPage/LoginPage/index.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/frontend/src/pages/AdminPage/LoginPage/index.tsx b/src/frontend/src/pages/AdminPage/LoginPage/index.tsx index b1772baa5..0c7e073df 100644 --- a/src/frontend/src/pages/AdminPage/LoginPage/index.tsx +++ b/src/frontend/src/pages/AdminPage/LoginPage/index.tsx @@ -19,6 +19,7 @@ export default function LoginAdminPage() { const [inputState, setInputState] = useState(CONTROL_LOGIN_STATE); const { login, isAuthenticated, setUserData } = useContext(AuthContext); + const setLoading = useAlertStore((state) => state.setLoading); const { password, username } = inputState; const setErrorData = useAlertStore((state) => state.setErrorData); @@ -35,6 +36,10 @@ export default function LoginAdminPage() { }; onLogin(user) .then((user) => { + console.log("admin page"); + + setLoading(true); + login(user.access_token); navigate("/admin/"); }) From a1cd3be2373d8e590fb4d075a693f95e334bc3ba Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:45:27 -0300 Subject: [PATCH 11/22] feat: Add useFlowsManagerStore to LoginPage for managing loading state during login --- src/frontend/src/pages/LoginPage/index.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/frontend/src/pages/LoginPage/index.tsx b/src/frontend/src/pages/LoginPage/index.tsx index 826b2a931..d25d1c2e1 100644 --- a/src/frontend/src/pages/LoginPage/index.tsx +++ b/src/frontend/src/pages/LoginPage/index.tsx @@ -9,6 +9,7 @@ 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"; import { inputHandlerEventType, @@ -23,6 +24,7 @@ export default function LoginPage(): JSX.Element { const { login } = useContext(AuthContext); const navigate = useNavigate(); const setErrorData = useAlertStore((state) => state.setErrorData); + const setLoading = useFlowsManagerStore((state) => state.setIsLoading); function handleInput({ target: { name, value }, @@ -37,6 +39,9 @@ export default function LoginPage(): JSX.Element { }; onLogin(user) .then((user) => { + console.log("login page"); + + setLoading(true); login(user.access_token); navigate("/"); }) From 6450b52c402137e2d55573a36c74e539b6699ecc Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:45:41 -0300 Subject: [PATCH 12/22] chore: Remove unused code in HeaderTabsSearchComponent --- .../headerTabsSearchComponent/index.tsx | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx b/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx index 17916f05b..c6ceb44c7 100644 --- a/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx +++ b/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx @@ -1,39 +1,19 @@ import { useState } from "react"; -import { useLocation } from "react-router-dom"; -import useAlertStore from "../../../../../../stores/alertStore"; import useFlowsManagerStore from "../../../../../../stores/flowsManagerStore"; -import { useFolderStore } from "../../../../../../stores/foldersStore"; -import { handleDownloadFolderFn } from "../../../../utils/handle-download-folder"; import InputSearchComponent from "../inputSearchComponent"; import TabsSearchComponent from "../tabsComponent"; type HeaderTabsSearchComponentProps = {}; const HeaderTabsSearchComponent = ({}: HeaderTabsSearchComponentProps) => { - const location = useLocation(); - const myCollectionId = useFolderStore((state) => state.myCollectionId); - const folderId = location?.state?.folderId || myCollectionId; const isLoading = useFlowsManagerStore((state) => state.isLoading); const [tabActive, setTabActive] = useState("Flows"); - const setErrorData = useAlertStore((state) => state.setErrorData); - const allFlows = useFlowsManagerStore((state) => state.allFlows); const [inputValue, setInputValue] = useState(""); const setSearchFlowsComponents = useFlowsManagerStore( - (state) => state.setSearchFlowsComponents + (state) => state.setSearchFlowsComponents, ); - const handleDownloadFolder = () => { - if (allFlows.length === 0) { - setErrorData({ - title: "Folder is empty", - list: [], - }); - return; - } - handleDownloadFolderFn(folderId); - }; - return ( <>
From 5462aeee3e3b3128dc08bfa3c4ea7a22ea246de6 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:45:50 -0300 Subject: [PATCH 13/22] refactor: Update useDeleteFolder hook to use refreshFolders instead of getFoldersApi --- src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx b/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx index 257f1b6d2..239bf26f3 100644 --- a/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx +++ b/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx @@ -2,11 +2,12 @@ import useAlertStore from "../../../stores/alertStore"; import { useFolderStore } from "../../../stores/foldersStore"; import { deleteFolder, getFolderById } from "../services"; -const useDeleteFolder = ({ navigate, getFoldersApi }) => { +const useDeleteFolder = ({ navigate }) => { const setSuccessData = useAlertStore((state) => state.setSuccessData); const setErrorData = useAlertStore((state) => state.setErrorData); const folderToEdit = useFolderStore((state) => state.folderToEdit); const myCollectionId = useFolderStore((state) => state.myCollectionId); + const refreshFolders = useFolderStore((state) => state.refreshFolders); const handleDeleteFolder = () => { deleteFolder(folderToEdit?.id!) @@ -15,7 +16,7 @@ const useDeleteFolder = ({ navigate, getFoldersApi }) => { title: "Folder deleted successfully.", }); getFolderById(myCollectionId!); - getFoldersApi(true); + refreshFolders(); navigate("/all"); }) .catch((err) => { From 9dd56b04126eb7efe98b40722b6671c70393b6f7 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:45:58 -0300 Subject: [PATCH 14/22] refactor: Update MainPage component to remove unused code and improve folder deletion handling --- .../src/pages/MainPage/pages/mainPage/index.tsx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx b/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx index 0daa61257..6b4892d60 100644 --- a/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx +++ b/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx @@ -16,7 +16,7 @@ import useDropdownOptions from "../../hooks/use-dropdown-options"; export default function HomePage(): JSX.Element { const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow); const setCurrentFlowId = useFlowsManagerStore( - (state) => state.setCurrentFlowId + (state) => state.setCurrentFlowId, ); const location = useLocation(); @@ -25,16 +25,9 @@ export default function HomePage(): JSX.Element { const [openFolderModal, setOpenFolderModal] = useState(false); const [openDeleteFolderModal, setOpenDeleteFolderModal] = useState(false); const is_component = pathname === "/components"; - const getFoldersApi = useFolderStore((state) => state.getFoldersApi); const setFolderToEdit = useFolderStore((state) => state.setFolderToEdit); const navigate = useNavigate(); - useEffect(() => { - setTimeout(() => { - getFoldersApi(); - }, 300); - }, []); - useEffect(() => { setCurrentFlowId(""); }, [pathname]); @@ -45,7 +38,7 @@ export default function HomePage(): JSX.Element { is_component, }); - const { handleDeleteFolder } = useDeleteFolder({ navigate, getFoldersApi }); + const { handleDeleteFolder } = useDeleteFolder({ navigate }); return ( <> From 33b3a9ee7ee6e1801608e82cd8d277a8ebf6d33e Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:46:06 -0300 Subject: [PATCH 15/22] refactor: Update getFoldersApi to handle startup application and improve code readability --- src/frontend/src/stores/foldersStore.tsx | 78 +++++++++++++++++------- 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/src/frontend/src/stores/foldersStore.tsx b/src/frontend/src/stores/foldersStore.tsx index ce858c3be..01db44247 100644 --- a/src/frontend/src/stores/foldersStore.tsx +++ b/src/frontend/src/stores/foldersStore.tsx @@ -7,15 +7,16 @@ import { } from "../pages/MainPage/services"; import { FoldersStoreType } from "../types/zustand/folders"; import useFlowsManagerStore from "./flowsManagerStore"; +import { useTypesStore } from "./typesStore"; export const useFolderStore = create((set, get) => ({ folders: [], - getFoldersApi: (refetch = false) => { + getFoldersApi: (refetch = false, startupApplication: boolean = false) => { return new Promise((resolve, reject) => { if (get()?.folders.length === 0 || refetch === true) { - get().setLoading(true); + get().setIsLoadingFolders(true); getFolders().then( - (res) => { + async (res) => { const foldersWithoutStarterProjects = res?.filter( (folder) => folder.name !== STARTER_FOLDER_NAME, ); @@ -33,38 +34,73 @@ export const useFolderStore = create((set, get) => ({ set({ myCollectionId }); - if (refetch === true) { - useFlowsManagerStore.getState().refreshFlows(); - useFlowsManagerStore.getState().setAllFlows; - } + const { refreshFlows } = useFlowsManagerStore.getState(); + const { getTypes } = useTypesStore.getState(); + const { setIsLoadingFolders } = get(); + + if (refetch) { + if (startupApplication) { + await refreshFlows(); + await getTypes(); + } else { + refreshFlows(); + getTypes(); + } + } + setIsLoadingFolders(false); - get().setLoading(false); resolve(); }, (error) => { set({ folders: [] }); - get().setLoading(false); + get().setIsLoadingFolders(false); reject(error); }, ); } }); }, - setFolders: (folders) => set(() => ({ folders: folders })), - loading: false, - setLoading: (loading) => set(() => ({ loading: loading })), - getFolderById: (id) => { - if (id) { - getFolderById(id).then( - (res) => { - const setAllFlows = useFlowsManagerStore.getState().setAllFlows; - setAllFlows(res.flows); - set({ selectedFolder: res }); + refreshFolders: () => { + return new Promise((resolve, reject) => { + getFolders().then( + async (res) => { + const foldersWithoutStarterProjects = res?.filter( + (folder) => folder.name !== STARTER_FOLDER_NAME, + ); + + const starterProjects = res?.find( + (folder) => folder.name === STARTER_FOLDER_NAME, + ); + + set({ starterProjectId: starterProjects!.id ?? "" }); + set({ folders: foldersWithoutStarterProjects }); + + const myCollectionId = res?.find( + (f) => f.name === DEFAULT_FOLDER, + )?.id; + + set({ myCollectionId }); + + resolve(); }, - () => { - get().getFoldersApi(true); + (error) => { + set({ folders: [] }); + get().setIsLoadingFolders(false); + reject(error); }, ); + }); + }, + setFolders: (folders) => set(() => ({ folders: folders })), + isLoadingFolders: false, + setIsLoadingFolders: (isLoadingFolders) => set(() => ({ isLoadingFolders })), + getFolderById: (id) => { + if (id) { + getFolderById(id).then((res) => { + const setAllFlows = useFlowsManagerStore.getState().setAllFlows; + setAllFlows(res.flows); + set({ selectedFolder: res }); + }); } }, selectedFolder: null, From 41fc8461079b7987364e6e5e6a4eb8a1dd4ea734 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Thu, 13 Jun 2024 17:46:14 -0300 Subject: [PATCH 16/22] refactor: Update FoldersStoreType to use isLoadingFolders instead of loading --- src/frontend/src/types/zustand/folders/index.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/types/zustand/folders/index.ts b/src/frontend/src/types/zustand/folders/index.ts index 5e41677b2..495d65b87 100644 --- a/src/frontend/src/types/zustand/folders/index.ts +++ b/src/frontend/src/types/zustand/folders/index.ts @@ -2,10 +2,13 @@ import { FolderType } from "../../../pages/MainPage/entities"; export type FoldersStoreType = { folders: FolderType[]; - getFoldersApi: (refetch?: boolean) => Promise; + getFoldersApi: ( + refetch?: boolean, + startupApplication?: boolean, + ) => Promise; setFolders: (folders: FolderType[]) => void; - loading: boolean; - setLoading: (loading: boolean) => void; + isLoadingFolders: boolean; + setIsLoadingFolders: (isLoadingFolders: boolean) => void; selectedFolder: FolderType | null; getFolderById: (id: string) => void; getMyCollectionFolder: () => void; @@ -23,4 +26,5 @@ export type FoldersStoreType = { setFolderIdDragging: (id: string) => void; starterProjectId: string; setStarterProjectId: (id: string) => void; + refreshFolders: () => void; }; From ec1a0fafe5be2864f71c17d5d33f9bcd5d82e396 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Fri, 14 Jun 2024 09:34:59 -0300 Subject: [PATCH 17/22] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20(use-delete-folder.t?= =?UTF-8?q?sx):=20replace=20refreshFolders=20with=20getFoldersApi=20for=20?= =?UTF-8?q?better=20API=20call=20management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx b/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx index 239bf26f3..1eb1c9c0c 100644 --- a/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx +++ b/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx @@ -8,6 +8,7 @@ const useDeleteFolder = ({ navigate }) => { const folderToEdit = useFolderStore((state) => state.folderToEdit); const myCollectionId = useFolderStore((state) => state.myCollectionId); const refreshFolders = useFolderStore((state) => state.refreshFolders); + const getFoldersApi = useFolderStore((state) => state.getFoldersApi); const handleDeleteFolder = () => { deleteFolder(folderToEdit?.id!) @@ -16,7 +17,7 @@ const useDeleteFolder = ({ navigate }) => { title: "Folder deleted successfully.", }); getFolderById(myCollectionId!); - refreshFolders(); + getFoldersApi(true); navigate("/all"); }) .catch((err) => { From 705311982c21ecae3b590af7648cef46de32b46e Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Fri, 14 Jun 2024 09:40:48 -0300 Subject: [PATCH 18/22] formatting files --- src/frontend/src/App.tsx | 6 +-- .../components/sideBarFolderButtons/index.tsx | 18 +++---- .../hooks/use-on-file-drop.tsx | 10 ++-- .../src/components/tableComponent/index.tsx | 10 ++-- src/frontend/src/contexts/authContext.tsx | 6 +-- src/frontend/src/controllers/API/api.tsx | 10 ++-- .../API/helpers/check-duplicate-requests.ts | 2 +- src/frontend/src/controllers/API/index.ts | 52 +++++++++---------- .../headerTabsSearchComponent/index.tsx | 2 +- .../pages/MainPage/pages/mainPage/index.tsx | 2 +- src/frontend/src/stores/foldersStore.tsx | 16 +++--- .../src/types/zustand/folders/index.ts | 2 +- 12 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 720ffb6b2..b84c0d792 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -29,10 +29,10 @@ export default function App() { useTrackLastVisitedPath(); const removeFromTempNotificationList = useAlertStore( - (state) => state.removeFromTempNotificationList, + (state) => state.removeFromTempNotificationList ); const tempNotificationList = useAlertStore( - (state) => state.tempNotificationList, + (state) => state.tempNotificationList ); const [fetchError, setFetchError] = useState(false); const isLoading = useFlowsManagerStore((state) => state.isLoading); @@ -48,7 +48,7 @@ export default function App() { const refreshVersion = useDarkStore((state) => state.refreshVersion); const refreshStars = useDarkStore((state) => state.refreshStars); const setGlobalVariables = useGlobalVariablesStore( - (state) => state.setGlobalVariables, + (state) => state.setGlobalVariables ); const checkHasStore = useStoreStore((state) => state.checkHasStore); const navigate = useNavigate(); diff --git a/src/frontend/src/components/sidebarComponent/components/sideBarFolderButtons/index.tsx b/src/frontend/src/components/sidebarComponent/components/sideBarFolderButtons/index.tsx index 1b538ba20..ff5c17a15 100644 --- a/src/frontend/src/components/sidebarComponent/components/sideBarFolderButtons/index.tsx +++ b/src/frontend/src/components/sidebarComponent/components/sideBarFolderButtons/index.tsx @@ -31,7 +31,7 @@ const SideBarFoldersButtonsComponent = ({ const [foldersNames, setFoldersNames] = useState({}); const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); const [editFolders, setEditFolderName] = useState( - folders.map((obj) => ({ name: obj.name, edit: false })), + folders.map((obj) => ({ name: obj.name, edit: false })) ); const uploadFolder = useFolderStore((state) => state.uploadFolder); const currentFolder = pathname.split("/"); @@ -58,7 +58,7 @@ const SideBarFoldersButtonsComponent = ({ const { dragOver, dragEnter, dragLeave, onDrop } = useFileDrop( folderId, - handleFolderChange, + handleFolderChange ); const handleUploadFlowsToFolder = () => { @@ -86,7 +86,7 @@ const SideBarFoldersButtonsComponent = ({ addFolder({ name: "New Folder", parent_id: null, description: "" }).then( (res) => { refreshFolders(); - }, + } ); } @@ -132,7 +132,7 @@ const SideBarFoldersButtonsComponent = ({ <> {folders.map((item, index) => { const editFolderName = editFolders?.filter( - (folder) => folder.name === item.name, + (folder) => folder.name === item.name )[0]; return (
handleChangeFolder!(item.id!)} > @@ -218,7 +218,7 @@ const SideBarFoldersButtonsComponent = ({ folders.map((obj) => ({ name: obj.name, edit: false, - })), + })) ); } if (e.key === "Enter") { @@ -251,10 +251,10 @@ const SideBarFoldersButtonsComponent = ({ }; const updatedFolder = await updateFolder( body, - item.id!, + item.id! ); const updateFolders = folders.filter( - (f) => f.name !== item.name, + (f) => f.name !== item.name ); setFolders([...updateFolders, updatedFolder]); setFoldersNames({}); @@ -262,7 +262,7 @@ const SideBarFoldersButtonsComponent = ({ folders.map((obj) => ({ name: obj.name, edit: false, - })), + })) ); } else { setFoldersNames((old) => ({ diff --git a/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx b/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx index c75bf4bec..ab4b9d27f 100644 --- a/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx +++ b/src/frontend/src/components/sidebarComponent/hooks/use-on-file-drop.tsx @@ -12,7 +12,7 @@ import { addVersionToDuplicates } from "../../../utils/reactflowUtils"; const useFileDrop = (folderId, folderChangeCallback) => { const setFolderDragging = useFolderStore((state) => state.setFolderDragging); const setFolderIdDragging = useFolderStore( - (state) => state.setFolderIdDragging, + (state) => state.setFolderIdDragging ); const setErrorData = useAlertStore((state) => state.setErrorData); @@ -45,7 +45,7 @@ const useFileDrop = (folderId, folderChangeCallback) => { | React.DragEvent | React.DragEvent | React.DragEvent, - folderId: string, + folderId: string ) => { e.preventDefault(); @@ -60,7 +60,7 @@ const useFileDrop = (folderId, folderChangeCallback) => { | React.DragEvent | React.DragEvent | React.DragEvent, - folderId: string, + folderId: string ) => { if (e.dataTransfer.types.some((types) => types === "Files")) { setFolderDragging(true); @@ -73,7 +73,7 @@ const useFileDrop = (folderId, folderChangeCallback) => { e: | React.DragEvent | React.DragEvent - | React.DragEvent, + | React.DragEvent ) => { e.preventDefault(); if (e.target === e.currentTarget) { @@ -87,7 +87,7 @@ const useFileDrop = (folderId, folderChangeCallback) => { | React.DragEvent | React.DragEvent | React.DragEvent, - folderId: string, + folderId: string ) => { if (e?.dataTransfer?.getData("flow")) { const data = JSON.parse(e?.dataTransfer?.getData("flow")); diff --git a/src/frontend/src/components/tableComponent/index.tsx b/src/frontend/src/components/tableComponent/index.tsx index e956d8795..954d7d257 100644 --- a/src/frontend/src/components/tableComponent/index.tsx +++ b/src/frontend/src/components/tableComponent/index.tsx @@ -35,7 +35,7 @@ const TableComponent = forwardRef< alertDescription = DEFAULT_TABLE_ALERT_MSG, ...props }, - ref, + ref ) => { let colDef = props.columnDefs.map((col, index) => { let newCol = { @@ -111,7 +111,7 @@ const TableComponent = forwardRef< }; const onColumnMoved = (params) => { const updatedColumnDefs = makeLastColumnNonResizable( - params.columnApi.getAllGridColumns().map((col) => col.getColDef()), + params.columnApi.getAllGridColumns().map((col) => col.getColDef()) ); params.api.setGridOption("columnDefs", updatedColumnDefs); if (props.onColumnMoved) props.onColumnMoved(params); @@ -135,7 +135,7 @@ const TableComponent = forwardRef< className={cn( dark ? "ag-theme-quartz-dark" : "ag-theme-quartz", "ag-theme-shadcn flex h-full flex-col", - "relative", + "relative" )} // applying the grid theme > source.includes("column"))) { localStorage.setItem( storeReference, - JSON.stringify(realRef.current?.api?.getColumnState()), + JSON.stringify(realRef.current?.api?.getColumnState()) ); setColumnStateChange(true); } @@ -175,7 +175,7 @@ const TableComponent = forwardRef< )}
); - }, + } ); export default TableComponent; diff --git a/src/frontend/src/contexts/authContext.tsx b/src/frontend/src/contexts/authContext.tsx index bd5c2d02c..f6b81a235 100644 --- a/src/frontend/src/contexts/authContext.tsx +++ b/src/frontend/src/contexts/authContext.tsx @@ -31,17 +31,17 @@ export function AuthProvider({ children }): React.ReactElement { const navigate = useNavigate(); const cookies = new Cookies(); const [accessToken, setAccessToken] = useState( - cookies.get("access_token_lf") ?? null, + cookies.get("access_token_lf") ?? null ); const [isAuthenticated, setIsAuthenticated] = useState( - !!cookies.get("access_token_lf"), + !!cookies.get("access_token_lf") ); const [isAdmin, setIsAdmin] = useState(false); const [userData, setUserData] = useState(null); const [autoLogin, setAutoLogin] = useState(false); const setLoading = useAlertStore((state) => state.setLoading); const [apiKey, setApiKey] = useState( - cookies.get("apikey_tkn_lflw"), + cookies.get("apikey_tkn_lflw") ); const getFoldersApi = useFolderStore((state) => state.getFoldersApi); diff --git a/src/frontend/src/controllers/API/api.tsx b/src/frontend/src/controllers/API/api.tsx index 0ac3efa6b..6bd73f5f1 100644 --- a/src/frontend/src/controllers/API/api.tsx +++ b/src/frontend/src/controllers/API/api.tsx @@ -48,7 +48,7 @@ function ApiInterceptor() { } await clearBuildVerticesState(error); return Promise.reject(error); - }, + } ); const isAuthorizedURL = (url) => { @@ -65,10 +65,10 @@ function ApiInterceptor() { const parsedURL = new URL(url); const isDomainAllowed = authorizedDomains.some( - (domain) => parsedURL.origin === new URL(domain).origin, + (domain) => parsedURL.origin === new URL(domain).origin ); const isEndpointAllowed = authorizedEndpoints.some((endpoint) => - parsedURL.pathname.includes(endpoint), + parsedURL.pathname.includes(endpoint) ); return isDomainAllowed || isEndpointAllowed; @@ -102,7 +102,7 @@ function ApiInterceptor() { }, (error) => { return Promise.reject(error); - }, + } ); return () => { @@ -134,7 +134,7 @@ function ApiInterceptor() { if (error?.config?.headers) { delete error.config.headers["Authorization"]; error.config.headers["Authorization"] = `Bearer ${cookies.get( - "access_token_lf", + "access_token_lf" )}`; const response = await axios.request(error.config); return response; diff --git a/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts b/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts index 85c6608ac..ec3c74268 100644 --- a/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts +++ b/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts @@ -9,7 +9,7 @@ export function checkDuplicateRequestAndStoreRequest(config) { const currentUrl = window.location.pathname; const currentTime = Date.now(); const isContained = AUTHORIZED_DUPLICATE_REQUESTS.some((request) => - config?.url!.includes(request), + config?.url!.includes(request) ); if ( diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index 104b815b0..481aa2135 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -63,7 +63,7 @@ export async function sendAll(data: sendAllProps) { } export async function postValidateCode( - code: string, + code: string ): Promise> { return await api.post(`${BASE_URL_API}validate/code`, { code }); } @@ -78,7 +78,7 @@ export async function postValidateCode( export async function postValidatePrompt( name: string, template: string, - frontend_node: APIClassType, + frontend_node: APIClassType ): Promise> { return api.post(`${BASE_URL_API}validate/prompt`, { name, @@ -151,7 +151,7 @@ export async function saveFlowToDatabase(newFlow: { * @throws Will throw an error if the update fails. */ export async function updateFlowInDatabase( - updatedFlow: FlowType, + updatedFlow: FlowType ): Promise { try { const response = await api.patch(`${BASE_URL_API}flows/${updatedFlow.id}`, { @@ -329,7 +329,7 @@ export async function getHealth() { * */ export async function getBuildStatus( - flowId: string, + flowId: string ): Promise> { return await api.get(`${BASE_URL_API}build/${flowId}/status`); } @@ -342,7 +342,7 @@ export async function getBuildStatus( * */ export async function postBuildInit( - flow: FlowType, + flow: FlowType ): Promise> { return await api.post(`${BASE_URL_API}build/init/${flow.id}`, flow); } @@ -358,7 +358,7 @@ export async function postBuildInit( */ export async function uploadFile( file: File, - id: string, + id: string ): Promise> { const formData = new FormData(); formData.append("file", file); @@ -380,7 +380,7 @@ export async function getProfilePictures(): Promise> { // let template = apiClass.template; return await api.post(`${BASE_URL_API}custom_component`, { @@ -393,7 +393,7 @@ export async function postCustomComponentUpdate( code: string, template: APITemplateType, field: string, - field_value: any, + field_value: any ): Promise> { return await api.post(`${BASE_URL_API}custom_component/update`, { code, @@ -415,7 +415,7 @@ export async function onLogin(user: LoginType) { headers: { "Content-Type": "application/x-www-form-urlencoded", }, - }, + } ); if (response.status === 200) { @@ -477,11 +477,11 @@ export async function addUser(user: UserInputType): Promise> { export async function getUsersPage( skip: number, - limit: number, + limit: number ): Promise> { try { const res = await api.get( - `${BASE_URL_API}users/?skip=${skip}&limit=${limit}`, + `${BASE_URL_API}users/?skip=${skip}&limit=${limit}` ); if (res.status === 200) { return res.data; @@ -518,7 +518,7 @@ export async function resetPassword(user_id: string, user: resetPasswordType) { try { const res = await api.patch( `${BASE_URL_API}users/${user_id}/reset-password`, - user, + user ); if (res.status === 200) { return res.data; @@ -592,7 +592,7 @@ export async function saveFlowStore( last_tested_version?: string; }, tags: string[], - publicFlow = false, + publicFlow = false ): Promise { try { const response = await api.post(`${BASE_URL_API}store/components/`, { @@ -721,7 +721,7 @@ export async function postStoreComponents(component: Component) { export async function getComponent(component_id: string) { try { const res = await api.get( - `${BASE_URL_API}store/components/${component_id}`, + `${BASE_URL_API}store/components/${component_id}` ); if (res.status === 200) { return res.data; @@ -736,7 +736,7 @@ export async function searchComponent( page?: number | null, limit?: number | null, status?: string | null, - tags?: string[], + tags?: string[] ): Promise { try { let url = `${BASE_URL_API}store/components/`; @@ -848,7 +848,7 @@ export async function updateFlowStore( }, tags: string[], publicFlow = false, - id: string, + id: string ): Promise { try { const response = await api.patch(`${BASE_URL_API}store/components/${id}`, { @@ -932,7 +932,7 @@ export async function deleteGlobalVariable(id: string) { export async function updateGlobalVariable( name: string, value: string, - id: string, + id: string ) { try { const response = api.patch(`${BASE_URL_API}variables/${id}`, { @@ -951,7 +951,7 @@ export async function getVerticesOrder( startNodeId?: string | null, stopNodeId?: string | null, nodes?: Node[], - Edges?: Edge[], + Edges?: Edge[] ): Promise> { // nodeId is optional and is a query parameter // if nodeId is not provided, the API will return all vertices @@ -971,7 +971,7 @@ export async function getVerticesOrder( return await api.post( `${BASE_URL_API}build/${flowId}/vertices`, data, - config, + config ); } @@ -979,7 +979,7 @@ export async function postBuildVertex( flowId: string, vertexId: string, input_value: string, - files?: string[], + files?: string[] ): Promise> { // input_value is optional and is a query parameter let data = {}; @@ -991,7 +991,7 @@ export async function postBuildVertex( } return await api.post( `${BASE_URL_API}build/${flowId}/vertices/${vertexId}`, - data, + data ); } @@ -1015,7 +1015,7 @@ export async function getFlowPool({ } export async function deleteFlowPool( - flowId: string, + flowId: string ): Promise> { const config = {}; config["params"] = { flow_id: flowId }; @@ -1029,7 +1029,7 @@ export async function deleteFlowPool( * @returns A promise that resolves to an array of AxiosResponse objects representing the delete responses. */ export async function multipleDeleteFlowsComponents( - flowIds: string[], + flowIds: string[] ): Promise[]> { const batches: string[][] = []; @@ -1052,7 +1052,7 @@ export async function multipleDeleteFlowsComponents( // Execute all delete requests const responses: Promise>[] = batches.map((batch) => - deleteBatch(batch), + deleteBatch(batch) ); // Return the responses after all requests are completed @@ -1062,7 +1062,7 @@ export async function multipleDeleteFlowsComponents( export async function getTransactionTable( id: string, mode: "intersection" | "union", - params = {}, + params = {} ): Promise<{ rows: Array; columns: Array }> { const config = {}; config["params"] = { flow_id: id }; @@ -1078,7 +1078,7 @@ export async function getMessagesTable( mode: "intersection" | "union", id?: string, excludedFields?: string[], - params = {}, + params = {} ): Promise<{ rows: Array; columns: Array }> { const config = {}; if (id) { diff --git a/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx b/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx index c6ceb44c7..b023216ab 100644 --- a/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx +++ b/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx @@ -11,7 +11,7 @@ const HeaderTabsSearchComponent = ({}: HeaderTabsSearchComponentProps) => { const [inputValue, setInputValue] = useState(""); const setSearchFlowsComponents = useFlowsManagerStore( - (state) => state.setSearchFlowsComponents, + (state) => state.setSearchFlowsComponents ); return ( diff --git a/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx b/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx index 6b4892d60..39add5211 100644 --- a/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx +++ b/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx @@ -16,7 +16,7 @@ import useDropdownOptions from "../../hooks/use-dropdown-options"; export default function HomePage(): JSX.Element { const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow); const setCurrentFlowId = useFlowsManagerStore( - (state) => state.setCurrentFlowId, + (state) => state.setCurrentFlowId ); const location = useLocation(); diff --git a/src/frontend/src/stores/foldersStore.tsx b/src/frontend/src/stores/foldersStore.tsx index 01db44247..8e42026b4 100644 --- a/src/frontend/src/stores/foldersStore.tsx +++ b/src/frontend/src/stores/foldersStore.tsx @@ -18,18 +18,18 @@ export const useFolderStore = create((set, get) => ({ getFolders().then( async (res) => { const foldersWithoutStarterProjects = res?.filter( - (folder) => folder.name !== STARTER_FOLDER_NAME, + (folder) => folder.name !== STARTER_FOLDER_NAME ); const starterProjects = res?.find( - (folder) => folder.name === STARTER_FOLDER_NAME, + (folder) => folder.name === STARTER_FOLDER_NAME ); set({ starterProjectId: starterProjects!.id ?? "" }); set({ folders: foldersWithoutStarterProjects }); const myCollectionId = res?.find( - (f) => f.name === DEFAULT_FOLDER, + (f) => f.name === DEFAULT_FOLDER )?.id; set({ myCollectionId }); @@ -55,7 +55,7 @@ export const useFolderStore = create((set, get) => ({ set({ folders: [] }); get().setIsLoadingFolders(false); reject(error); - }, + } ); } }); @@ -65,18 +65,18 @@ export const useFolderStore = create((set, get) => ({ getFolders().then( async (res) => { const foldersWithoutStarterProjects = res?.filter( - (folder) => folder.name !== STARTER_FOLDER_NAME, + (folder) => folder.name !== STARTER_FOLDER_NAME ); const starterProjects = res?.find( - (folder) => folder.name === STARTER_FOLDER_NAME, + (folder) => folder.name === STARTER_FOLDER_NAME ); set({ starterProjectId: starterProjects!.id ?? "" }); set({ folders: foldersWithoutStarterProjects }); const myCollectionId = res?.find( - (f) => f.name === DEFAULT_FOLDER, + (f) => f.name === DEFAULT_FOLDER )?.id; set({ myCollectionId }); @@ -87,7 +87,7 @@ export const useFolderStore = create((set, get) => ({ set({ folders: [] }); get().setIsLoadingFolders(false); reject(error); - }, + } ); }); }, diff --git a/src/frontend/src/types/zustand/folders/index.ts b/src/frontend/src/types/zustand/folders/index.ts index 495d65b87..45c1e0bd9 100644 --- a/src/frontend/src/types/zustand/folders/index.ts +++ b/src/frontend/src/types/zustand/folders/index.ts @@ -4,7 +4,7 @@ export type FoldersStoreType = { folders: FolderType[]; getFoldersApi: ( refetch?: boolean, - startupApplication?: boolean, + startupApplication?: boolean ) => Promise; setFolders: (folders: FolderType[]) => void; isLoadingFolders: boolean; From 57a7b2baabd0fa39a8d45cfedfb604bf27ecde3d Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Fri, 14 Jun 2024 09:45:53 -0300 Subject: [PATCH 19/22] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20(use-delete-folder.t?= =?UTF-8?q?sx):=20remove=20unused=20refreshFolders=20variable=20to=20clean?= =?UTF-8?q?=20up=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx b/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx index 1eb1c9c0c..0d093bc32 100644 --- a/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx +++ b/src/frontend/src/pages/MainPage/hooks/use-delete-folder.tsx @@ -7,7 +7,6 @@ const useDeleteFolder = ({ navigate }) => { const setErrorData = useAlertStore((state) => state.setErrorData); const folderToEdit = useFolderStore((state) => state.folderToEdit); const myCollectionId = useFolderStore((state) => state.myCollectionId); - const refreshFolders = useFolderStore((state) => state.refreshFolders); const getFoldersApi = useFolderStore((state) => state.getFoldersApi); const handleDeleteFolder = () => { From a9cb7b0f5ebfd8f0994ae0c93c1257216433164c Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Fri, 14 Jun 2024 06:27:48 -0700 Subject: [PATCH 20/22] Update linting workflows for frontend and Python code (#2171) * chore: Update pre-commit hooks and dependencies * chore: Add linting workflow for frontend code * chore: Update linting workflow for Python code and include tests in pull requests * chore: Add Ruff style check workflow for Python code --- .github/workflows/lint-js.yml | 51 +++++++++++++++++++++ .github/workflows/{lint.yml => lint-py.yml} | 21 +++++---- .github/workflows/matchers/ruff.json | 14 ++++++ .github/workflows/style-check-py.yml | 39 ++++++++++++++++ .pre-commit-config.yaml | 26 ----------- 5 files changed, 115 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/lint-js.yml rename .github/workflows/{lint.yml => lint-py.yml} (77%) create mode 100644 .github/workflows/matchers/ruff.json create mode 100644 .github/workflows/style-check-py.yml diff --git a/.github/workflows/lint-js.yml b/.github/workflows/lint-js.yml new file mode 100644 index 000000000..0590e8a38 --- /dev/null +++ b/.github/workflows/lint-js.yml @@ -0,0 +1,51 @@ +name: Lint Frontend + +on: + pull_request: + paths: + - "src/frontend/**" + +env: + NODE_VERSION: "21" + +jobs: + run-linters: + name: Run linters + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + id: setup-node + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Cache Node.js dependencies + uses: actions/cache@v4 + id: npm-cache + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('src/frontend/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Install Node.js dependencies + run: | + cd src/frontend + npm ci + if: ${{ steps.setup-node.outputs.cache-hit != 'true' }} + + - name: Run linters + uses: wearerequired/lint-action@v1 + with: + github_token: ${{ secrets.github_token }} + auto_fix: true + git_email: "gabriel@langflow.org" + # Enable linters + eslint: true + prettier: true + prettier_args: '--write \"{tests,src}/**/*.{js,jsx,ts,tsx,json,md}\" --ignore-path .prettierignore' + diff --git a/.github/workflows/lint.yml b/.github/workflows/lint-py.yml similarity index 77% rename from .github/workflows/lint.yml rename to .github/workflows/lint-py.yml index 3c5898369..5ab5541e3 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint-py.yml @@ -1,17 +1,12 @@ -name: lint +name: Lint Python on: - push: - branches: [main] - paths: - - "poetry.lock" - - "pyproject.toml" - - "src/backend/**" pull_request: paths: - "poetry.lock" - "pyproject.toml" - "src/backend/**" + - "tests/**" env: POETRY_VERSION: "1.8.2" @@ -45,6 +40,12 @@ jobs: path: | ./.mypy_cache key: ${{ runner.os }}-mypy-${{ hashFiles('**/pyproject.toml') }} - - name: Lint check - run: | - make lint + - name: Run linters + uses: wearerequired/lint-action@v1 + with: + github_token: ${{ secrets.github_token }} + # Enable linters + git_email: "gabriel@langflow.org" + mypy: true + mypy_args: '--namespace-packages -p "langflow"' + diff --git a/.github/workflows/matchers/ruff.json b/.github/workflows/matchers/ruff.json new file mode 100644 index 000000000..53b21be23 --- /dev/null +++ b/.github/workflows/matchers/ruff.json @@ -0,0 +1,14 @@ +{ + "problemMatcher": [ + { + "owner": "ruff", + "pattern": [ + { + "regexp": "^(Would reformat): (.+)$", + "message": 1, + "file": 2 + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/workflows/style-check-py.yml b/.github/workflows/style-check-py.yml new file mode 100644 index 000000000..4063cd48d --- /dev/null +++ b/.github/workflows/style-check-py.yml @@ -0,0 +1,39 @@ +name: Ruff Style Check + +on: + pull_request: + paths: + - "poetry.lock" + - "pyproject.toml" + - "src/backend/**" + - "tests/**" + +env: + POETRY_VERSION: "1.8.2" + +jobs: + lint: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: + - "3.12" + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }} + uses: "./.github/actions/poetry_caching" + with: + python-version: ${{ matrix.python-version }} + poetry-version: ${{ env.POETRY_VERSION }} + cache-key: ${{ runner.os }}-poetry-${{ env.POETRY_VERSION }}-${{ hashFiles('**/poetry.lock') }} + - name: Install Python dependencies + run: | + poetry env use ${{ matrix.python-version }} + poetry install + - name: Register problem matcher + run: echo "::add-matcher::.github/workflows/matchers/ruff.json" + - name: Run Ruff + run: poetry run ruff check --output-format=github . + - name: Run Ruff format + run: poetry run ruff format --check . + diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d03df05b9..16599a199 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,18 +1,5 @@ fail_fast: true repos: - - repo: https://github.com/pre-commit/mirrors-eslint - rev: "v9.1.1" - hooks: - - id: eslint - files: \.[jt]sx?$ # *.js, *.jsx, *.ts and *.tsx - types: [file] - args: ["--fix", "--no-warn-ignored"] - additional_dependencies: - - eslint@9.1.1 - - eslint-plugin-prettier - - eslint-config-prettier - - prettier - - eslint-plugin-react@latest - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.1.0 hooks: @@ -25,16 +12,3 @@ repos: args: - --fix=lf - id: trailing-whitespace - - repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version. - rev: v0.4.2 - hooks: - # Run the linter. - - id: ruff - # Python - files: \.py$ - types: [file] - # Run the formatter. - - id: ruff-format - files: \.py$ - types: [file] From 244306961180f273f0be673ab016782a363bdb94 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Fri, 14 Jun 2024 12:33:18 -0300 Subject: [PATCH 21/22] chore: Update mypy command prefix to use "poetry run" --- .github/workflows/lint-py.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/lint-py.yml b/.github/workflows/lint-py.yml index 5ab5541e3..6182f91fc 100644 --- a/.github/workflows/lint-py.yml +++ b/.github/workflows/lint-py.yml @@ -48,4 +48,5 @@ jobs: git_email: "gabriel@langflow.org" mypy: true mypy_args: '--namespace-packages -p "langflow"' + mypy_command_prefix: "poetry run" From 71e8aa00cf33e84134352b535ed5841f4d1c1817 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Fri, 14 Jun 2024 13:23:03 -0300 Subject: [PATCH 22/22] =?UTF-8?q?=F0=9F=90=9B=20(utils.ts):=20add=20option?= =?UTF-8?q?al=20chaining=20to=20base=5Fclasses=20to=20prevent=20runtime=20?= =?UTF-8?q?errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/src/utils/utils.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/frontend/src/utils/utils.ts b/src/frontend/src/utils/utils.ts index 5a1f6621f..0a1f99692 100644 --- a/src/frontend/src/utils/utils.ts +++ b/src/frontend/src/utils/utils.ts @@ -56,7 +56,7 @@ export function normalCaseToSnakeCase(str: string): string { export function toTitleCase( str: string | undefined, - isNodeField?: boolean + isNodeField?: boolean, ): string { if (!str) return ""; let result = str @@ -65,7 +65,7 @@ export function toTitleCase( if (isNodeField) return word; if (index === 0) { return checkUpperWords( - word[0].toUpperCase() + word.slice(1).toLowerCase() + word[0].toUpperCase() + word.slice(1).toLowerCase(), ); } return checkUpperWords(word.toLowerCase()); @@ -78,7 +78,7 @@ export function toTitleCase( if (isNodeField) return word; if (index === 0) { return checkUpperWords( - word[0].toUpperCase() + word.slice(1).toLowerCase() + word[0].toUpperCase() + word.slice(1).toLowerCase(), ); } return checkUpperWords(word.toLowerCase()); @@ -182,7 +182,7 @@ export function checkLocalStorageKey(key: string): boolean { export function IncrementObjectKey( object: object, - key: string + key: string, ): { newKey: string; increment: number } { let count = 1; const type = removeCountFromString(key); @@ -217,7 +217,7 @@ export function groupByFamily( data: APIDataType, baseClasses: string, left: boolean, - flow?: NodeType[] + flow?: NodeType[], ): groupedObjType[] { const baseClassesSet = new Set(baseClasses.split("\n")); let arrOfPossibleInputs: Array<{ @@ -243,7 +243,7 @@ export function groupByFamily( baseClassesSet.has(template.type)) || (template?.input_types && template?.input_types.some((inputType) => - baseClassesSet.has(inputType) + baseClassesSet.has(inputType), ))) ); }; @@ -263,7 +263,7 @@ export function groupByFamily( hasBaseClassInBaseClasses: foundNode?.hasBaseClassInBaseClasses || nodeData.node!.base_classes.some((baseClass) => - baseClassesSet.has(baseClass) + baseClassesSet.has(baseClass), ), //seta como anterior ou verifica se o node tem base class displayName: nodeData.node?.display_name, }); @@ -280,10 +280,10 @@ export function groupByFamily( if (!foundNode) { foundNode = { hasBaseClassInTemplate: Object.values(node!.template).some( - checkBaseClass + checkBaseClass, ), - hasBaseClassInBaseClasses: node!.base_classes.some((baseClass) => - baseClassesSet.has(baseClass) + hasBaseClassInBaseClasses: node!.base_classes?.some((baseClass) => + baseClassesSet.has(baseClass), ), displayName: node?.display_name, }; @@ -355,7 +355,7 @@ export function isTimeStampString(str: string): boolean { export function extractColumnsFromRows( rows: object[], mode: "intersection" | "union", - excludeColumns?: Array + excludeColumns?: Array, ): (ColDef | ColGroupDef)[] { let columnsKeys: { [key: string]: ColDef | ColGroupDef } = {}; if (rows.length === 0) {