From ed37473b946c5753d5d0d6f70b9766e9279e89c6 Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa Date: Fri, 16 May 2025 14:55:46 -0300 Subject: [PATCH] feat: modularize folder download functionality with reusable utilities (#8084) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✨ (index.tsx): Add support for custom download folder functionality to improve file download process 📝 (use-get-download-folders.ts): Update useGetDownloadFolders function to use customGetDownloadTypeFolders for downloading folders 📝 (custom-get-download-folders.ts): Add customGetDownloadTypeFolders and customGetDownloadFolderBlob functions for handling custom download folder logic --- .../components/sideBarFolderButtons/index.tsx | 30 +++----------- .../folders/use-get-download-folders.ts | 9 +--- .../utils/custom-get-download-folders.ts | 41 +++++++++++++++++++ 3 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 src/frontend/src/customization/utils/custom-get-download-folders.ts diff --git a/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/index.tsx b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/index.tsx index fba0b6bb6..34d4e3f95 100644 --- a/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/index.tsx +++ b/src/frontend/src/components/core/folderSidebarComponent/components/sideBarFolderButtons/index.tsx @@ -30,6 +30,7 @@ import { } from "@/customization/feature-flags"; import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate"; import { track } from "@/customization/utils/analytics"; +import { customGetDownloadFolderBlob } from "@/customization/utils/custom-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"; @@ -169,35 +170,14 @@ const SideBarFoldersButtonsComponent = ({ }); }; - const handleDownloadFolder = (id: string) => { + const handleDownloadFolder = (id: string, folderName: string) => { mutateDownloadFolder( { folderId: id, }, { onSuccess: (response) => { - // Create a blob from the response data - const blob = new Blob([response.data], { - type: "application/x-zip-compressed", - }); - - const url = window.URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - - // Get filename from header or use default - const filename = - response.headers?.["content-disposition"] - ?.split("filename=")[1] - ?.replace(/['"]/g, "") ?? "flows.zip"; - - link.setAttribute("download", filename); - document.body.appendChild(link); - link.click(); - link.remove(); - window.URL.revokeObjectURL(url); - - track("Project Exported", { folderId: id }); + customGetDownloadFolderBlob(response, id, folderName, setSuccessData); }, onError: (e) => { setErrorData({ @@ -460,7 +440,9 @@ const SideBarFoldersButtonsComponent = ({ item={item} index={index} handleDeleteFolder={handleDeleteFolder} - handleDownloadFolder={handleDownloadFolder} + handleDownloadFolder={() => + handleDownloadFolder(item.id!, item.name) + } handleSelectFolderToRename={ handleSelectFolderToRename } diff --git a/src/frontend/src/controllers/API/queries/folders/use-get-download-folders.ts b/src/frontend/src/controllers/API/queries/folders/use-get-download-folders.ts index 4804c472b..4b3eec975 100644 --- a/src/frontend/src/controllers/API/queries/folders/use-get-download-folders.ts +++ b/src/frontend/src/controllers/API/queries/folders/use-get-download-folders.ts @@ -1,9 +1,9 @@ +import { customGetDownloadTypeFolders } from "@/customization/utils/custom-get-download-folders"; 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 IGetDownloadFolders { folderId: string; } @@ -19,12 +19,7 @@ export const useGetDownloadFolders: useMutationFunctionType< ): Promise => { const response = await api.get( `${getURL("PROJECTS")}/download/${payload.folderId}`, - { - responseType: "blob", - headers: { - Accept: "application/x-zip-compressed", - }, - }, + customGetDownloadTypeFolders(), ); return response; }; diff --git a/src/frontend/src/customization/utils/custom-get-download-folders.ts b/src/frontend/src/customization/utils/custom-get-download-folders.ts new file mode 100644 index 000000000..4ed7e23a7 --- /dev/null +++ b/src/frontend/src/customization/utils/custom-get-download-folders.ts @@ -0,0 +1,41 @@ +import { AxiosRequestConfig, ResponseType } from "axios"; +import { track } from "./analytics"; + +export const customGetDownloadTypeFolders = (): AxiosRequestConfig => { + return { + responseType: "blob" as ResponseType, + headers: { + Accept: "application/x-zip-compressed", + }, + }; +}; + +export const customGetDownloadFolderBlob = ( + response: any, + id: string, + folderName?: string, + setSuccessData?: (data: any) => void, +) => { + // Create a blob from the response data + const blob = new Blob([response.data], { + type: "application/x-zip-compressed", + }); + + const url = window.URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + + // Get filename from header or use default + const filename = + response.headers?.["content-disposition"] + ?.split("filename=")[1] + ?.replace(/['"]/g, "") ?? "flows.zip"; + + link.setAttribute("download", filename); + document.body.appendChild(link); + link.click(); + link.remove(); + window.URL.revokeObjectURL(url); + + track("Project Exported", { folderId: id }); +};