diff --git a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Folder.tsx b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Folder.tsx index 88c1aaea1e..99d1e08f46 100644 --- a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Folder.tsx +++ b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Folder.tsx @@ -33,7 +33,7 @@ import { type TreeFolder, type DataCompProps, isFolder, - canEditFile, + isProtected, } from "../utils"; import { Fragment, useState } from "react"; import EmptyView from "../../../../../common/page/SimpleContent"; @@ -45,8 +45,6 @@ import useConfirm from "../../../../../../hooks/useConfirm"; import { deleteFile } from "../../../../../../services/api/studies/raw"; import useEnqueueErrorSnackbar from "../../../../../../hooks/useEnqueueErrorSnackbar"; import { toError } from "../../../../../../utils/fnUtils"; -import { useOutletContext } from "react-router"; -import type { StudyMetadata } from "../../../../../../common/types"; import { useSnackbar } from "notistack"; function Folder(props: DataCompProps) { @@ -54,14 +52,12 @@ function Folder(props: DataCompProps) { filename, filePath, treeData, - canEdit, setSelectedFile, reloadTreeData, studyId, } = props; const { t } = useTranslation(); - const { study } = useOutletContext<{ study: StudyMetadata }>(); const replaceAction = useConfirm(); const deleteAction = useConfirm(); const { enqueueSnackbar } = useSnackbar(); @@ -126,14 +122,12 @@ function Folder(props: DataCompProps) { {filename} - {canEdit && ( - `${filePath}/${file.name}`} - onUploadSuccessful={reloadTreeData} - validate={handleValidateUpload} - /> - )} + `${filePath}/${file.name}`} + onUploadSuccessful={reloadTreeData} + validate={handleValidateUpload} + /> } @@ -159,7 +153,7 @@ function Folder(props: DataCompProps) { - - - {t("global.delete")} - + {menuData && !isProtected(menuData.filePath) && ( + + + {t("global.delete")} + + )} {/* Confirm file replacement */} (); @@ -82,14 +82,12 @@ function Json({ filePath, filename, studyId, canEdit }: DataCompProps) { {filename} - {canEdit && ( - - )} + ; +function DebugMatrix({ filename, filePath }: DataCompProps) { + return ; } export default DebugMatrix; 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 f2ac0a31e1..cc36cb33dd 100644 --- a/webapp/src/components/App/Singlestudy/explore/Debug/Data/Text.tsx +++ b/webapp/src/components/App/Singlestudy/explore/Debug/Data/Text.tsx @@ -75,7 +75,7 @@ function getSyntaxProps(data: string | string[]): SyntaxHighlighterProps { }; } -function Text({ studyId, filePath, filename, canEdit }: DataCompProps) { +function Text({ studyId, filePath, filename }: DataCompProps) { const { t } = useTranslation(); const theme = useTheme(); @@ -115,20 +115,18 @@ function Text({ studyId, filePath, filename, canEdit }: DataCompProps) { {filename} - {canEdit && ( - - )} + - {isEmptyContent(text) ? ( + {isEmptyContent(text) ? ( // TODO: remove this when the files become editable ) : ( 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 de7e0ca24e..35e1994da9 100644 --- a/webapp/src/components/App/Singlestudy/explore/Debug/Data/index.tsx +++ b/webapp/src/components/App/Singlestudy/explore/Debug/Data/index.tsx @@ -17,7 +17,7 @@ import Text from "./Text"; import Unsupported from "./Unsupported"; import Matrix from "./Matrix"; import Folder from "./Folder"; -import { canEditFile, type FileInfo, type FileType } from "../utils"; +import { type FileInfo, type FileType } from "../utils"; import type { DataCompProps } from "../utils"; import ViewWrapper from "../../../../../common/page/ViewWrapper"; import type { StudyMetadata } from "../../../../../../common/types"; @@ -45,7 +45,6 @@ function Data({ study, setSelectedFile, reloadTreeData, ...fileInfo }: Props) { diff --git a/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts b/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts index f0e9c428b8..3884f08eea 100644 --- a/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts +++ b/webapp/src/components/App/Singlestudy/explore/Debug/utils.ts @@ -19,7 +19,6 @@ import FolderIcon from "@mui/icons-material/Folder"; import DatasetIcon from "@mui/icons-material/Dataset"; import { SvgIconComponent } from "@mui/icons-material"; import * as RA from "ramda-adjunct"; -import type { StudyMetadata } from "../../../../../common/types"; //////////////////////////////////////////////////////////////// // Types @@ -44,7 +43,6 @@ export interface FileInfo { export interface DataCompProps extends FileInfo { studyId: string; - canEdit: boolean; setSelectedFile: (file: FileInfo) => void; reloadTreeData: () => void; } @@ -59,7 +57,14 @@ const URL_SCHEMES = { FILE: "file://", } as const; -const SUPPORTED_EXTENSIONS = [".txt", ".log", ".csv", ".tsv", ".ini"] as const; +const SUPPORTED_EXTENSIONS = [ + ".txt", + ".log", + ".csv", + ".tsv", + ".ini", + ".yml", +] as const; // Maps file types to their corresponding icon components. const iconByFileType: Record = { @@ -108,29 +113,22 @@ 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(URL_SCHEMES.FILE) && + return treeData.startsWith(URL_SCHEMES.FILE) && SUPPORTED_EXTENSIONS.some((ext) => treeData.endsWith(ext)) - ) { - return "text"; - } + ? "text" + : "unsupported"; } - return "unsupported"; + return "text"; } /** - * Checks if a study's file can be edited. + * Checks if a path is protected from deletion * - * @param study - The study where the file is located. - * @param filePath - The path of the file. - * @returns True if the file can be edited, false otherwise. + * @param path - Path to check + * @returns Whether the path is protected */ -export function canEditFile(study: StudyMetadata, filePath: string): boolean { - return ( - !study.archived && - (filePath === "user" || filePath.startsWith("user/")) && - // To remove when Xpansion tool configuration will be moved to "input/expansion" directory - !(filePath === "user/expansion" || filePath.startsWith("user/expansion/")) - ); +export function isProtected(path: string): boolean { + // user/expansion folder and its contents must not be deleted + return path === "user/expansion" || path.startsWith("user/expansion/"); }