Skip to content

Commit

Permalink
feat(ui-studies): update validation in MoveStudyDialog
Browse files Browse the repository at this point in the history
ANT-2390
  • Loading branch information
skamril committed Nov 21, 2024
1 parent 489d0a8 commit 8b9cbca
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 53 deletions.
8 changes: 5 additions & 3 deletions webapp/public/locales/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"global.status": "Status",
"global.semicolon": "Semicolon",
"global.language": "Language",
"global.path": "Path",
"global.time.hourly": "Hourly",
"global.time.daily": "Daily",
"global.time.weekly": "Weekly",
Expand Down Expand Up @@ -154,6 +155,9 @@
"form.field.requireUppercase": "Must contain at least one uppercase letter.",
"form.field.requireDigit": "Must contain at least one digit.",
"form.field.requireSpecialChars": "Must contain at least one special character.",
"form.field.path.startWithSlashNotAllowed": "Path must not start with a '/'",
"form.field.path.endWithSlashNotAllowed": "Path must not end with a '/'",
"form.field.path.invalid": "Invalid path",
"matrix.graphSelector": "Columns",
"matrix.message.importHint": "Click or drag and drop a matrix here",
"matrix.importNewMatrix": "Import a new matrix",
Expand Down Expand Up @@ -620,7 +624,6 @@
"studies.error.loadStudy": "Failed to load study",
"studies.error.runStudy": "Failed to run study",
"studies.error.scanFolder": "Failed to start folder scan",
"studies.error.moveStudy": "Failed to move study {{study}}",
"studies.error.saveData": "Failed to save data",
"studies.error.copyStudy": "Failed to copy study",
"studies.error.import": "Failed to import Study ({{uploadFile}})",
Expand All @@ -631,11 +634,10 @@
"studies.error.createStudy": "Failed to create Study {{studyname}}",
"studies.success.saveData": "Data saved with success",
"studies.success.scanFolder": "Folder scan started",
"studies.success.moveStudy": "Study {{study}} was successfully moved to {{folder}}",
"studies.success.moveStudy": "Study '{{study}}' was successfully moved to '{{path}}'",
"studies.success.createStudy": "Study {{studyname}} created successfully",
"studies.studylaunched": "{{studyname}} launched!",
"studies.copySuffix": "Copy",
"studies.folder": "Folder",
"studies.filters.strictfolder": "Show only direct folder children",
"studies.scanFolder": "Scan folder",
"studies.moveStudy": "Move",
Expand Down
8 changes: 5 additions & 3 deletions webapp/public/locales/fr/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"global.status": "Statut",
"global.semicolon": "Point-virgule",
"global.language": "Langue",
"global.path": "Chemin",
"global.time.hourly": "Horaire",
"global.time.daily": "Journalier",
"global.time.weekly": "Hebdomadaire",
Expand Down Expand Up @@ -154,6 +155,9 @@
"form.field.requireUppercase": "Doit contenir au moins une lettre majuscule.",
"form.field.requireDigit": "Doit contenir au moins un chiffre.",
"form.field.requireSpecialChars": "Doit contenir au moins un caractère spécial.",
"form.field.path.startWithSlashNotAllowed": "Le chemin ne doit pas commencer par un '/'",
"form.field.path.endWithSlashNotAllowed": "Le chemin ne doit pas finir par un '/'",
"form.field.path.invalid": "Chemin invalide",
"matrix.graphSelector": "Colonnes",
"matrix.message.importHint": "Cliquer ou glisser une matrice ici",
"matrix.importNewMatrix": "Import d'une nouvelle matrice",
Expand Down Expand Up @@ -620,7 +624,6 @@
"studies.error.loadStudy": "Échec du chargement de l'étude",
"studies.error.runStudy": "Échec du lancement de l'étude",
"studies.error.scanFolder": "Échec du lancement du scan",
"studies.error.moveStudy": "Échec du déplacement de l'étude {{study}}",
"studies.error.saveData": "Erreur lors de la sauvegarde des données",
"studies.error.copyStudy": "Erreur lors de la copie de l'étude",
"studies.error.import": "L'import de l'étude a échoué ({{uploadFile}})",
Expand All @@ -631,11 +634,10 @@
"studies.error.createStudy": "Erreur lors de la création de l'étude {{studyname}}",
"studies.success.saveData": "Donnée sauvegardée avec succès",
"studies.success.scanFolder": "L'analyse du dossier a commencé",
"studies.success.moveStudy": "L'étude {{study}} a été déplacée avec succès vers {{folder}}",
"studies.success.moveStudy": "L'étude \"{{study}}\" a été déplacée avec succès vers \"{{folder}}\"",
"studies.success.createStudy": "L'étude {{studyname}} a été crée avec succès",
"studies.studylaunched": "{{studyname}} lancé(s) !",
"studies.copySuffix": "Copie",
"studies.folder": "Dossier",
"studies.filters.strictfolder": "Afficher uniquement les descendants directs",
"studies.scanFolder": "Scanner le dossier",
"studies.moveStudy": "Déplacer",
Expand Down
89 changes: 48 additions & 41 deletions webapp/src/components/App/Studies/MoveStudyDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,33 @@
*/

