Skip to content

Commit

Permalink
feat(ui-debug): add download in original file format (#2277)
Browse files Browse the repository at this point in the history
  • Loading branch information
hdinia authored Dec 20, 2024
1 parent 4b68b03 commit ca0582b
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 83 deletions.
1 change: 1 addition & 0 deletions webapp/public/locales/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"global.date": "Date",
"global.general": "General",
"global.files": "Files",
"global.rawFile": "Raw file",
"global.none": "None",
"global.upload": "Upload",
"global.key": "Key",
Expand Down
1 change: 1 addition & 0 deletions webapp/public/locales/fr/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"global.date": "Date",
"global.general": "Général",
"global.files": "Fichiers",
"global.rawFile": "Fichier brut",
"global.none": "Aucun",
"global.upload": "Charger",
"global.key": "Clé",
Expand Down
31 changes: 10 additions & 21 deletions webapp/src/components/App/Singlestudy/explore/Debug/Data/Json.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,54 +21,43 @@ import UsePromiseCond from "../../../../../common/utils/UsePromiseCond";
import type { DataCompProps } from "../utils";
import DownloadButton from "../../../../../common/buttons/DownloadButton";
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 jsonRes = usePromiseWithSnackbarError(
() => getStudyData(studyId, filePath, -1),
{
errorMessage: t("studies.error.retrieveData"),
deps: [studyId, filePath],
},
);

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

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

const handleDownload = async () => {
const file = await getRawFile({ studyId, path: filePath });
downloadFile(file, file.name);
};

const handleSave: JSONEditorProps["onSave"] = (json) => {
return editStudy(json, studyId, filePath);
};

const handleSaveSuccessful: JSONEditorProps["onSaveSuccessful"] = (json) => {
setCurrentJson(json);

const handleSaveSuccessful: JSONEditorProps["onSaveSuccessful"] = () => {
enqueueSnackbar(t("studies.success.saveData"), {
variant: "success",
});
};

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

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

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

return (
<UsePromiseCond
response={res}
response={jsonRes}
ifFulfilled={(json) => (
<Flex>
<Menubar>
Expand Down
17 changes: 7 additions & 10 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 textRes = usePromiseWithSnackbarError(
() =>
getStudyData<string>(studyId, filePath).then((text) =>
parseContent(text, { filePath, fileType }),
Expand All @@ -90,17 +91,13 @@ function Text({
// Event Handlers
////////////////////////////////////////////////////////////////

const handleDownload = () => {
if (res.data) {
downloadFile(
res.data,
filename.endsWith(".txt") ? filename : `${filename}.txt`,
);
}
const handleDownload = async () => {
const file = await getRawFile({ studyId, path: filePath });
downloadFile(file, file.name);
};

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

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

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

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

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

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

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

const handleUploadSuccessful = () => {
res.reload();
const handleDownload = async () => {
const file = await getRawFile({ studyId, path: filePath });
downloadFile(file, file.name);
};

////////////////////////////////////////////////////////////////
Expand All @@ -56,13 +42,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
5 changes: 3 additions & 2 deletions webapp/src/components/common/Matrix/hooks/useMatrix/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {
} from "../../shared/utils";
import useUndo from "use-undo";
import { GridCellKind } from "@glideapps/glide-data-grid";
import { importFile } from "../../../../../services/api/studies/raw";
import { uploadFile } from "../../../../../services/api/studies/raw";
import { fetchMatrixFn } from "../../../../App/Singlestudy/explore/Modelization/Areas/Hydro/utils";
import usePrompt from "../../../../../hooks/usePrompt";
import { Aggregate, Column, Operation } from "../../shared/constants";
Expand Down Expand Up @@ -251,7 +251,8 @@ export function useMatrix(

const handleUpload = async (file: File) => {
try {
await importFile({ file, studyId, path: url });
await uploadFile({ file, studyId, path: url });
// TODO: update the API to return the uploaded file data and remove this
await fetchMatrix();
} catch (e) {
enqueueErrorSnackbar(t("matrix.error.import"), e as Error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,15 @@ describe("useMatrix", () => {
describe("File operations", () => {
test("should handle file import", async () => {
const mockFile = new File([""], "test.csv", { type: "text/csv" });
vi.mocked(rawStudy.importFile).mockResolvedValue();
vi.mocked(rawStudy.uploadFile).mockResolvedValue();

const hook = await setupHook();

await act(async () => {
await hook.result.current.handleUpload(mockFile);
});

expect(rawStudy.importFile).toHaveBeenCalledWith({
expect(rawStudy.uploadFile).toHaveBeenCalledWith({
file: mockFile,
studyId: DATA.studyId,
path: DATA.url,
Expand Down
18 changes: 13 additions & 5 deletions webapp/src/components/common/buttons/DownloadMatrixButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
* This file is part of the Antares project.
*/

import { downloadMatrix } from "../../../services/api/studies/raw";
import { getMatrixFile, getRawFile } from "../../../services/api/studies/raw";
import { downloadFile } from "../../../utils/fileUtils";
import { StudyMetadata } from "../../../common/types";
import { useTranslation } from "react-i18next";
import DownloadButton from "./DownloadButton";
import type { TTableExportFormat } from "@/services/api/studies/raw/types";

type ExportFormat = TTableExportFormat | "raw";

export interface DownloadMatrixButtonProps {
studyId: StudyMetadata["id"];
path: string;
Expand All @@ -30,28 +32,34 @@ function DownloadMatrixButton(props: DownloadMatrixButtonProps) {
const { t } = useTranslation();
const { studyId, path, disabled, label = t("global.export") } = props;

const options: Array<{ label: string; value: TTableExportFormat }> = [
const options: Array<{ label: string; value: ExportFormat }> = [
{ label: "CSV", value: "csv" },
{
label: `CSV (${t("global.semicolon").toLowerCase()})`,
value: "csv (semicolon)",
},
{ label: "TSV", value: "tsv" },
{ label: "XLSX", value: "xlsx" },
{ label: `${t("global.rawFile")}`, value: "raw" },
];

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

const handleDownload = async (format: TTableExportFormat) => {
const handleDownload = async (format: ExportFormat) => {
if (!path) {
return;
}

if (format === "raw") {
const file = await getRawFile({ studyId, path });
return downloadFile(file, file.name);
}

const isXlsx = format === "xlsx";

const res = await downloadMatrix({
const matrixFile = await getMatrixFile({
studyId,
path,
format,
Expand All @@ -62,7 +70,7 @@ function DownloadMatrixButton(props: DownloadMatrixButtonProps) {
const extension = format === "csv (semicolon)" ? "csv" : format;

return downloadFile(
res,
matrixFile,
`matrix_${studyId}_${path.replace("/", "_")}.${extension}`,
);
};
Expand Down
4 changes: 2 additions & 2 deletions webapp/src/components/common/buttons/UploadFileButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { toError } from "../../../utils/fnUtils";
import { Accept, useDropzone } from "react-dropzone";
import { StudyMetadata } from "../../../common/types";
import { useSnackbar } from "notistack";
import { importFile } from "../../../services/api/studies/raw";
import { uploadFile } from "../../../services/api/studies/raw";

type ValidateResult = boolean | null | undefined;
type Validate = (file: File) => ValidateResult | Promise<ValidateResult>;
Expand Down Expand Up @@ -89,7 +89,7 @@ function UploadFileButton(props: UploadFileButtonProps) {

const filePath = typeof path === "function" ? path(fileToUpload) : path;

await importFile({
await uploadFile({
studyId,
path: filePath,
file: fileToUpload,
Expand Down
Loading

0 comments on commit ca0582b

Please sign in to comment.