Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: folder fetching, folder sidebar and fix various issues #3344

Merged
merged 39 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
be54190
Removed unused code
lucaseduoli Aug 14, 2024
96f8587
Separated folder sidebar from common sidebar
lucaseduoli Aug 14, 2024
966f3a8
Removed useOnFileDrop from common sidebar
lucaseduoli Aug 14, 2024
3394430
Added folderSidebarComponent that fetches the folders
lucaseduoli Aug 14, 2024
8365149
Added useOnFileDrop and SIdebarFoldersButton
lucaseduoli Aug 14, 2024
d7f39b7
Make auth context not get folders
lucaseduoli Aug 14, 2024
8790002
Make delete folder refetch get folders
lucaseduoli Aug 14, 2024
dba42cb
Make folder mutations refetch the getFolder
lucaseduoli Aug 14, 2024
c01dc49
Create getFolder query
lucaseduoli Aug 14, 2024
2eef2cc
Removed unused functions from useFolderStore
lucaseduoli Aug 14, 2024
d55207c
Make isLoading from application depend only on flows
lucaseduoli Aug 14, 2024
d831605
Make main page not refetch folders
lucaseduoli Aug 14, 2024
a1f0441
Change types of folders store
lucaseduoli Aug 14, 2024
ef56fd1
removed getFolders refetch on duplicateFolders
lucaseduoli Aug 14, 2024
ce1d078
Added loading from query into ComponentsComponent
lucaseduoli Aug 14, 2024
ffddd06
Made the flow page get the flows and types if they're not available
lucaseduoli Aug 14, 2024
3ebc787
Made the loading be the isLoading only
lucaseduoli Aug 14, 2024
7a2173c
Removed unused function
lucaseduoli Aug 14, 2024
12cdceb
Make cards appear even if it didnt load
lucaseduoli Aug 14, 2024
bc95837
Removed setLoading of various pages
lucaseduoli Aug 14, 2024
014fbe8
Fixed loading happening every time the flow changes
lucaseduoli Aug 14, 2024
d6149fd
Added skeleton instead of loading on folders
lucaseduoli Aug 14, 2024
5271109
Added routing to contain folderId on both flows and initial page
lucaseduoli Aug 14, 2024
e82402f
remove redirect of useFileDrop
lucaseduoli Aug 14, 2024
ce46e11
remove folderid getting from state
lucaseduoli Aug 14, 2024
963d18e
removed setAllFlows
lucaseduoli Aug 14, 2024
5404e9e
chore: Remove unused variables and functions in useDuplicateFlows hook
lucaseduoli Aug 14, 2024
946dcec
Added refetch of folders when the flow is deleted or added
lucaseduoli Aug 14, 2024
6e0a494
Changed redirectToLastLocation to redirect to last folder also
lucaseduoli Aug 14, 2024
768c26d
Added upload flow to folder tanstack and refetched folders on upload
lucaseduoli Aug 14, 2024
fd31a06
Added loading of current folder on display of empty component
lucaseduoli Aug 14, 2024
5badc19
Removed refetching folder on file drop
lucaseduoli Aug 14, 2024
ed30857
Removed unused code
lucaseduoli Aug 14, 2024
30f9358
Fixed add new flow from header not redirecting correctly
lucaseduoli Aug 14, 2024
bbe899d
Fixed unused code
lucaseduoli Aug 14, 2024
e1ff7c1
Merge branch 'main' into fix/empty_flows
lucaseduoli Aug 14, 2024
080b773
Added undefined on setting current flow as empty
lucaseduoli Aug 14, 2024
cff0e40
Added disable top bar and make it be displayed on the top of an empty…
lucaseduoli Aug 14, 2024
542402a
Fixed select all checked when deleting all flows
lucaseduoli Aug 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Skeleton } from "@/components/ui/skeleton";

