Skip to content

Commit

Permalink
feat(ui-debug): add download of files in their original format
Browse files Browse the repository at this point in the history
  • Loading branch information
hdinia committed Dec 19, 2024
1 parent d8df7e9 commit 77c0cf9
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 42 deletions.
37 changes: 22 additions & 15 deletions webapp/src/components/App/Singlestudy/explore/Debug/Data/Json.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,39 @@ import { downloadFile } from "../../../../../../utils/fileUtils";
import { useEffect, useState } from "react";
import { Filename, Flex, Menubar } from "./styles";
import UploadFileButton from "../../../../../common/buttons/UploadFileButton";
import { getRawFile } from "@/services/api/studies/raw";

function Json({ filePath, filename, studyId, canEdit }: DataCompProps) {
const [t] = useTranslation();
const { enqueueSnackbar } = useSnackbar();
const [currentJson, setCurrentJson] = useState<JSONEditorProps["json"]>();

const res = usePromiseWithSnackbarError(
const fileRes = usePromiseWithSnackbarError(
() => getStudyData(studyId, filePath, -1),
{
errorMessage: t("studies.error.retrieveData"),
deps: [studyId, filePath],
},
);

const rawFileRes = usePromiseWithSnackbarError(
() => getRawFile(studyId, filePath),
{
errorMessage: t("studies.error.retrieveData"),
deps: [studyId, filePath],
},
);

useEffect(() => {
setCurrentJson(res.data);
}, [res.data]);
setCurrentJson(fileRes.data);
}, [fileRes.data]);

const handleDownload = () => {
if (rawFileRes.data) {
const { data, filename } = rawFileRes.data;
downloadFile(data, filename);
}
};

////////////////////////////////////////////////////////////////
// Event Handlers
Expand All @@ -58,17 +74,8 @@ function Json({ filePath, filename, studyId, canEdit }: DataCompProps) {
});
};

const handleDownload = () => {
if (currentJson !== undefined) {
downloadFile(
JSON.stringify(currentJson, null, 2),
filename.endsWith(".json") ? filename : `${filename}.json`,
);
}
};

const handleUploadSuccessful = () => {
res.reload();
fileRes.reload();
};

