diff --git a/webapp/public/locales/en/main.json b/webapp/public/locales/en/main.json
index 952091b0d4..d6bbea522e 100644
--- a/webapp/public/locales/en/main.json
+++ b/webapp/public/locales/en/main.json
@@ -252,6 +252,7 @@
"study.bindingconstraints": "Binding Constraints",
"study.debug": "Debug",
"study.debug.file.image": "Image file",
+ "study.debug.file.unsupported": "Unsupported file type",
"study.debug.file.deleteConfirm.title": "Delete File?",
"study.debug.file.deleteConfirm.message": "Are you sure you want to delete the file?",
"study.debug.folder.empty": "Folder is empty",
diff --git a/webapp/public/locales/fr/main.json b/webapp/public/locales/fr/main.json
index 81ffca6679..9ddb68910e 100644
--- a/webapp/public/locales/fr/main.json
+++ b/webapp/public/locales/fr/main.json
@@ -253,6 +253,7 @@
"study.debug": "Debug",
"study.debug.file.image": "Fichier image",
"study.debug.folder.empty": "Le dossier est vide",
+ "study.debug.file.unsupported": "Type de fichier non supporté",
"study.debug.file.deleteConfirm.title": "Supprimer le fichier ?",
"study.debug.file.deleteConfirm.message": "Êtes-vous sûr de vouloir supprimer le fichier ?",
"study.debug.folder.upload.replaceFileConfirm.title": "Remplacer le fichier ?",
diff --git a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Image.tsx b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Image.tsx
deleted file mode 100644
index 23aa34e993..0000000000
--- a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Image.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Copyright (c) 2024, RTE (https://www.rte-france.com)
- *
- * See AUTHORS.txt
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * SPDX-License-Identifier: MPL-2.0
- *
- * This file is part of the Antares project.
- */
-
-import { useTranslation } from "react-i18next";
-import EmptyView from "../../../../../common/page/SimpleContent";
-import ImageIcon from "@mui/icons-material/Image";
-import { Filename, Flex, Menubar } from "./styles";
-import type { DataCompProps } from "../utils";
-
-function Image({ filename }: DataCompProps) {
- const { t } = useTranslation();
-
- return (
-
-
- {filename}
-
-
-
- );
-}
-
-export default Image;
diff --git a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Matrix.tsx b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Matrix.tsx
index a140fe71e8..26a211251d 100644
--- a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Matrix.tsx
+++ b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Matrix.tsx
@@ -15,7 +15,7 @@
import Matrix from "../../../../../common/Matrix";
import type { DataCompProps } from "../utils";
-function DebugMatrix({ studyId, filename, filePath, canEdit }: DataCompProps) {
+function DebugMatrix({ filename, filePath, canEdit }: DataCompProps) {
return ;
}
diff --git a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Unsupported.tsx b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Unsupported.tsx
new file mode 100644
index 0000000000..59c4f48950
--- /dev/null
+++ b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Unsupported.tsx
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2024, RTE (https://www.rte-france.com)
+ *
+ * See AUTHORS.txt
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This file is part of the Antares project.
+ */
+
+import { useTranslation } from "react-i18next";
+import EmptyView from "../../../../../common/page/SimpleContent";
+import BlockIcon from "@mui/icons-material/Block";
+import { Filename, Flex, Menubar } from "./styles";
+import type { DataCompProps } from "../utils";
+import DownloadButton from "@/components/common/buttons/DownloadButton";
+import UploadFileButton from "@/components/common/buttons/UploadFileButton";
+import usePromiseWithSnackbarError from "@/hooks/usePromiseWithSnackbarError";
+import { getStudyData } from "@/services/api/study";
+import { downloadFile } from "@/utils/fileUtils";
+
+function Unsupported({ studyId, filePath, filename }: DataCompProps) {
+ const { t } = useTranslation();
+
+ const res = usePromiseWithSnackbarError(
+ () => getStudyData(studyId, filePath),
+ {
+ errorMessage: t("studies.error.retrieveData"),
+ deps: [studyId, filePath],
+ },
+ );
+
+ ////////////////////////////////////////////////////////////////
+ // Event Handlers
+ ////////////////////////////////////////////////////////////////
+
+ const handleDownload = () => {
+ if (res.data) {
+ downloadFile(
+ res.data,
+ filename.endsWith(".txt") ? filename : `${filename}.txt`,
+ );
+ }
+ };
+
+ const handleUploadSuccessful = () => {
+ res.reload();
+ };
+
+ ////////////////////////////////////////////////////////////////
+ // JSX
+ ////////////////////////////////////////////////////////////////
+
+ return (
+
+
+ {filename}
+
+
+
+
+
+ );
+}
+
+export default Unsupported;
diff --git a/webapp/src/components/App/Singlestudy/explore/Debug/Data/index.tsx b/webapp/src/components/App/Singlestudy/explore/Debug/Data/index.tsx
index f387b7ef9c..de7e0ca24e 100644
--- a/webapp/src/components/App/Singlestudy/explore/Debug/Data/index.tsx
+++ b/webapp/src/components/App/Singlestudy/explore/Debug/Data/index.tsx
@@ -12,15 +12,16 @@
* This file is part of the Antares project.
*/
+import { ComponentType } from "react";
import Text from "./Text";
-import Image from "./Image";
-import Json from "./Json";
+import Unsupported from "./Unsupported";
import Matrix from "./Matrix";
import Folder from "./Folder";
import { canEditFile, type FileInfo, type FileType } from "../utils";
import type { DataCompProps } from "../utils";
import ViewWrapper from "../../../../../common/page/ViewWrapper";
import type { StudyMetadata } from "../../../../../../common/types";
+import Json from "./Json";
interface Props extends FileInfo {
study: StudyMetadata;
@@ -28,28 +29,23 @@ interface Props extends FileInfo {
reloadTreeData: () => void;
}
-type DataComponent = React.ComponentType;
-
-const componentByFileType: Record = {
+const componentByFileType: Record> = {
matrix: Matrix,
json: Json,
text: Text,
- image: Image,
+ unsupported: Unsupported,
folder: Folder,
} as const;
-function Data(props: Props) {
- const { study, setSelectedFile, reloadTreeData, ...fileInfo } = props;
- const { fileType, filePath } = fileInfo;
- const canEdit = canEditFile(study, filePath);
- const DataViewer = componentByFileType[fileType];
+function Data({ study, setSelectedFile, reloadTreeData, ...fileInfo }: Props) {
+ const DataViewer = componentByFileType[fileInfo.fileType];
return (
diff --git a/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts b/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts
index b1d8653f07..d192aad6d9 100644
--- a/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts
+++ b/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts
@@ -14,7 +14,7 @@
import DataObjectIcon from "@mui/icons-material/DataObject";
import TextSnippetIcon from "@mui/icons-material/TextSnippet";
-import ImageIcon from "@mui/icons-material/Image";
+import BlockIcon from "@mui/icons-material/Block";
import FolderIcon from "@mui/icons-material/Folder";
import DatasetIcon from "@mui/icons-material/Dataset";
import { SvgIconComponent } from "@mui/icons-material";
@@ -33,7 +33,7 @@ export interface TreeFolder {
export type TreeData = TreeFolder | TreeFile;
-export type FileType = "json" | "matrix" | "text" | "image" | "folder";
+export type FileType = "json" | "matrix" | "text" | "folder" | "unsupported";
export interface FileInfo {
fileType: FileType;
@@ -58,8 +58,8 @@ const iconByFileType: Record = {
matrix: DatasetIcon,
json: DataObjectIcon,
text: TextSnippetIcon,
- image: ImageIcon,
folder: FolderIcon,
+ unsupported: BlockIcon,
} as const;
/**
@@ -83,21 +83,44 @@ export function isFolder(treeData: TreeData): treeData is TreeFolder {
* @returns The corresponding file type.
*/
export function getFileType(treeData: TreeData): FileType {
+ if (isFolder(treeData)) {
+ return "folder";
+ }
+
if (typeof treeData === "string") {
+ // Handle matrix files
if (
treeData.startsWith("matrix://") ||
treeData.startsWith("matrixfile://")
) {
return "matrix";
}
+
+ // Handle files displayed as JSON by the API even though they are .ini files in the filesystem.
+ // The json:// prefix or .json extension indicates the content should be viewed as JSON.
if (treeData.startsWith("json://") || treeData.endsWith(".json")) {
return "json";
}
- if (treeData.startsWith("file://") && treeData.endsWith(".ico")) {
- return "image";
+
+ // Handle regular files with file:// prefix
+ // All files except matrices and json-formatted content use this prefix
+ // We filter to only allow extensions that can be properly displayed (.txt, .log, .csv, .tsv, .ini)
+ // Other extensions (like .RDS or .xlsx) are marked as unsupported since they can't be shown in the UI
+ if (treeData.startsWith("file://")) {
+ const supportedTextExtensions = [".txt", ".log", ".csv", ".tsv", ".ini"];
+
+ // Check if the file ends with any of the supported extensions
+ if (supportedTextExtensions.some((ext) => treeData.endsWith(ext))) {
+ return "text";
+ }
+
+ // Any other extension with file:// prefix is unsupported
+ return "unsupported";
}
}
- return isFolder(treeData) ? "folder" : "text";
+
+ // Default to text for any other string content
+ return "text";
}
////////////////////////////////////////////////////////////////