import { DialogProps } from "@mui/material";
import TextField from "@mui/material/TextField";
import { useSnackbar } from "notistack";
import * as R from "ramda";
import { useTranslation } from "react-i18next";
import { usePromise } from "react-use";
import { StudyMetadata } from "../../../common/types";
import useEnqueueErrorSnackbar from "../../../hooks/useEnqueueErrorSnackbar";
import { moveStudy } from "../../../services/api/study";
import { isStringEmpty } from "../../../services/utils";
import FormDialog from "../../common/dialogs/FormDialog";
import { SubmitHandlerPlus } from "../../common/Form/types";
import StringFE from "@/components/common/fieldEditors/StringFE";
import * as R from "ramda";
import { validatePath } from "@/utils/validation/string";

function formalizePath(studyId: StudyMetadata["id"], path: string | undefined) {
const pathTrimmed = path?.trim();

if (!pathTrimmed) {
return "";
}

const pathArray = pathTrimmed.split("/").filter(Boolean);
const lastFolder = R.last(pathArray);

// Antares Web automatically add the study ID to a not empty path when moving a study (cf. `handleSubmit`)
if (lastFolder === studyId) {
return pathArray.slice(0, -1).join("/");
}

return pathArray.join("/");
}

interface Props extends DialogProps {
study: StudyMetadata;
Expand All @@ -33,36 +49,35 @@ interface Props extends DialogProps {
function MoveStudyDialog(props: Props) {
const { study, open, onClose } = props;
const [t] = useTranslation();
const mounted = usePromise();
const { enqueueSnackbar } = useSnackbar();
const enqueueErrorSnackbar = useEnqueueErrorSnackbar();

const defaultValues = {
folder: R.join("/", R.dropLast(1, R.split("/", study.folder || ""))),
path: formalizePath(study.id, study.folder),
};

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

const handleSubmit = async (
const handleSubmit = (data: SubmitHandlerPlus<typeof defaultValues>) => {
const path = formalizePath(study.id, data.values.path);
return moveStudy(study.id, path && `${path}/${study.id}`);
};

const handleSubmitSuccessful = (
data: SubmitHandlerPlus<typeof defaultValues>,
) => {
const { folder } = data.values;
try {
await mounted(moveStudy(study.id, folder));
enqueueSnackbar(
t("studies.success.moveStudy", { study: study.name, folder }),
{
variant: "success",
},
);
onClose();
} catch (e) {
enqueueErrorSnackbar(
t("studies.error.moveStudy", { study: study.name }),
e as Error,
);
}
onClose();

enqueueSnackbar(
t("studies.success.moveStudy", {
study: study.name,
path: data.values.path,
}),
{
variant: "success",
},
);
};

////////////////////////////////////////////////////////////////
Expand All @@ -74,27 +89,19 @@ function MoveStudyDialog(props: Props) {
open={open}
config={{ defaultValues }}
onSubmit={handleSubmit}
onSubmitSuccessful={handleSubmitSuccessful}
onCancel={onClose}
>
{(formObj) => (
<TextField
{({ control }) => (
<StringFE
name="path"
control={control}
rules={{ validate: validatePath({ allowEmpty: true }) }}
label={t("global.path")}
placeholder={t("studies.movefolderplaceholder")}
sx={{ mx: 0 }}
autoFocus
label={t("studies.folder")}
error={!!formObj.formState.errors.folder}
helperText={formObj.formState.errors.folder?.message}
placeholder={t("studies.movefolderplaceholder") as string}
InputLabelProps={
// Allow to show placeholder when field is empty
formObj.formState.defaultValues?.folder ? { shrink: true } : {}
}
fullWidth
{...formObj.register("folder", {
required: t("form.field.required") as string,
validate: (value) => {
return !isStringEmpty(value);
},
})}
/>
)}
</FormDialog>
Expand Down
11 changes: 5 additions & 6 deletions webapp/src/services/api/study.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/

import { AxiosRequestConfig } from "axios";
import { isBoolean, trimCharsStart } from "ramda-adjunct";
import { isBoolean } from "ramda-adjunct";
import client from "./client";
import {
FileStudyTreeConfigDTO,
Expand Down Expand Up @@ -163,11 +163,10 @@ export const copyStudy = async (
return res.data;
};

export const moveStudy = async (sid: string, folder: string): Promise<void> => {
const folderWithId = trimCharsStart("/", `${folder.trim()}/${sid}`);
await client.put(
`/v1/studies/${sid}/move?folder_dest=${encodeURIComponent(folderWithId)}`,
);
export const moveStudy = async (sid: string, folder: string) => {
await client.put(`/v1/studies/${sid}/move`, null, {
params: { folder_dest: folder },
});
};

export const archiveStudy = async (sid: string): Promise<void> => {
Expand Down

0 comments on commit 8b9cbca

Please sign in to comment.