204 lines
6.4 KiB
JavaScript
204 lines
6.4 KiB
JavaScript
import { useState } from "react";
|
|
import { useMutation, useQueryClient } from "react-query";
|
|
import { editExo } from "../../requests/requests.exos.js";
|
|
import { notificationService } from "../../services/notification.service.js";
|
|
import styles from "../../styles/exos/ExoEditForm.module.scss";
|
|
import { parseClassName } from "../../utils/utils.js";
|
|
import ModelInput from "./modelInput.jsx";
|
|
import { AlertType, useAlert } from "../../context/alert.context.js";
|
|
import { RiErrorWarningFill } from "react-icons/ri";
|
|
import { CODE_SEPARATOR } from "../../utils/constant.js";
|
|
|
|
export function ExoEditForm({ step, cancel, setFull, full }) {
|
|
const [spec, setSpec] = useState({
|
|
name: step.name,
|
|
consigne: step.consigne,
|
|
exo_model: step.exo_model,
|
|
});
|
|
const alert = useAlert();
|
|
const queryClient = useQueryClient();
|
|
const [errors, setErrors] = useState({
|
|
name: null,
|
|
exo_model: null,
|
|
consigne: null,
|
|
});
|
|
const { mutate, isLoading, data } = useMutation(
|
|
() => {
|
|
const dataToSend = new FormData()
|
|
var blob = new Blob([spec.exo_model.data], { type: "text/x-python" });
|
|
var file = new File([blob], spec.exo_model.filename != null ? spec.exo_model.filename: 'main.py', { type: "text/x-python" });
|
|
|
|
dataToSend.append("file", file);
|
|
dataToSend.append("name",spec.name);
|
|
dataToSend.append("consigne",spec.consigne);
|
|
dataToSend.append("id_code", step.id_code);
|
|
return editExo(dataToSend);
|
|
},
|
|
{
|
|
onSuccess: (data) => {
|
|
queryClient.invalidateQueries("exo-data");
|
|
notificationService.success(
|
|
"Modification !",
|
|
`L'exercice ${spec.name} a bien été modifié !`,
|
|
{ autoClose: true, keepAfterRouteChange: true }
|
|
);
|
|
cancel();
|
|
},
|
|
onError: (err) => {
|
|
console.log(err.response.data.errors, {
|
|
...errors,
|
|
...err.response.data.errors
|
|
});
|
|
var resetErrors = { name: null, exo_model: null, consigne: null };
|
|
var newError = { ...resetErrors, ...err.response.data.errors };
|
|
setErrors({...newError})
|
|
notificationService.error(
|
|
"Erreur",
|
|
"La modification n'a pu être enregistrée ! Réessayez plus tard !",
|
|
{ autoClose: true, keepAfterRouteChange: true }
|
|
);
|
|
},
|
|
}
|
|
);
|
|
|
|
return (
|
|
<>
|
|
{!full && (
|
|
<>
|
|
<span
|
|
className={parseClassName([
|
|
styles["input-container"],
|
|
styles["ex_card--title"],
|
|
"marginb-p0",
|
|
])}
|
|
>
|
|
<span>
|
|
<input
|
|
type="text"
|
|
className={parseClassName([
|
|
"exo-input",
|
|
styles["ex_card--title"],
|
|
styles.input,
|
|
errors.name !== null ? styles["exo-input-error"] : undefined,
|
|
])}
|
|
value={spec.name}
|
|
onChange={(e) => {
|
|
setSpec({ ...spec, name: e.target.value });
|
|
}}
|
|
placeholder="Nom..."
|
|
/>
|
|
{spec.name !== step.name && (
|
|
<RiErrorWarningFill className="red" />
|
|
)}{" "}
|
|
</span>
|
|
{errors.name !== null &&
|
|
errors.name.map((err, i) => {
|
|
return (
|
|
<p className="error-msg" key={i}>
|
|
{err}
|
|
</p>
|
|
);
|
|
})}
|
|
</span>
|
|
<span
|
|
className={[
|
|
parseClassName([styles["input-container"], "marginb-p0"]),
|
|
]}
|
|
>
|
|
<span>
|
|
<input
|
|
type="text"
|
|
className={parseClassName([
|
|
"exo-input",
|
|
styles.input,
|
|
errors.consigne !== null
|
|
? styles["exo-input-error"]
|
|
: undefined,
|
|
])}
|
|
style={{ gridColumn: "1/3" }}
|
|
value={spec.consigne}
|
|
onChange={(e) => {
|
|
setSpec({ ...spec, consigne: e.target.value });
|
|
}}
|
|
placeholder="Consigne..."
|
|
/>
|
|
{spec.consigne !== step.consigne && (
|
|
<RiErrorWarningFill className="red" />
|
|
)}{" "}
|
|
</span>
|
|
{errors.consigne !== null &&
|
|
errors.consigne.map((err, i) => {
|
|
return (
|
|
<p className="error-msg" key={i}>
|
|
{err}
|
|
</p>
|
|
);
|
|
})}
|
|
</span>
|
|
</>
|
|
)}
|
|
<div
|
|
style={{ /* gridColumn: "1/3" */ height: full && "100%" }}
|
|
className={!full ? styles["modelinput-container"] : undefined}
|
|
>
|
|
<ModelInput
|
|
model={spec.exo_model}
|
|
setModel={(n)=>{setSpec({...spec,exo_model: n})}}
|
|
setFull={setFull}
|
|
full={full}
|
|
step={step}
|
|
onChange={(new_model) => {
|
|
setSpec({ ...spec, exo_model: new_model});
|
|
}}
|
|
tempSpec={spec}
|
|
/>
|
|
{errors.exo_model !== null &&
|
|
errors.exo_model.map((err, i) => {
|
|
return (
|
|
<p className="error-msg margint-p0" key={i}>
|
|
{err}
|
|
</p>
|
|
);
|
|
})}
|
|
</div>
|
|
|
|
{!full && (
|
|
<div className={styles["btn-container"]}>
|
|
<button
|
|
className={parseClassName(["exo-btn", styles["btn"]])}
|
|
onClick={mutate}
|
|
>
|
|
{!isLoading ? (
|
|
"Valider !"
|
|
) : (
|
|
<div className={styles["loader-btn-container"]}>
|
|
<span className="loader"></span>
|
|
</div>
|
|
)}
|
|
</button>
|
|
<button
|
|
className={parseClassName(["cancel-btn", styles["btn"]])}
|
|
onClick={() => {
|
|
if (
|
|
spec.consigne != step.consigne ||
|
|
spec.name != step.name ||
|
|
step.exo_model != spec.exo_model
|
|
) {
|
|
alert.alert({
|
|
title: "Êtes-vous sûr ?",
|
|
active: true,
|
|
message: `Vous avez des modifications non enregistrée, voulez vous annuler ?`,
|
|
type: AlertType.Warning,
|
|
validate: cancel,
|
|
});
|
|
} else cancel();
|
|
}}
|
|
>
|
|
Annuler !
|
|
</button>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|