export function SidebarFolderSkeleton() {
return (
<div className="flex h-10 w-full shrink-0 animate-pulse cursor-pointer items-center gap-4 rounded-md border bg-background px-4 opacity-100 lg:min-w-full">
<Skeleton className="h-3 w-4 rounded-full" />
<Skeleton className="h-3 w-[40%]" />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
import { usePostUploadFlowToFolder } from "@/controllers/API/queries/folders/use-post-upload-to-folder";
import useSaveFlow from "@/hooks/flows/use-save-flow";
import {
UPLOAD_ALERT_LIST,
WRONG_FILE_ERROR_ALERT,
} from "../../../constants/alerts_constants";
import { uploadFlowToFolder } from "../../../pages/MainPage/services";
import useAlertStore from "../../../stores/alertStore";
import useFlowsManagerStore from "../../../stores/flowsManagerStore";
import { useFolderStore } from "../../../stores/foldersStore";
import { addVersionToDuplicates } from "../../../utils/reactflowUtils";

const useFileDrop = (
folderId: string,
folderChangeCallback: (folderId: string) => void,
) => {
const useFileDrop = (folderId: string) => {
const setFolderDragging = useFolderStore((state) => state.setFolderDragging);
const setFolderIdDragging = useFolderStore(
(state) => state.setFolderIdDragging,
);

const setErrorData = useAlertStore((state) => state.setErrorData);
const refreshFolders = useFolderStore((state) => state.refreshFolders);
const flows = useFlowsManagerStore((state) => state.flows);
const saveFlow = useSaveFlow();

const triggerFolderChange = (folderId) => {
if (folderChangeCallback) {
folderChangeCallback(folderId);
}
};
const { mutate: uploadFlowToFolder } = usePostUploadFlowToFolder();
const handleFileDrop = async (e) => {
if (e.dataTransfer.types.some((type) => type === "Files")) {
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
Expand Down Expand Up @@ -121,10 +112,7 @@ const useFileDrop = (
setFolderDragging(false);
setFolderIdDragging("");

saveFlow(updatedFlow).then(() => {
refreshFolders();
triggerFolderChange(folderId);
});
saveFlow(updatedFlow);
};

const uploadFormData = (data) => {
Expand All @@ -133,10 +121,7 @@ const useFileDrop = (
setFolderDragging(false);
setFolderIdDragging("");

uploadFlowToFolder(formData, folderId).then(() => {
refreshFolders();
triggerFolderChange(folderId);
});
uploadFlowToFolder({ flows: formData, folderId });
};

return {
Expand Down
38 changes: 38 additions & 0 deletions src/frontend/src/components/folderSidebarComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useGetFoldersQuery } from "@/controllers/API/queries/folders/use-get-folders";
import { useLocation } from "react-router-dom";
import { FolderType } from "../../pages/MainPage/entities";
import { cn } from "../../utils/utils";
import HorizontalScrollFadeComponent from "../horizontalScrollFadeComponent";
import SideBarFoldersButtonsComponent from "./components/sideBarFolderButtons";

type SidebarNavProps = {
handleChangeFolder?: (id: string) => void;
handleDeleteFolder?: (item: FolderType) => void;
className?: string;
};

export default function FolderSidebarNav({
className,
handleChangeFolder,
handleDeleteFolder,
...props
}: SidebarNavProps) {
const location = useLocation();
const pathname = location.pathname;

const { data: folders, isPending } = useGetFoldersQuery();

return (
<nav className={cn(className)} {...props}>
<HorizontalScrollFadeComponent>
<SideBarFoldersButtonsComponent
loading={isPending || !folders}
pathname={pathname}
handleChangeFolder={handleChangeFolder}
handleDeleteFolder={handleDeleteFolder}
folders={folders}
/>
</HorizontalScrollFadeComponent>
</nav>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const MenuBar = ({}: {}): JSX.Element => {
const currentSavedFlow = useFlowsManagerStore((state) => state.currentFlow);
const updatedAt = currentSavedFlow?.updated_at;
const onFlowPage = useFlowStore((state) => state.onFlowPage);
const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow);

const changesNotSaved =
customStringify(currentFlow) !== customStringify(currentSavedFlow) &&
Expand All @@ -71,6 +72,7 @@ export const MenuBar = ({}: {}): JSX.Element => {
function handleAddFlow() {
try {
addFlow().then((id) => {
setCurrentFlow(undefined); // Reset current flow for useEffect of flowPage to update the current flow
navigate("/flow/" + id);
});
} catch (err) {
Expand Down
14 changes: 5 additions & 9 deletions src/frontend/src/components/headerComponent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,12 @@ export default function Header(): JSX.Element {
}`;

const redirectToLastLocation = () => {
const lastFlowVisitedIndex = routeHistory
const lastVisitedIndex = routeHistory
.reverse()
.findIndex(
(path) => path.includes("/flow/") && path !== location.pathname,
);
.findIndex((path) => path !== location.pathname);

const lastFlowVisited = routeHistory[lastFlowVisitedIndex];
lastFlowVisited && !location.pathname.includes("/flow")
? navigate(lastFlowVisited)
: navigate("/all");
const lastFlowVisited = routeHistory[lastVisitedIndex];
lastFlowVisited ? navigate(lastFlowVisited) : navigate("/all");
};

const visitedFlowPathBefore = () => {
Expand Down Expand Up @@ -108,7 +104,7 @@ export default function Header(): JSX.Element {
</div>

<div className="round-button-div">
<Link to="/">
<Link to="/all">
<Button
className="gap-2"
variant={
Expand Down
28 changes: 1 addition & 27 deletions src/frontend/src/components/sidebarComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,29 @@
import { useLocation } from "react-router-dom";
import { FolderType } from "../../pages/MainPage/entities";
import { useFolderStore } from "../../stores/foldersStore";
import { cn } from "../../utils/utils";
import HorizontalScrollFadeComponent from "../horizontalScrollFadeComponent";
import SideBarButtonsComponent from "./components/sideBarButtons";
import SideBarFoldersButtonsComponent from "./components/sideBarFolderButtons";

type SidebarNavProps = {
items: {
href?: string;
title: string;
icon: React.ReactNode;
}[];
handleChangeFolder?: (id: string) => void;
handleEditFolder?: (item: FolderType) => void;
handleDeleteFolder?: (item: FolderType) => void;
className?: string;
};

export default function SidebarNav({
className,
items,
handleChangeFolder,
handleEditFolder,
handleDeleteFolder,
...props
}: SidebarNavProps) {
const location = useLocation();
const pathname = location.pathname;
const loadingFolders = useFolderStore((state) => state.isLoadingFolders);
const folders = useFolderStore((state) => state.folders);

const pathValues = ["folder", "components", "flows", "all"];
const isFolderPath = pathValues.some((value) => pathname.includes(value));

// Ensure all conditions are covered and provide a default case if necessary
const sidebarContent =
items.length > 0 ? (
<SideBarButtonsComponent items={items} pathname={pathname} />
) : !loadingFolders && folders?.length > 0 && isFolderPath ? (
<SideBarFoldersButtonsComponent
pathname={pathname}
handleChangeFolder={handleChangeFolder}
handleDeleteFolder={handleDeleteFolder}
/>
) : null;

return (
<nav className={cn(className)} {...props}>
<HorizontalScrollFadeComponent>
{sidebarContent!}
<SideBarButtonsComponent items={items} pathname={pathname} />
</HorizontalScrollFadeComponent>
</nav>
);
Expand Down
4 changes: 0 additions & 4 deletions src/frontend/src/contexts/authContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import useAuthStore from "@/stores/authStore";
import { createContext, useEffect, useState } from "react";
import Cookies from "universal-cookie";
import useAlertStore from "../stores/alertStore";
import { useFolderStore } from "../stores/foldersStore";
import { useStoreStore } from "../stores/storeStore";
import { Users } from "../types/api";
import { AuthContextType } from "../types/contexts/auth";
Expand Down Expand Up @@ -38,8 +37,6 @@ export function AuthProvider({ children }): React.ReactElement {
cookies.get(LANGFLOW_API_TOKEN),
);

const getFoldersApi = useFolderStore((state) => state.getFoldersApi);

const checkHasStore = useStoreStore((state) => state.checkHasStore);
const fetchApiData = useStoreStore((state) => state.fetchApiData);
const setIsAuthenticated = useAuthStore((state) => state.setIsAuthenticated);
Expand Down Expand Up @@ -68,7 +65,6 @@ export function AuthProvider({ children }): React.ReactElement {
setUserData(user);
const isSuperUser = user!.is_superuser;
useAuthStore.getState().setIsAdmin(isSuperUser);
getFoldersApi(true, true);
checkHasStore();
fetchApiData();
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const useDeleteDeleteFlows: useMutationFunctionType<
undefined,
IDeleteFlows
> = (options?) => {
const { mutate } = UseRequestProcessor();
const { mutate, queryClient } = UseRequestProcessor();

const deleteFlowsFn = async (payload: IDeleteFlows): Promise<any> => {
const response = await api.delete<any>(`${getURL("FLOWS")}/`, {
Expand All @@ -25,7 +25,12 @@ export const useDeleteDeleteFlows: useMutationFunctionType<
const mutation: UseMutationResult<IDeleteFlows, any, IDeleteFlows> = mutate(
["useLoginUser"],
deleteFlowsFn,
options,
{
...options,
onSettled: () => {
queryClient.refetchQueries({ queryKey: ["useGetFolder"] });
},
},
);

return mutation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const usePatchUpdateFlow: useMutationFunctionType<
undefined,
IPatchUpdateFlow
> = (options?) => {
const { mutate } = UseRequestProcessor();
const { mutate, queryClient } = UseRequestProcessor();

const PatchUpdateFlowFn = async (payload: IPatchUpdateFlow): Promise<any> => {
const response = await api.patch(`${getURL("FLOWS")}/${payload.id}`, {
Expand All @@ -33,7 +33,14 @@ export const usePatchUpdateFlow: useMutationFunctionType<
};

const mutation: UseMutationResult<IPatchUpdateFlow, any, IPatchUpdateFlow> =
mutate(["usePatchUpdateFlow"], PatchUpdateFlowFn, options);
mutate(["usePatchUpdateFlow"], PatchUpdateFlowFn, {
...options,
onSettled: () => {
queryClient.refetchQueries({
queryKey: ["useGetFolder"],
});
},
});

return mutation;
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const usePostAddFlow: useMutationFunctionType<
undefined,
IPostAddFlow
> = (options?) => {
const { mutate } = UseRequestProcessor();
const { mutate, queryClient } = UseRequestProcessor();

const postAddFlowFn = async (payload: IPostAddFlow): Promise<any> => {
const response = await api.post(`${getURL("FLOWS")}/`, {
Expand All @@ -36,7 +36,12 @@ export const usePostAddFlow: useMutationFunctionType<
const mutation: UseMutationResult<IPostAddFlow, any, IPostAddFlow> = mutate(
["usePostAddFlow"],
postAddFlowFn,
options,
{
...options,
onSettled: () => {
queryClient.refetchQueries({ queryKey: ["useGetFolder"] });
},
},
);

return mutation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const useDeleteFolders: useMutationFunctionType<
undefined,
DeleteFoldersParams
> = (options?) => {
const { mutate } = UseRequestProcessor();
const { mutate, queryClient } = UseRequestProcessor();

const deleteFolder = async ({
folder_id,
Expand All @@ -25,7 +25,12 @@ export const useDeleteFolders: useMutationFunctionType<
DeleteFoldersParams,
any,
DeleteFoldersParams
> = mutate(["useDeleteFolders"], deleteFolder, options);
> = mutate(["useDeleteFolders"], deleteFolder, {
...options,
onSettled: () => {
queryClient.refetchQueries({ queryKey: ["useGetFolders"] });
},
});

return mutation;
};
30 changes: 30 additions & 0 deletions src/frontend/src/controllers/API/queries/folders/use-get-folder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { FolderType } from "@/pages/MainPage/entities";
import { useQueryFunctionType } from "@/types/api";
import { api } from "../../api";
import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor";

interface IGetFolder {
id: string;
}

export const useGetFolderQuery: useQueryFunctionType<IGetFolder, FolderType> = (
params,
options,
) => {
const { query } = UseRequestProcessor();

const getFolderFn = async (): Promise<FolderType> => {
const res = await api.get(`${getURL("FOLDERS")}/${params.id}`);
const data = res.data;

return data;
};

const queryResult = query(
["useGetFolder", { id: params.id }],
getFolderFn,
options,
);
return queryResult;
};
Loading