Skip to content

Commit

Permalink
Move logic out of presentation layer and use file-saver
Browse files Browse the repository at this point in the history
Signed-off-by: ibolton336 <ibolton@redhat.com>
  • Loading branch information
ibolton336 committed Aug 29, 2023
1 parent 1ba754e commit fab4e47
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 53 deletions.
13 changes: 13 additions & 0 deletions client/src/app/api/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -748,3 +748,16 @@ export const updateQuestionnaire = (
// TODO: of 204 - NoContext) ... the return type does not make sense.
export const deleteQuestionnaire = (id: number): Promise<Questionnaire> =>
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);
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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 ? (
<Spinner size="sm" />
) : downloadMutation.isError ? (
<Alert variant="warning" isInline title={"Error downloading report"}>
<p>{"An error has occurred. Try to download again."}</p>
</Alert>
) : (
<Button
onClick={handleDownload}
id={`download-${mimeType}-button`}
variant="link"
className={spacing.pXs}
>
{mimeType === MimeType.YAML ? "YAML" : "Report"}
</Button>
<>
<Button
onClick={handleDownload}
id={`download-${mimeType}-button`}
variant="link"
className={spacing.pXs}
>
{mimeType === MimeType.YAML ? "YAML" : "Report"}
</Button>
</>
)}
</>
);
Expand Down
52 changes: 52 additions & 0 deletions client/src/app/queries/download.ts
Original file line number Diff line number Diff line change
@@ -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<void> => {
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);
};

0 comments on commit fab4e47

Please sign in to comment.