diff --git a/frontend/src/components/FileField.tsx b/frontend/src/components/FileField.tsx index a97a1747f5bbb1efcc13134c7143ec0d9bf439a9_ZnJvbnRlbmQvc3JjL2NvbXBvbmVudHMvRmlsZUZpZWxkLnRzeA==..7f50dc6cef5f423f927a262fa69bfe03b9f72097_ZnJvbnRlbmQvc3JjL2NvbXBvbmVudHMvRmlsZUZpZWxkLnRzeA== 100644 --- a/frontend/src/components/FileField.tsx +++ b/frontend/src/components/FileField.tsx @@ -3,7 +3,7 @@ import Visibility from "@mui/icons-material/Visibility"; import { ChangeEventHandler, useRef } from "react"; import { CWFile } from "@/types"; -import { downloadFile, getFileNameFromURL, openFile } from "@/utils"; +import { getFileDownloadUrl, getFileNameFromURL } from "@/utils"; import { ButtonTooltip } from "./ButtonTooltip"; interface FileFieldProps { @@ -21,15 +21,6 @@ }: FileFieldProps) { const ref = useRef<HTMLInputElement>(null); - const onPressOpen = async () => { - let fileToOpen = value?.data as Blob; - // The file is available on the server, fetch it - if (!fileToOpen && value?.downloadUrl) { - fileToOpen = await downloadFile(value.downloadUrl); - } - openFile(fileToOpen); - }; - const chooseFile = () => { ref.current?.click(); }; @@ -46,6 +37,6 @@ function getFileName() { if (value?.data) { - return `(${value.data.name})`; + return `${value.data.name}`; } if (value?.downloadUrl) { @@ -50,6 +41,6 @@ } if (value?.downloadUrl) { - return `(${getFileNameFromURL(value?.downloadUrl)})`; + return `${getFileNameFromURL(value?.downloadUrl)}`; } return ""; } @@ -73,7 +64,7 @@ > {label} {filePresent - ? ` ${getFileName()}: Modifier le fichier` + ? ` (${getFileName()}): Modifier le fichier` : " : Choisir un fichier"} </Button> <ButtonTooltip @@ -84,7 +75,8 @@ <Button startIcon={<Visibility />} disabled={disabled || !filePresent} - onClick={onPressOpen} + href={getFileDownloadUrl(value)} + download={getFileName()} > Voir </Button> diff --git a/frontend/src/components/ImportProcessTable.tsx b/frontend/src/components/ImportProcessTable.tsx index a97a1747f5bbb1efcc13134c7143ec0d9bf439a9_ZnJvbnRlbmQvc3JjL2NvbXBvbmVudHMvSW1wb3J0UHJvY2Vzc1RhYmxlLnRzeA==..7f50dc6cef5f423f927a262fa69bfe03b9f72097_ZnJvbnRlbmQvc3JjL2NvbXBvbmVudHMvSW1wb3J0UHJvY2Vzc1RhYmxlLnRzeA== 100644 --- a/frontend/src/components/ImportProcessTable.tsx +++ b/frontend/src/components/ImportProcessTable.tsx @@ -23,6 +23,5 @@ import { useGetImportProcesses } from "@/hooks/useGetImportProcesses"; import { ErrorScreen } from "./ErrorScreen"; import { LoadingScreen } from "./LoadingScreen"; -import { downloadFile, openFile } from "@/utils"; import { ButtonTooltip } from "./ButtonTooltip"; import { useState, useEffect } from "react"; @@ -27,5 +26,6 @@ import { ButtonTooltip } from "./ButtonTooltip"; import { useState, useEffect } from "react"; +import { getFileNameFromURL } from "@/utils"; export interface ImportProcessTableProps { dataServiceEid?: number; @@ -34,15 +34,6 @@ showProjectColumn?: boolean; } -async function showFile(url?: string) { - if (url) { - const fileToOpen = await downloadFile(url); - openFile(fileToOpen); - } else { - console.error("No file to open"); - } -} - const REFRESH_INTERVAL = 5000; export function ImportProcessTable(props: ImportProcessTableProps) { @@ -141,7 +132,8 @@ <IconButton color="primary" disabled={!hasLog} - onClick={() => showFile(importProcess.log_url)} + href={importProcess.log_url ?? ""} + download={getFileNameFromURL(importProcess.log_url)} > {hasLog ? <Visibility /> : <VisibilityOff />} </IconButton> @@ -190,26 +182,18 @@ "aria-labelledby": "dataset-menu", }} > - <MenuItem - onClick={() => { - showFile(importProcess.input_dataset_url); - handleClose(); - }} - disabled={importProcess.input_dataset_url == null} - > - Entrée - </MenuItem> - <MenuItem - onClick={() => { - showFile(importProcess.output_dataset_url); - handleClose(); - }} - disabled={importProcess.output_dataset_url == null} - > - Sortie - </MenuItem> + <DatasetMenuItem + text="Entrée" + url={importProcess.input_dataset_url} + onClick={handleClose} + /> + <DatasetMenuItem + text="Sortie" + url={importProcess.output_dataset_url} + onClick={handleClose} + /> </Menu> </TableCell> ); } @@ -211,8 +195,42 @@ </Menu> </TableCell> ); } +function DatasetMenuItem({ + text, + url, + onClick, +}: { + text: string; + url?: string; + onClick: () => void; +}) { + if (!url) { + return ( + <MenuItem onClick={onClick} disabled={true}> + {text} + </MenuItem> + ); + } + + // Putting href and download props directly on the MenuItem does not work + return ( + <a + href={url} + download={getFileNameFromURL(url)} + style={{ + color: "inherit", + textDecoration: "inherit", + }} + > + <MenuItem onClick={onClick} disabled={false}> + {text} + </MenuItem> + </a> + ); +} + function ShaclButton({ importProcess }: { importProcess: ImportProcess }) { if (importProcess.shacl_valid) { return ( @@ -236,7 +254,8 @@ <ButtonTooltip title={"Voir le rapport d'erreur SHACL"}> <IconButton color="primary" - onClick={() => showFile(importProcess.shacl_report_url)} + href={importProcess.shacl_report_url ?? ""} + download={getFileNameFromURL(importProcess.shacl_report_url)} > <Visibility color="warning" /> </IconButton> diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts index a97a1747f5bbb1efcc13134c7143ec0d9bf439a9_ZnJvbnRlbmQvc3JjL3V0aWxzLnRz..7f50dc6cef5f423f927a262fa69bfe03b9f72097_ZnJvbnRlbmQvc3JjL3V0aWxzLnRz 100644 --- a/frontend/src/utils.ts +++ b/frontend/src/utils.ts @@ -1,7 +1,6 @@ -export function openFile(file?: Blob) { - if (file) { - const url = URL.createObjectURL(file); - window.open(url); - } else { - console.warn("No file available either locally or on the server"); +import { CWFile } from "./types"; + +export function getFileDownloadUrl(file?: CWFile): string { + if (file?.data) { + return URL.createObjectURL(file.data); } @@ -7,3 +6,7 @@ } + if (file?.downloadUrl) { + return file.downloadUrl; + } + return ""; } @@ -8,12 +11,8 @@ } -export async function downloadFile(url: string) { - const response = await fetch(url, { - credentials: "include", - }); - return await response.blob(); -} - -export function getFileNameFromURL(url: string): string { +export function getFileNameFromURL(url?: string): string { + if (!url) { + return ""; + } return url.slice(url.lastIndexOf("/") + 1); }