Skip to content

Commit

Permalink
refactor: add new use-query endpoint of upload files (langflow-ai#2533)
Browse files Browse the repository at this point in the history
* refactor: add new use-query endpoint of upload files

* extend type for payload callbackSuccess

* [autofix.ci] apply automated fixes

* bugfix: drag and drop image on chat not working

* Refactored query function to use Options

* Used dedicated function as queryFn

* ✨ (API): export use-post-upload-file in files index
♻️ (FileInput): refactor file upload mutation to use onSuccess and onError
♻️ (chatInput): refactor file upload mutation to use onSuccess and onError
♻️ (chatView): refactor file upload mutation to use onSuccess and onError

* ♻️ (use-get-download-images.ts): simplify getDownloadImagesFn function
♻️ (use-get-transactions.ts): simplify getTransactionsFn function
✨ (use-handle-file-change.tsx): add hook to handle file input changes
✨ (use-upload.tsx): add hook to handle file paste events

* Added type on Request Processor

---------

Co-authored-by: anovazzi1 <otavio2204@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Lucas Oliveira <lucas.edu.oli@hotmail.com>
(cherry picked from commit bfaac8b)
  • Loading branch information
Cristhianzl authored and nicoloboschi committed Jul 10, 2024

Verified

This commit was signed with the committer’s verified signature.
nicoloboschi Nicolò Boschi
1 parent f57fa54 commit 7f97c3d
Show file tree
Hide file tree
Showing 20 changed files with 362 additions and 184 deletions.
1 change: 0 additions & 1 deletion src/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export default function App() {
const dark = useDarkStore((state) => state.dark);

const isLoadingFolders = useFolderStore((state) => state.isLoadingFolders);
useGetVersionQuery(undefined, "updateState");

const [isLoadingHealth, setIsLoadingHealth] = useState(false);
useEffect(() => {
Expand Down
40 changes: 23 additions & 17 deletions src/frontend/src/components/inputFileComponent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { usePostUploadFile } from "@/controllers/API/queries/files/use-post-upload-file";
import { useEffect, useState } from "react";
import {
CONSOLE_ERROR_MSG,
Expand Down Expand Up @@ -46,6 +47,8 @@ export default function InputFileComponent({
setMyValue(value);
}, [value]);

const mutation = usePostUploadFile();

const handleButtonClick = (): void => {
// Create a file input element
const input = document.createElement("input");
Expand All @@ -63,24 +66,27 @@ export default function InputFileComponent({
// Check if the file type is correct
if (file && checkFileType(file.name)) {
// Upload the file
uploadFile(file, currentFlowId)
.then((res) => res.data)
.then((data) => {
// Get the file name from the response
const { file_path } = data;
mutation.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
onFileChange(file_path);
// Update the state and callback with the name of the file
// sets the value to the user
setMyValue(file.name);
onChange(file.name);
setLoading(false);
})
.catch(() => {
console.error(CONSOLE_ERROR_MSG);
setLoading(false);
});
// sets the value that goes to the backend
onFileChange(file_path);
// Update the state and on with the name of the file
// sets the value to the user
setMyValue(file.name);
onChange(file.name);
setLoading(false);
},
onError: () => {
console.error(CONSOLE_ERROR_MSG);
setLoading(false);
},
},
);
} else {
// Show an error if the file type is not allowed
setErrorData({
Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/controllers/API/helpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { BASE_URL_API } from "../../../constants/constants";
export const URLs = {
TRANSACTIONS: `monitor/transactions`,
API_KEY: `api_key`,
FILES: `files`,
VERSION: `version`,
} as const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ interface IPostAddApiKey {
}

// add types for error handling and success
export const usePostAddApiKey: useMutationFunctionType<IPostAddApiKey> = ({
callbackSuccess,
callbackError,
}) => {
export const usePostAddApiKey: useMutationFunctionType<IPostAddApiKey> = (
options,
) => {
const { mutate } = UseRequestProcessor();

const postAddApiKeyFn = async (payload: IPostAddApiKey): Promise<any> => {
Expand All @@ -27,18 +26,7 @@ export const usePostAddApiKey: useMutationFunctionType<IPostAddApiKey> = ({
const res = await postAddApiKeyFn(payload);
return res.data;
},
{
onError: (err) => {
if (callbackError) {
callbackError(err);
}
},
onSuccess: (data) => {
if (callbackSuccess) {
callbackSuccess(data);
}
},
},
options,
);

return mutation;
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/controllers/API/queries/files/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./use-get-download-images";
export * from "./use-get-profile-pictures";
export * from "./use-post-upload-file";
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { keepPreviousData } from "@tanstack/react-query";
import { useQueryFunctionType } from "../../../../types/api";
import { api } from "../../api";
import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor";

interface DownloadImagesQueryParams {
flowId: string;
fileName: string;
}

export interface DownloadImagesResponse {
response: string;
}

export const useGetDownloadImagesQuery: useQueryFunctionType<
DownloadImagesQueryParams,
DownloadImagesResponse
> = ({ flowId, fileName }) => {
const { query } = UseRequestProcessor();

const getDownloadImagesFn = async () => {
const response = await api.get<DownloadImagesResponse>(
`${getURL("FILES")}/images/${flowId}/${fileName}`,
);
return response["data"];
};

const queryResult = query(
["useGetDownloadImagesQuery"],
getDownloadImagesFn,
{
placeholderData: keepPreviousData,
},
);

return queryResult;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { keepPreviousData } from "@tanstack/react-query";
import { useQueryFunctionType } from "../../../../types/api";
import { api } from "../../api";
import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor";

interface ProfilePicturesQueryParams {}

export interface ProfilePicturesResponse {
files: string[];
}

export const useGetProfilePicturesQuery: useQueryFunctionType<
ProfilePicturesQueryParams,
ProfilePicturesResponse
> = () => {
const { query } = UseRequestProcessor();

const getProfilePicturesFn = async () => {
const response = await api.get<ProfilePicturesResponse>(
`${getURL("FILES")}/profile_pictures/list`,
);

return response.data;
};

const queryResult = query(
["useGetProfilePicturesQuery"],
getProfilePicturesFn,
{
placeholderData: keepPreviousData,
},
);

return queryResult;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useMutationFunctionType } from "@/types/api";
import { UseMutationResult } from "@tanstack/react-query";
import { api } from "../../api";
import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor";

interface IPostUploadFile {
file: File;
id: string;
}

export const usePostUploadFile: useMutationFunctionType<IPostUploadFile> = (
options?,
) => {
const { mutate } = UseRequestProcessor();

const postUploadFileFn = async (payload: IPostUploadFile): Promise<any> => {
const formData = new FormData();
formData.append("file", payload.file);

const response = await api.post<any>(
`${getURL("FILES")}/upload/${payload.id}`,
formData,
);

return response.data;
};

const mutation: UseMutationResult<IPostUploadFile, any, IPostUploadFile> =
mutate(
["usePostUploadFile"],
async (payload: IPostUploadFile) => {
const res = await postUploadFileFn(payload);
return res;
},
options,
);

return mutation;
};
Original file line number Diff line number Diff line change
Expand Up @@ -39,29 +39,24 @@ export const useGetTransactionsQuery: useQueryFunctionType<
}
};

const getTransactionsFn = async (id: string, params = {}) => {
const getTransactionsFn = async () => {
const config = {};
config["params"] = { flow_id: id };
if (params) {
config["params"] = { ...config["params"], ...params };
}

return await api.get<TransactionsResponse>(
const rows = await api.get<TransactionsResponse>(
`${getURL("TRANSACTIONS")}`,
config,
);

return responseFn(rows);
};

const queryResult = query(
["useGetTransactionsQuery"],
async () => {
const rows = await getTransactionsFn(id, params);
return responseFn(rows);
},
{
placeholderData: keepPreviousData,
},
);
const queryResult = query(["useGetTransactionsQuery"], getTransactionsFn, {
placeholderData: keepPreviousData,
});

return queryResult;
};
25 changes: 21 additions & 4 deletions src/frontend/src/controllers/API/services/request-processor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
useMutation,
UseMutationOptions,
useQuery,
useQueryClient,
UseQueryOptions,
} from "@tanstack/react-query";
import { MutationFunctionType, QueryFunctionType } from "../../../types/api";

export function UseRequestProcessor(): {
Expand All @@ -7,19 +13,30 @@ export function UseRequestProcessor(): {
} {
const queryClient = useQueryClient();

function query(queryKey, queryFn, options = {}) {
function query(
queryKey: UseQueryOptions["queryKey"],
queryFn: UseQueryOptions["queryFn"],
options: Omit<UseQueryOptions, "queryFn" | "queryKey"> = {},
) {
return useQuery({
queryKey,
queryFn,
...options,
});
}

function mutate(mutationKey, mutationFn, options = {}) {
function mutate(
mutationKey: UseMutationOptions["mutationKey"],
mutationFn: UseMutationOptions["mutationFn"],
options: Omit<UseMutationOptions, "mutationFn" | "mutationKey"> = {},
) {
return useMutation({
mutationKey,
mutationFn,
onSettled: () => queryClient.invalidateQueries(mutationKey),
onSettled: (data, error, variables, context) => {
queryClient.invalidateQueries({ queryKey: mutationKey });
options.onSettled && options.onSettled(data, error, variables, context);
},
...options,
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Button } from "../../../../../../components/ui/button";

import { usePostUploadFile } from "@/controllers/API/queries/files/use-post-upload-file";
import { useEffect, useState } from "react";
import IconComponent from "../../../../../../components/genericIconComponent";
import { BASE_URL_API } from "../../../../../../constants/constants";
Expand Down Expand Up @@ -66,6 +67,8 @@ export default function IOFileInput({ field, updateValue }: IOFileInputProps) {
setIsDragging(false);
};

const mutation = usePostUploadFile();

const upload = async (file) => {
if (file) {
// Check if a file was selected
Expand All @@ -80,17 +83,18 @@ export default function IOFileInput({ field, updateValue }: IOFileInputProps) {
document.body.appendChild(imgElement); // Add the image to the body or replace this with your desired location
};
fileReader.readAsDataURL(file);

uploadFile(file, currentFlowId)
.then((res) => res.data)
.then((data) => {
// Get the file name from the response
const { file_path, flowId } = data;
setFilePath(file_path);
})
.catch(() => {
console.error("Error occurred while uploading file");
});
mutation.mutate(
{ file, id: currentFlowId },
{
onSuccess: (data) => {
const { file_path } = data;
setFilePath(file_path);
},
onError: () => {
console.error("Error occurred while uploading file");
},
},
);
}
};

Expand Down
Loading

0 comments on commit 7f97c3d

Please sign in to comment.