diff --git a/webapp/public/locales/en/main.json b/webapp/public/locales/en/main.json index d6bbea522e..df948d3920 100644 --- a/webapp/public/locales/en/main.json +++ b/webapp/public/locales/en/main.json @@ -251,7 +251,6 @@ "study.district": "District", "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?", diff --git a/webapp/public/locales/fr/main.json b/webapp/public/locales/fr/main.json index 9ddb68910e..3dacacb6e0 100644 --- a/webapp/public/locales/fr/main.json +++ b/webapp/public/locales/fr/main.json @@ -251,7 +251,6 @@ "study.district": "District", "study.bindingconstraints": "Contraintes Couplantes", "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 ?", diff --git a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Text.tsx b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Text.tsx index 7380186bc3..e2b156dded 100644 --- a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Text.tsx +++ b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Text.tsx @@ -31,6 +31,8 @@ import DownloadButton from "../../../../../common/buttons/DownloadButton"; import { downloadFile } from "../../../../../../utils/fileUtils"; import { Filename, Flex, Menubar } from "./styles"; import UploadFileButton from "../../../../../common/buttons/UploadFileButton"; +import EmptyView from "@/components/common/page/SimpleContent"; +import GridOffIcon from "@mui/icons-material/GridOff"; SyntaxHighlighter.registerLanguage("xml", xml); SyntaxHighlighter.registerLanguage("plaintext", plaintext); @@ -42,6 +44,16 @@ const logsRegex = /^(\[[^\]]*\]){3}/; // Ex: "EXP : 0" const propertiesRegex = /^[^:]+ : [^:]+/; +function isEmptyContent(text: string | string[]): boolean { + if (Array.isArray(text)) { + return ( + text.length === 0 || + text.every((line) => typeof line === "string" && !line.trim()) + ); + } + return typeof text !== "string" || !text.trim(); +} + function getSyntaxProps(data: string | string[]): SyntaxHighlighterProps { const isArray = Array.isArray(data); const text = isArray ? data.join("\n") : data; @@ -111,24 +123,31 @@ function Text({ studyId, filePath, filename, canEdit }: DataCompProps) { onUploadSuccessful={handleUploadSuccessful} /> )} - - - - - + + {isEmptyContent(text) ? ( + + ) : ( + + + + )} )} /> diff --git a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Unsupported.tsx b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Unsupported.tsx index 59c4f48950..163235ba6f 100644 --- a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Unsupported.tsx +++ b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Unsupported.tsx @@ -40,10 +40,7 @@ function Unsupported({ studyId, filePath, filename }: DataCompProps) { const handleDownload = () => { if (res.data) { - downloadFile( - res.data, - filename.endsWith(".txt") ? filename : `${filename}.txt`, - ); + downloadFile(res.data, filename); } }; @@ -62,7 +59,6 @@ function Unsupported({ studyId, filePath, filename }: DataCompProps) { diff --git a/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts b/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts index d192aad6d9..f3176bc019 100644 --- a/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts +++ b/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts @@ -50,9 +50,17 @@ export interface DataCompProps extends FileInfo { } //////////////////////////////////////////////////////////////// -// File Info +// Utils //////////////////////////////////////////////////////////////// +const URL_SCHEMES = { + MATRIX: ["matrix://", "matrixfile://"], + JSON: ["json://"], + FILE: ["file://"], +} as const; + +const SUPPORTED_EXTENSIONS = [".txt", ".log", ".csv", ".tsv", ".ini"] as const; + // Maps file types to their corresponding icon components. const iconByFileType: Record = { matrix: DatasetIcon, @@ -88,17 +96,14 @@ export function getFileType(treeData: TreeData): FileType { } if (typeof treeData === "string") { - // Handle matrix files - if ( - treeData.startsWith("matrix://") || - treeData.startsWith("matrixfile://") - ) { + if (URL_SCHEMES.MATRIX.some((scheme) => treeData.startsWith(scheme))) { 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")) { + if ( + URL_SCHEMES.JSON.some((scheme) => treeData.startsWith(scheme)) || + treeData.endsWith(".json") + ) { return "json"; } @@ -106,27 +111,17 @@ export function getFileType(treeData: TreeData): FileType { // 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"; + if ( + URL_SCHEMES.FILE.some((scheme) => treeData.startsWith(scheme)) && + SUPPORTED_EXTENSIONS.some((ext) => treeData.endsWith(ext)) + ) { + return "text"; } } - // Default to text for any other string content - return "text"; + return "unsupported"; } -//////////////////////////////////////////////////////////////// -// Rights -//////////////////////////////////////////////////////////////// - /** * Checks if a study's file can be edited. *