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: add flow and upload flow functionality #3200

Merged
merged 51 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
f0d23aa
Removed unused function and fixed tags initial value
lucaseduoli Jul 31, 2024
bf36487
Added post save flow
lucaseduoli Jul 31, 2024
3c5ed15
Added update flow patch
lucaseduoli Jul 31, 2024
a77cba7
Merge remote-tracking branch 'origin/main' into fix/save_flow
lucaseduoli Aug 1, 2024
ff2bc6e
removed unused import
lucaseduoli Aug 1, 2024
e2a15d3
created useAddFlow hook to substitute AddFlow function on flowsManage…
lucaseduoli Aug 1, 2024
67b5f88
fixed post save flow to handle endpoint name as undefined
lucaseduoli Aug 1, 2024
529bc3b
Fixed add flow hook to use post save flow mutation
lucaseduoli Aug 1, 2024
deaccd5
removed unused line
lucaseduoli Aug 1, 2024
948ed3b
changed addFlow to use hook in all components that use addFlow
lucaseduoli Aug 1, 2024
3b64f71
Removed unused code
lucaseduoli Aug 1, 2024
58b13c5
removed addFlow of useDuplicateFlows call
lucaseduoli Aug 1, 2024
39b229c
made newProject default as true
lucaseduoli Aug 1, 2024
fc48054
removed unused variables from addFlow
lucaseduoli Aug 1, 2024
ccd1113
fixed url of requests of flows
lucaseduoli Aug 1, 2024
0129832
passed functions directly
lucaseduoli Aug 1, 2024
d7c19ef
fix app to display loading on top of the router
lucaseduoli Aug 1, 2024
e2f14e3
fixed promise of addFlow
lucaseduoli Aug 1, 2024
eae889e
Merge remote-tracking branch 'origin/main' into fix/save_flow
lucaseduoli Aug 1, 2024
14499bc
Added upload flow hook with a lot of modularity
lucaseduoli Aug 5, 2024
2005714
Fixed addFlow naming
lucaseduoli Aug 5, 2024
a17160a
Added helper functions for file uploading
lucaseduoli Aug 5, 2024
b829285
Changed upload flow to use helper functions
lucaseduoli Aug 5, 2024
5cbbb81
removed refresh on post
lucaseduoli Aug 5, 2024
4cfe781
changed paste function to handle when chatinput node exists on paste
lucaseduoli Aug 5, 2024
f290825
Used helper function to create input on FileInput
lucaseduoli Aug 5, 2024
a6bf87c
Used helper function to create input on InputFileComponent
lucaseduoli Aug 5, 2024
4d1c9cb
Used helper function to create input on folder upload, and used uploa…
lucaseduoli Aug 5, 2024
95b4191
used uploadFlow hook on dropdown options
lucaseduoli Aug 5, 2024
aec8d57
used addFlow instead of addComponent on node toolbar
lucaseduoli Aug 5, 2024
4070597
changed upload flow on headerComponent to use hook
lucaseduoli Aug 5, 2024
266f23d
Changed pageComponent to use uploadFlow hook
lucaseduoli Aug 5, 2024
d5008ef
removed useFileDrop dependency
lucaseduoli Aug 5, 2024
063f8aa
Fixed onFileDrop to use uploadFlow
lucaseduoli Aug 5, 2024
4f1b25d
removed useDropdown dependency
lucaseduoli Aug 5, 2024
1cac54a
removed unused add and upload functions from flowsManagerStore
lucaseduoli Aug 5, 2024
1ee0157
Clean flows and refetch when flow change, added loader when is fetching
lucaseduoli Aug 5, 2024
2a8f734
Changed loading to the useQuery isPending
lucaseduoli Aug 6, 2024
0394fde
changed post to add flow
lucaseduoli Aug 6, 2024
54491be
fixed error when uploading other thing that is not a JSON not appearing
lucaseduoli Aug 6, 2024
f5a7834
changed useAddFlow to handle empty params too
lucaseduoli Aug 6, 2024
132e381
Fixed loading every time we switch tabs
lucaseduoli Aug 6, 2024
b09c698
Fixed unnecessary list and !
lucaseduoli Aug 6, 2024
efc3221
Fixed reference bug
lucaseduoli Aug 6, 2024
0fbcd0c
Inserted cloneDeep to prevent reference bugs
lucaseduoli Aug 6, 2024
f30579d
Fixed tests of drag and drop
lucaseduoli Aug 6, 2024
b6f96f1
Merge remote-tracking branch 'origin/main' into fix/save_flow
lucaseduoli Aug 6, 2024
23a48c6
Fixed flows not being refreshed when uploading
lucaseduoli Aug 6, 2024
bff52b8
[autofix.ci] apply automated fixes
autofix-ci[bot] Aug 6, 2024
8e29559
fixed folders test
lucaseduoli Aug 6, 2024
f50c63e
fixed folders test
lucaseduoli Aug 6, 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
19 changes: 10 additions & 9 deletions src/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ import { useGetVersionQuery } from "./controllers/API/queries/version";
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 useAuthStore from "./stores/authStore";
import { useDarkStore } from "./stores/darkStore";
import useFlowsManagerStore from "./stores/flowsManagerStore";
import { useFolderStore } from "./stores/foldersStore";
import { cn } from "./utils/utils";