////////////////////////////////////////////////////////////////
Expand All @@ -77,7 +84,7 @@ function Json({ filePath, filename, studyId, canEdit }: DataCompProps) {

return (
<UsePromiseCond
response={res}
response={fileRes}
ifFulfilled={(json) => (
<Flex>
<Menubar>
Expand All @@ -93,7 +100,7 @@ function Json({ filePath, filename, studyId, canEdit }: DataCompProps) {
<DownloadButton onClick={handleDownload} />
</Menubar>
<JSONEditor
json={json}
json={currentJson ?? json}
modes={["tree", "code"]}
enableSort={false}
enableTransform={false}
Expand Down
29 changes: 18 additions & 11 deletions webapp/src/components/App/Singlestudy/explore/Debug/Data/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ 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";
import { getRawFile } from "@/services/api/studies/raw";

SyntaxHighlighter.registerLanguage("xml", xml);
SyntaxHighlighter.registerLanguage("plaintext", plaintext);
Expand Down Expand Up @@ -75,7 +76,7 @@ function Text({
const { t } = useTranslation();
const theme = useTheme();

const res = usePromiseWithSnackbarError(
const fileRes = usePromiseWithSnackbarError(
() =>
getStudyData<string>(studyId, filePath).then((text) =>
parseContent(text, { filePath, fileType }),
Expand All @@ -86,21 +87,27 @@ function Text({
},
);

////////////////////////////////////////////////////////////////
// Event Handlers
////////////////////////////////////////////////////////////////
const rawFileRes = usePromiseWithSnackbarError(
() => getRawFile(studyId, filePath),
{
errorMessage: t("studies.error.retrieveData"),
deps: [studyId, filePath],
},
);

const handleDownload = () => {
if (res.data) {
downloadFile(
res.data,
filename.endsWith(".txt") ? filename : `${filename}.txt`,
);
if (rawFileRes.data) {
const { data, filename } = rawFileRes.data;
downloadFile(data, filename);
}
};

////////////////////////////////////////////////////////////////
// Event Handlers
////////////////////////////////////////////////////////////////

const handleUploadSuccessful = () => {
res.reload();
fileRes.reload();
};

////////////////////////////////////////////////////////////////
Expand All @@ -109,7 +116,7 @@ function Text({

return (
<UsePromiseCond
response={res}
response={fileRes}
ifFulfilled={(text) => (
<Flex>
<Menubar>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ 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";
import { getRawFile } from "@/services/api/studies/raw";

function Unsupported({ studyId, filePath, filename, canEdit }: DataCompProps) {
const { t } = useTranslation();

const res = usePromiseWithSnackbarError(
() => getStudyData<string>(studyId, filePath),
const rawFileRes = usePromiseWithSnackbarError(
() => getRawFile(studyId, filePath),
{
errorMessage: t("studies.error.retrieveData"),
deps: [studyId, filePath],
Expand All @@ -39,15 +39,12 @@ function Unsupported({ studyId, filePath, filename, canEdit }: DataCompProps) {
////////////////////////////////////////////////////////////////

const handleDownload = () => {
if (res.data) {
downloadFile(res.data, filename);
if (rawFileRes.data) {
const { data, filename } = rawFileRes.data;
downloadFile(data, filename);
}
};

const handleUploadSuccessful = () => {
res.reload();
};

////////////////////////////////////////////////////////////////
// JSX
////////////////////////////////////////////////////////////////
Expand All @@ -56,13 +53,7 @@ function Unsupported({ studyId, filePath, filename, canEdit }: DataCompProps) {
<Flex>
<Menubar>
<Filename>{filename}</Filename>
{canEdit && (
<UploadFileButton
studyId={studyId}
path={filePath}
onUploadSuccessful={handleUploadSuccessful}
/>
)}
{canEdit && <UploadFileButton studyId={studyId} path={filePath} />}
<DownloadButton onClick={handleDownload} />
</Menubar>
<EmptyView icon={BlockIcon} title={t("study.debug.file.unsupported")} />
Expand Down
38 changes: 38 additions & 0 deletions webapp/src/services/api/studies/raw/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type {
DeleteFileParams,
DownloadMatrixParams,
ImportFileParams,
RawFile,
} from "./types";

export async function downloadMatrix(params: DownloadMatrixParams) {
Expand Down Expand Up @@ -51,3 +52,40 @@ export async function deleteFile(params: DeleteFileParams) {

await client.delete<void>(url, { params: { path } });
}

/**
* Reads an original raw file from a study with its metadata.
*
* @param studyId - Unique identifier of the study
* @param filePath - Path to the file within the study
* @returns Promise containing the file data and metadata
*/
export async function getRawFile(
studyId: string,
filePath: string,
): Promise<RawFile> {
const response = await client.get(
`/v1/studies/${studyId}/raw/original-file`,
{
params: {
path: filePath,
},
responseType: "blob",
},
);

const contentDisposition = response.headers["content-disposition"];
let filename = filePath.split("/").pop() || "file"; // fallback filename

if (contentDisposition) {
const matches = /filename=([^;]+)/.exec(contentDisposition);
if (matches?.[1]) {
filename = matches[1].replace(/"/g, "").trim();
}
}

return {
data: response.data,
filename: filename,
};
}
5 changes: 5 additions & 0 deletions webapp/src/services/api/studies/raw/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ export interface DeleteFileParams {
studyId: StudyMetadata["id"];
path: string;
}

export interface RawFile {
data: Blob;
filename: string;
}

0 comments on commit 77c0cf9

Please sign in to comment.