Generateurv2/frontend/components/exos/Editor.jsx
2022-05-18 10:15:54 +02:00

147 lines
4.2 KiB
JavaScript

import AceEditor from "react-ace";
import React, { useEffect, useState } from "react";
import "ace-builds/src-min-noconflict/ext-language_tools";
import "ace-builds/src-noconflict/mode-python";
import "ace-builds/src-noconflict/snippets/python";
import "ace-builds/src-noconflict/mode-javascript";
import "ace-builds/src-noconflict/snippets/javascript";
import "ace-builds/src-noconflict/theme-tomorrow_night_blue";
import { exoInstance } from "../../apis/exoInstance.instance.js";
import { useQuery } from "react-query";
import { editorOut } from "../../requests/requests.exos.js";
import styles from "../../styles/exos/Editor.module.scss";
import { VscDebugStart } from "react-icons/vsc";
import { parseClassName } from "../../utils/utils.js";
import { notificationService } from "../../services/notification.service.js";
function ConsoleComp({ content, step }) {
return (
<div
className={parseClassName([
styles["console"],
])}
>
<p className="margin-0 marginb-p1">
Python 3.10.1 (main, Dec 29 2021, 10:45:39) -{" "}
{step.name.replace(" ", "_")}.py
</p>
{content.out.length == 0 && content.error.length == 0 && (
<p className="console-line margin-0">{">"}</p>
)}
{content.out.map((l) => {
return (
<p className={parseClassName(["console-line", "margin-0"])}>
{">"} {l}
</p>
);
})}
{content.error.map((l) => {
return (
<p
className={parseClassName([
"console-line",
"margin-0",
styles["error_lines"],
])}
>
{">"} {l}
</p>
);
})}
</div>
);
}
const Console = React.memo(ConsoleComp);
export default function CustomEditor({ ...props }) {
const [enable, setEnable] = useState(false);
const { isLoading, isFetching, data, refetch, remove } = useQuery(
"editor",
async () => await editorOut(props.value),
{
refetchOnWindowFocus: false,
staleTime: 1000000,
enabled: enable,
}
);
useEffect(() => {
return () => {
remove();
};
}, []);
return (
<>
<div className={styles["btn-container"]}>
<button
onClick={async () => {
setEnable(true);
refetch();
}}
className={parseClassName(["exo-btn", styles["run-btn"]])}
>
{!isLoading && !isFetching && (
<>
<VscDebugStart className={styles["run-icon"]} />
Run
</>
)}
{(isLoading || isFetching) && (
<>
<span
className={parseClassName(["loader", styles["loader"]])}
></span>
</>
)}
</button>
<button
className={parseClassName(["exo-btn", styles["btn"]])}
onClick={(e) => {
refetch().then((res) => {
console.log('tes', res)
if (res.data.error.length == 0) {
props.validate(e);
} else {
notificationService.error('Erreur', 'Veuillez regler l\'erreur', {autoClose: true })
}
});
}}
>
Valider
</button>
<button
onClick={props.cancel}
className={parseClassName(["cancel-btn", styles.btn])}
>
Annuler
</button>
</div>
<div className={styles["full-editor"]}>
<div className={styles["editor"]}>
<div className={styles["onglet-container"]}>
<div className={styles["onglet"]}>
Python - {props.filename != null ? props.filename: 'main.py'}
</div>
</div>
<AceEditor {...props} theme="tomorrow_night_blue" />{" "}
</div>
<div className={styles["console-container"]}>
<div className={styles["onglet-container"]}>
<div className={styles["onglet"]}>Console</div>
</div>
<Console
content={
isLoading || isFetching || !data
? { out: ["..."], error: [] }
: data
}
step={props.step}
/>
</div>
</div>
</>
);
}