export default function App() {
useTrackLastVisitedPath();
Expand Down Expand Up @@ -164,15 +164,16 @@ export default function App() {
></FetchErrorComponent>
}

<Case condition={isLoadingApplication}>
<div className="loading-page-panel">
<LoadingComponent remSize={50} />
</div>
</Case>
<div
className={cn(
"loading-page-panel absolute left-0 top-0 z-[999]",
isLoadingApplication ? "" : "hidden",
)}
>
<LoadingComponent remSize={50} />
</div>

<Case condition={!isLoadingApplication}>
<Router />
</Case>
<Router />
</>
</ErrorBoundary>
<div></div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useState } from "react";
import useAddFlow from "@/hooks/flows/use-add-flow";
import { getComponent } from "../../../controllers/API";
import useFlowsManagerStore from "../../../stores/flowsManagerStore";
import { storeComponent } from "../../../types/store";
import cloneFlowWithParent from "../../../utils/storeUtils";

Expand All @@ -14,7 +13,7 @@ const useInstallComponent = (
setSuccessData: (value: { title: string }) => void,
setErrorData: (value: { title: string; list: string[] }) => void,
) => {
const addFlow = useFlowsManagerStore((state) => state.addFlow);
const addFlow = useAddFlow();

const handleInstall = () => {
const temp = downloadsCount;
Expand All @@ -24,7 +23,7 @@ const useInstallComponent = (
getComponent(data.id)
.then((res) => {
const newFlow = cloneFlowWithParent(res, res.id, data.is_component);
addFlow(true, newFlow)
addFlow({ flow: newFlow })
.then((id) => {
setSuccessData({
title: `${name} ${isStore ? "Downloaded" : "Installed"} Successfully.`,
Expand Down
10 changes: 5 additions & 5 deletions src/frontend/src/components/exampleComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import useAddFlow from "@/hooks/flows/use-add-flow";
import emojiRegex from "emoji-regex";
import { useNavigate } from "react-router-dom";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { FlowType } from "../../types/flow";
import { updateIds } from "../../utils/reactflowUtils";
import { cn } from "../../utils/utils";
Expand All @@ -20,10 +21,9 @@ export default function CollectionCardComponent({
flow: FlowType;
authorized?: boolean;
}) {
const addFlow = useFlowsManagerStore((state) => state.addFlow);
const addFlow = useAddFlow();
const navigate = useNavigate();
const emojiRegex = /\p{Emoji}/u;
const isEmoji = (str: string) => emojiRegex.test(str);
const isEmoji = (str: string) => emojiRegex().test(str);

return (
<Card
Expand Down Expand Up @@ -77,7 +77,7 @@ export default function CollectionCardComponent({
<Button
onClick={() => {
updateIds(flow.data!);
addFlow(true, flow).then((id) => {
addFlow({ flow }).then((id) => {
navigate("/flow/" + id);
});
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
DropdownMenuTrigger,
} from "../../../ui/dropdown-menu";

import useAddFlow from "@/hooks/flows/use-add-flow";
import useUploadFlow from "@/hooks/flows/use-upload-flow";
import { useNavigate } from "react-router-dom";
import { UPLOAD_ERROR_ALERT } from "../../../../constants/alerts_constants";
import { SAVED_HOVER } from "../../../../constants/constants";
Expand All @@ -26,7 +28,7 @@ import { Button } from "../../../ui/button";

export const MenuBar = ({}: {}): JSX.Element => {
const shortcuts = useShortcutsStore((state) => state.shortcuts);
const addFlow = useFlowsManagerStore((state) => state.addFlow);
const addFlow = useAddFlow();
const currentFlow = useFlowsManagerStore((state) => state.currentFlow);
const setErrorData = useAlertStore((state) => state.setErrorData);
const setSuccessData = useAlertStore((state) => state.setSuccessData);
Expand All @@ -40,14 +42,14 @@ export const MenuBar = ({}: {}): JSX.Element => {
const saveLoading = useFlowsManagerStore((state) => state.saveLoading);
const [openSettings, setOpenSettings] = useState(false);
const [openLogs, setOpenLogs] = useState(false);
const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow);
const uploadFlow = useUploadFlow();
const navigate = useNavigate();
const isBuilding = useFlowStore((state) => state.isBuilding);
const getTypes = useTypesStore((state) => state.getTypes);

function handleAddFlow() {
try {
addFlow(true).then((id) => {
addFlow().then((id) => {
navigate("/flow/" + id);
});
} catch (err) {
Expand Down Expand Up @@ -125,14 +127,18 @@ export const MenuBar = ({}: {}): JSX.Element => {
<DropdownMenuItem
className="cursor-pointer"
onClick={() => {
uploadFlow({ newProject: false, isComponent: false }).catch(
(error) => {
uploadFlow({ position: { x: 300, y: 100 } })
.then(() => {
setSuccessData({
title: "Uploaded successfully",
});
})
.catch((error) => {
setErrorData({
title: UPLOAD_ERROR_ALERT,
list: [error],
list: [(error as Error).message],
});
},
);
});
}}
>
<IconComponent name="FileUp" className="header-menu-options" />
Expand Down
88 changes: 36 additions & 52 deletions src/frontend/src/components/inputFileComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { usePostUploadFile } from "@/controllers/API/queries/files/use-post-upload-file";
import { useEffect, useState } from "react";
import { createFileUpload } from "@/helpers/create-file-upload";
import { useEffect } from "react";
import {
CONSOLE_ERROR_MSG,
INVALID_FILE_ALERT,
Expand All @@ -19,7 +20,6 @@ export default function InputFileComponent({
id,
}: FileComponentType): JSX.Element {
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
const [loading, setLoading] = useState(false);
const setErrorData = useAlertStore((state) => state.setErrorData);

// Clear component state
Expand All @@ -39,58 +39,42 @@ export default function InputFileComponent({
return false;
}

const { mutate } = usePostUploadFile();
const { mutate, isPending } = usePostUploadFile();

const handleButtonClick = (): void => {
// Create a file input element
const input = document.createElement("input");
document.body.appendChild(input);
input.type = "file";
input.accept = fileTypes?.join(",");
input.style.display = "none"; // Hidden from view
input.multiple = false; // Allow only one file selection
const onChangeFile = (event: Event): void => {
setLoading(true);
createFileUpload({ multiple: false, accept: fileTypes?.join(",") }).then(
(files) => {
const file = files[0];
if (file) {
if (checkFileType(file.name)) {
// Upload the file
mutate(
{ file, id: currentFlowId },
{
onSuccess: (data) => {
// Get the file name from the response
const { file_path } = data;

// Get the selected file
const file = (event.target as HTMLInputElement).files?.[0];

// Check if the file type is correct
if (file && checkFileType(file.name)) {
// Upload the file
mutate(
{ file, id: currentFlowId },
{
onSuccess: (data) => {
// Get the file name from the response
const { file_path } = data;

// sets the value that goes to the backend
// Update the state and on with the name of the file
// sets the value to the user
handleOnNewValue({ value: file.name, file_path });
setLoading(false);
},
onError: () => {
console.error(CONSOLE_ERROR_MSG);
setLoading(false);
},
},
);
} else {
// Show an error if the file type is not allowed
setErrorData({
title: INVALID_FILE_ALERT,
list: fileTypes,
});
setLoading(false);
}
};

input.addEventListener("change", onChangeFile);

// Trigger the file selection dialog
input.click();
// sets the value that goes to the backend
// Update the state and on with the name of the file
// sets the value to the user
handleOnNewValue({ value: file.name, file_path });
},
onError: () => {
console.error(CONSOLE_ERROR_MSG);
},
},
);
} else {
// Show an error if the file type is not allowed
setErrorData({
title: INVALID_FILE_ALERT,
list: fileTypes,
});
}
}
},
);
};

return (
Expand All @@ -114,7 +98,7 @@ export default function InputFileComponent({
unstyled
className="inline-flex items-center justify-center"
onClick={handleButtonClick}
loading={loading}
loading={isPending}
disabled={disabled}
>
<IconComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import {
usePostUploadFolders,
} from "@/controllers/API/queries/folders";
import { useGetDownloadFolders } from "@/controllers/API/queries/folders/use-get-download-folders";
import { createFileUpload } from "@/helpers/create-file-upload";
import { getObjectsFromFilelist } from "@/helpers/get-objects-from-filelist";
import useUploadFlow from "@/hooks/flows/use-upload-flow";
import { useEffect, useRef, useState } from "react";
import { useLocation } from "react-router-dom";
import { FolderType } from "../../../../pages/MainPage/entities";
Expand Down Expand Up @@ -55,6 +58,7 @@ const SideBarFoldersButtonsComponent = ({
const setErrorData = useAlertStore((state) => state.setErrorData);
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
const uploadFlow = useUploadFlow();

const handleFolderChange = () => {
getFolderById(folderId);
Expand All @@ -68,46 +72,41 @@ const SideBarFoldersButtonsComponent = ({
const { mutate } = usePostUploadFolders();

const handleUploadFlowsToFolder = () => {
const input = document.createElement("input");
input.type = "file";
input.accept = ".json";
input.click();

input.onchange = (event: Event) => {
if (
(event.target as HTMLInputElement).files![0].type === "application/json"
) {
const file = (event.target as HTMLInputElement).files![0];
const formData = new FormData();
formData.append("file", file);
file.text().then(async (text) => {
const data = JSON.parse(text);
if (data.data?.nodes) {
await useFlowsManagerStore.getState().addFlow(true, data);
createFileUpload().then((files: File[]) => {
getObjectsFromFilelist<any>(files).then((objects) => {
if (objects.every((flow) => flow.data?.nodes)) {
uploadFlow({ files }).then(() => {
getFolderById(folderId);
} else {
setSuccessData({
title: "Uploaded successfully",
});
});
} else {
files.forEach((folder) => {
const formData = new FormData();
formData.append("file", folder);
mutate(
{ formData },
{
onSuccess: () => {
getFolderById(folderId);
getFoldersApi(true);
setSuccessData({
title: "Uploaded successfully",
title: "Folder uploaded successfully.",
});
},
onError: (err) => {
console.log(err);
setErrorData({
title: `Error on upload`,
list: [err["response"]["data"]],
list: [err["response"]["data"]["message"]],
});
},
},
);
}
});
}
};
});
}
});
});
};

const { mutate: mutateDownloadFolder } = useGetDownloadFolders();
Expand Down
28 changes: 1 addition & 27 deletions src/frontend/src/controllers/API/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,32 +262,6 @@ export async function getFlowStylesFromDatabase() {
}
}

/**
* Saves a new flow style to the database.
*
* @param {FlowStyleType} flowStyle - The flow style data to save.
* @returns {Promise<any>} The saved flow style data.
* @throws Will throw an error if saving fails.
*/
export async function saveFlowStyleToDatabase(flowStyle: FlowStyleType) {
try {
const response = await api.post(`${BASE_URL_API}flow_styles/`, flowStyle, {
headers: {
accept: "application/json",
"Content-Type": "application/json",
},
});

if (response.status !== 201) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response?.data;
} catch (error) {
console.error(error);
throw error;
}
}

/**
* Fetches the version of the API.
*
Expand Down Expand Up @@ -508,7 +482,7 @@ export async function getStoreComponents({
limit = 9999999,
is_component = null,
sort = "-count(liked_by)",
tags = [] || null,
tags = [],
liked = null,
isPrivate = null,
search = null,
Expand Down
Loading
Loading