diff --git a/client/src/app/api/rest.ts b/client/src/app/api/rest.ts index b77d2d0f8f..157765a965 100644 --- a/client/src/app/api/rest.ts +++ b/client/src/app/api/rest.ts @@ -748,3 +748,16 @@ export const updateQuestionnaire = ( // TODO: of 204 - NoContext) ... the return type does not make sense. export const deleteQuestionnaire = (id: number): Promise => axios.delete(`${QUESTIONNAIRES}/${id}`); + +export const downloadStaticReport = ( + applicationId: number, + acceptHeader: string +) => + axios + .get(`${APPLICATIONS}/${applicationId}/analysis/report`, { + responseType: "blob", // Tell Axios to expect a binary response + headers: { + Accept: acceptHeader, + }, + }) + .then((response) => response.data); diff --git a/client/src/app/pages/applications/components/application-detail-drawer/components/download-button.tsx b/client/src/app/pages/applications/components/application-detail-drawer/components/download-button.tsx index 2dc4a7ff3b..1ae11b3b74 100644 --- a/client/src/app/pages/applications/components/application-detail-drawer/components/download-button.tsx +++ b/client/src/app/pages/applications/components/application-detail-drawer/components/download-button.tsx @@ -1,9 +1,10 @@ import React, { useState } from "react"; import { APPLICATIONS } from "@app/api/rest"; -import { Button } from "@patternfly/react-core"; +import { Alert, Button } from "@patternfly/react-core"; import spacing from "@patternfly/react-styles/css/utilities/Spacing/spacing"; import { Application } from "@app/api/models"; import { Spinner } from "@patternfly/react-core"; +import { useDownloadStaticReport } from "@app/queries/download"; export enum MimeType { TAR = "tar", @@ -16,66 +17,34 @@ function DownloadButton({ application: Application; mimeType: MimeType; }) { - const [isLoading, setIsLoading] = useState(false); + const downloadMutation = useDownloadStaticReport(); const handleDownload = async () => { - let acceptHeader = "application/x-tar"; - - switch (mimeType) { - case MimeType.YAML: - acceptHeader = "application/x-yaml"; - break; - case MimeType.TAR: - default: - acceptHeader = "application/x-tar"; - } - setIsLoading(true); - - try { - const response = await fetch( - `${APPLICATIONS}/${application?.id}/analysis/report`, - { - headers: { - Accept: acceptHeader, - }, - } - ); - - if (!response.ok) { - throw new Error("Network response was not ok when downloading file."); - } - - const blob = await response.blob(); - const url = window.URL.createObjectURL(blob); - const a = document.createElement("a"); - a.style.display = "none"; - a.href = url; - a.download = `analysis-${application.name}.` + mimeType; - - document.body.appendChild(a); - a.click(); - - window.URL.revokeObjectURL(url); - } catch (error) { - console.error("There was an error downloading the file:", error); - } finally { - setIsLoading(false); - } + downloadMutation.mutate({ + applicationId: application.id, + mimeType: mimeType, + }); }; return ( <> - {isLoading ? ( + {downloadMutation.isLoading ? ( + ) : downloadMutation.isError ? ( + +

{"An error has occurred. Try to download again."}

+
) : ( - + <> + + )} ); diff --git a/client/src/app/queries/download.ts b/client/src/app/queries/download.ts new file mode 100644 index 0000000000..4102882cf2 --- /dev/null +++ b/client/src/app/queries/download.ts @@ -0,0 +1,52 @@ +import axios from "axios"; +import { saveAs } from "file-saver"; +import { APPLICATIONS } from "@app/api/rest"; // Import your API endpoint +import { UseQueryOptions, useMutation, useQuery } from "@tanstack/react-query"; +import { MimeType } from "@app/pages/applications/components/application-detail-drawer/components/download-button"; + +interface DownloadOptions { + applicationId: number; + mimeType: MimeType; +} + +export const downloadStaticReport = async ({ + applicationId, + mimeType, +}: DownloadOptions): Promise => { + let acceptHeader = "application/x-tar"; + + switch (mimeType) { + case MimeType.YAML: + acceptHeader = "application/x-yaml"; + break; + case MimeType.TAR: + default: + acceptHeader = "application/x-tar"; + } + + try { + const response = await axios.get( + `${APPLICATIONS}/${applicationId}/analysis/report`, + { + responseType: "blob", + headers: { + Accept: acceptHeader, + }, + } + ); + + if (response.status !== 200) { + throw new Error("Network response was not ok when downloading file."); + } + + const blob = new Blob([response.data]); + saveAs(blob, `analysis-report.${acceptHeader.split("/")[1]}`); + } catch (error) { + console.error("There was an error downloading the file:", error); + throw error; // Rethrow the error to be captured by React Query + } +}; + +export const useDownloadStaticReport = () => { + return useMutation(downloadStaticReport); +};