From 3b83a51265133d4ecdd60c8e2937ac7399a38b31 Mon Sep 17 00:00:00 2001 From: Tristan Verbeken Date: Wed, 22 May 2024 23:08:04 +0200 Subject: [PATCH 01/12] temp changes @matthias help me :sob: --- .../forms/projectFormTabs/DockerFormTab.tsx | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx index c28ac625..0470f846 100644 --- a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx +++ b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx @@ -1,5 +1,5 @@ import { InboxOutlined, UploadOutlined } from "@ant-design/icons" -import {Button, Form, Input, Switch, Upload} from "antd" +import {Button, Dropdown, Form, Input, Menu, Select, Switch, Upload} from "antd" import { TextAreaProps } from "antd/es/input" import { FormInstance } from "antd/lib" import {FC, useState} from "react" @@ -9,6 +9,7 @@ import useAppApi from "../../../hooks/useAppApi" import MarkdownTooltip from "../../common/MarkdownTooltip" import { classicNameResolver } from "typescript" import MarkdownTextfield from "../../input/MarkdownTextfield" +import TextArea from "antd/es/input/TextArea"; const UploadBtn: React.FC<{ form: FormInstance; fieldName: string; textFieldProps?: TextAreaProps; disabled?: boolean }> = ({ form, fieldName, disabled }) => { const handleFileUpload = (file: File) => { @@ -42,13 +43,30 @@ const UploadBtn: React.FC<{ form: FormInstance; fieldName: string; textFieldProp ) } +interface Script { + displayName: string; + scriptGenerator: (script: string) => string; + image?: string; +} + +interface ScriptCollection { + [key: string]: Script; +} + const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { const { t } = useTranslation() const {message} = useAppApi() const [withTemplate, setWithTemplate] = useState(true) + const [imageSelect, setImageSelect] = useState("alpine") const dockerImage = Form.useWatch("dockerImage", form) const dockerDisabled = !dockerImage?.length + const languageOptions:ScriptCollection = { + "bash": {displayName:"Bash", scriptGenerator: (script: string) => script, image: "fedora"}, + "python": {displayName:"Python", scriptGenerator: (script: string) => `python -c '${script}'`, image: "python"}, + "javascript": {displayName:"Javascript (node)", scriptGenerator: (script: string) => `node -e '${script}', image: "node"`}, + "haskell": {displayName:"Haskell", scriptGenerator: (script: string) => `runhaskell -e '${script}'`, image: "haskell"} + } function isValidTemplate(template: string): string { if (!template?.length) return "" // Template is optional @@ -114,14 +132,22 @@ const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { placement="right" /> } + name="dockerImage" > - + />} + + <> = ({ form }) => { } name="dockerScript" > - Date: Thu, 23 May 2024 00:01:52 +0200 Subject: [PATCH 02/12] Fixed textfield input --- .../forms/projectFormTabs/DockerFormTab.tsx | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx index 0470f846..8433e82f 100644 --- a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx +++ b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx @@ -2,7 +2,7 @@ import { InboxOutlined, UploadOutlined } from "@ant-design/icons" import {Button, Dropdown, Form, Input, Menu, Select, Switch, Upload} from "antd" import { TextAreaProps } from "antd/es/input" import { FormInstance } from "antd/lib" -import {FC, useState} from "react" +import {FC, useEffect, useState} from "react" import { useTranslation } from "react-i18next" import { ApiRoutes } from "../../../@types/requests" import useAppApi from "../../../hooks/useAppApi" @@ -58,9 +58,10 @@ const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { const {message} = useAppApi() const [withTemplate, setWithTemplate] = useState(true) const [imageSelect, setImageSelect] = useState("alpine") - const dockerImage = Form.useWatch("dockerImage", form) + const [dockerDisabled, setDockerImage] = useState(false) + + - const dockerDisabled = !dockerImage?.length const languageOptions:ScriptCollection = { "bash": {displayName:"Bash", scriptGenerator: (script: string) => script, image: "fedora"}, "python": {displayName:"Python", scriptGenerator: (script: string) => `python -c '${script}'`, image: "python"}, @@ -68,6 +69,10 @@ const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { "haskell": {displayName:"Haskell", scriptGenerator: (script: string) => `runhaskell -e '${script}'`, image: "haskell"} } + useEffect(() => { + setDockerImage(imageSelect.length == 0) + }, [imageSelect]); + function isValidTemplate(template: string): string { if (!template?.length) return "" // Template is optional let atLeastOne = false // Template should not be empty @@ -132,17 +137,23 @@ const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { placement="right" /> } - - name="dockerImage" + //name = "dockerImage" //Als je deze uncomment dan werkt de value van de input niet meer. > - { } + onChange={(event) => setImageSelect(event.target.value)} + /> + + + + - setImageSelect(val)} > {Object.keys(languageOptions).map((key) => ( {languageOptions[key].displayName} ))} From 1e7ede314dfae264aa0d116646b6752ce5035842 Mon Sep 17 00:00:00 2001 From: Matthias-VE Date: Thu, 23 May 2024 00:06:10 +0200 Subject: [PATCH 03/12] remove wahoo --- .../src/components/forms/projectFormTabs/DockerFormTab.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx index 8433e82f..c2efbbaa 100644 --- a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx +++ b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx @@ -145,13 +145,6 @@ const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { onChange={(event) => setImageSelect(event.target.value)} /> - - - - + + setImageSelect(event.target.value)} - /> - - - - + placeholder={t("project.tests.dockerImagePlaceholder")} + />} - {Object.keys(languageOptions).map((key) => ( {languageOptions[key].displayName} ))} From 9643c2bee1901f3bf2f2c9634bee0aa2293a7ce9 Mon Sep 17 00:00:00 2001 From: Matthias-VE Date: Thu, 23 May 2024 00:18:46 +0200 Subject: [PATCH 06/12] working but now with form states instead of react states --- .../src/components/forms/projectFormTabs/DockerFormTab.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx index 0470f846..f8f3e4e8 100644 --- a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx +++ b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx @@ -57,7 +57,6 @@ const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { const { t } = useTranslation() const {message} = useAppApi() const [withTemplate, setWithTemplate] = useState(true) - const [imageSelect, setImageSelect] = useState("alpine") const dockerImage = Form.useWatch("dockerImage", form) const dockerDisabled = !dockerImage?.length @@ -137,12 +136,11 @@ const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { > { } - form.setFieldValue( "dockerImage", val)}> {Object.keys(languageOptions).map((key) => ( {languageOptions[key].displayName} ))} From 35d3f62bc0cf29f80ef828d9624f5de1dc6e5dfd Mon Sep 17 00:00:00 2001 From: Tristan Verbeken Date: Thu, 23 May 2024 12:32:31 +0200 Subject: [PATCH 07/12] added docker icons --- frontend/public/docker_langauges/bash.svg | 1 + frontend/public/docker_langauges/haskell.svg | 1 + frontend/public/docker_langauges/node-js.svg | 1 + frontend/public/docker_langauges/python.svg | 1 + 4 files changed, 4 insertions(+) create mode 100644 frontend/public/docker_langauges/bash.svg create mode 100644 frontend/public/docker_langauges/haskell.svg create mode 100644 frontend/public/docker_langauges/node-js.svg create mode 100644 frontend/public/docker_langauges/python.svg diff --git a/frontend/public/docker_langauges/bash.svg b/frontend/public/docker_langauges/bash.svg new file mode 100644 index 00000000..928d5a9d --- /dev/null +++ b/frontend/public/docker_langauges/bash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/docker_langauges/haskell.svg b/frontend/public/docker_langauges/haskell.svg new file mode 100644 index 00000000..0c627ebd --- /dev/null +++ b/frontend/public/docker_langauges/haskell.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/docker_langauges/node-js.svg b/frontend/public/docker_langauges/node-js.svg new file mode 100644 index 00000000..3e77c253 --- /dev/null +++ b/frontend/public/docker_langauges/node-js.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/docker_langauges/python.svg b/frontend/public/docker_langauges/python.svg new file mode 100644 index 00000000..bf2a1601 --- /dev/null +++ b/frontend/public/docker_langauges/python.svg @@ -0,0 +1 @@ + \ No newline at end of file From 8e0f1f7f626932db1a8abd694ada20ddae69e189 Mon Sep 17 00:00:00 2001 From: Tristan Verbeken Date: Thu, 23 May 2024 19:02:04 +0200 Subject: [PATCH 08/12] added container menu dropdown --- frontend/public/docker_langauges/custom.svg | 1 + .../forms/projectFormTabs/DockerFormTab.tsx | 105 +++++++++++------- frontend/src/i18n/en/translation.json | 2 +- frontend/src/i18n/nl/translation.json | 4 +- .../src/pages/editProject/EditProject.tsx | 11 +- 5 files changed, 79 insertions(+), 44 deletions(-) create mode 100644 frontend/public/docker_langauges/custom.svg diff --git a/frontend/public/docker_langauges/custom.svg b/frontend/public/docker_langauges/custom.svg new file mode 100644 index 00000000..39ead495 --- /dev/null +++ b/frontend/public/docker_langauges/custom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx index f8f3e4e8..24c14d26 100644 --- a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx +++ b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx @@ -11,6 +11,12 @@ import { classicNameResolver } from "typescript" import MarkdownTextfield from "../../input/MarkdownTextfield" import TextArea from "antd/es/input/TextArea"; +import BashIcon from "../../../../public/docker_langauges/bash.svg" +import PythonIcon from "../../../../public/docker_langauges/python.svg" +import NodeIcon from "../../../../public/docker_langauges/node-js.svg" +import HaskellIcon from "../../../../public/docker_langauges/haskell.svg" +import Custom from "../../../../public/docker_langauges/custom.svg" + const UploadBtn: React.FC<{ form: FormInstance; fieldName: string; textFieldProps?: TextAreaProps; disabled?: boolean }> = ({ form, fieldName, disabled }) => { const handleFileUpload = (file: File) => { const reader = new FileReader() @@ -45,27 +51,41 @@ const UploadBtn: React.FC<{ form: FormInstance; fieldName: string; textFieldProp interface Script { displayName: string; - scriptGenerator: (script: string) => string; - image?: string; + image: string; + icon: string; } interface ScriptCollection { [key: string]: Script; } +export const languageOptions: ScriptCollection = { + "bash": { displayName: "Bash", image: "fedora", icon: BashIcon }, + "python": { displayName: "Python", image: "python", icon: PythonIcon }, + "javascript": { displayName: "Javascript (node)", image: "node", icon: NodeIcon }, + "haskell": { displayName: "Haskell", image: "haskell", icon: HaskellIcon }, + "custom": { displayName: "Custom", image: "", icon: Custom } +} + +export function imageToLanguage(script: string): string { + for(const language in languageOptions) { + if(script === languageOptions[language].image) { + return language + } + } + return "" +} + + const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { const { t } = useTranslation() const {message} = useAppApi() const [withTemplate, setWithTemplate] = useState(true) + const [selectedLanguage, setSelectedLanguage] = useState("bash") const dockerImage = Form.useWatch("dockerImage", form) const dockerDisabled = !dockerImage?.length - const languageOptions:ScriptCollection = { - "bash": {displayName:"Bash", scriptGenerator: (script: string) => script, image: "fedora"}, - "python": {displayName:"Python", scriptGenerator: (script: string) => `python -c '${script}'`, image: "python"}, - "javascript": {displayName:"Javascript (node)", scriptGenerator: (script: string) => `node -e '${script}', image: "node"`}, - "haskell": {displayName:"Haskell", scriptGenerator: (script: string) => `runhaskell -e '${script}'`, image: "haskell"} - } + function isValidTemplate(template: string): string { if (!template?.length) return "" // Template is optional @@ -124,28 +144,46 @@ const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { return ( <> - } - - name="dockerImage" + label={ + + } + name="dockerImage" > - { } + + + + + + + + - - - <> = ({ form }) => { - {/* */}
= ({ form }) => {
+ = ({ form }) => { style={{fontFamily: "monospace", whiteSpace: "pre", overflowX: "auto"}} placeholder={"@helloWorldTest\n>required\n>description=\"This is a test\"\nExpected output 1\n\n@helloUGent\n>optional\nExpected output 2\n"} /> - {/**/}
: } diff --git a/frontend/src/i18n/en/translation.json b/frontend/src/i18n/en/translation.json index da297bf2..6aaf520a 100644 --- a/frontend/src/i18n/en/translation.json +++ b/frontend/src/i18n/en/translation.json @@ -211,7 +211,7 @@ "simpleMode": "Without template", "templateMode": "With template", "fileStructureTooltip": "This templates specifies the file structure a submission has to follow.\nIt uses the following syntax:\n* Folders end on `'/'`\n* Use indents to specify files inside a folder\n* Regex can be used\n\t* `'.'` is still a normal `'.'`\n\t* `'\\.'` can be used as regex `'.'`\n* `'-'` at the start of a line specifies a file/folder that is not allowed", - "dockerImageTooltip": "Specify a valid Docker-container from [Docker Hub](https://hub.docker.com/) on which the test script will be run.", + "dockerImageTooltip": "Specify a valid Docker container from [Docker Hub](https://hub.docker.com/) on which the test script will be run. You can also choose a language with a preselected container.", "dockerScriptTooltip": "Bash-script that is executed.\n* The files of the student's submission can be found in `'/shared/input'`\n* Extra files uploaded below can be found in `'/shared/extra'`\n\n More information about the required output depends on the mode and can be found below.", "dockerTemplateTooltip": "To specify specific tests, you need to provide a template. First, enter the test name with '@{test}'. Below this, you can use '>' to provide options such as ('>required', '>optional', '>description'). Everything under these options until the next test or the end of the file is the expected output.", "dockerTestDirTooltip": "Upload additional files needed for the Docker test.\n\nThese files are available in the folder `'/shared/extra'`.", diff --git a/frontend/src/i18n/nl/translation.json b/frontend/src/i18n/nl/translation.json index 39820ff9..522fc6c5 100644 --- a/frontend/src/i18n/nl/translation.json +++ b/frontend/src/i18n/nl/translation.json @@ -213,7 +213,7 @@ "templateMode": "Met sjabloon", "fileStructurePreview": "Voorbeeld van bestandsstructuur", "fileStructureTooltip": "Dit sjabloon specificeert de bestandsstructuur die een indiening moet volgen.\nHet gebruikt de volgende syntax:\n* Mappen eindigen op `'/'`\n* Gebruik inspringing om bestanden binnen een map aan te geven\n* Regex kan worden gebruikt\n\t* `'.'` is nog steeds een normale `'.'`\n\t* `'\\.'` kan worden gebruikt als regex `'.'`\n* `'-'` aan het begin van een regel geeft aan dat een bestand/map niet is toegestaan", - "dockerImageTooltip": "Specificeer een geldige Docker-container van [Docker Hub](https://hub.docker.com/) waarop het testscript zal worden uitgevoerd.", + "dockerImageTooltip": "Specificeer een geldige Docker-container van [Docker Hub](https://hub.docker.com/) waarop het testscript zal worden uitgevoerd. Je kan ook kiezen voor een voorgeconfigureerde programmeertaal met bijhorende container.", "dockerScriptTooltip": "Bash-script dat wordt uitgevoerd.\n* De bestanden van de student zijn indieningen zijn te vinden in `'/shared/input'`\n* Extra bestanden die hieronder zijn geĆ¼pload, zijn te vinden in `'/shared/extra'`\n\nMeer informatie over de vereiste uitvoer is afhankelijk van de modus en is hieronder te vinden.", "dockerTemplateTooltip": "Om specifieke tests te definiĆ«ren, moet je een sjabloon invoeren. Geef eerst de naam van de test in met '@{test}'. Hieronder kun je met een '>' opties geven zoals ('>required', '>optional', '>description'). Alles onder de opties tot de volgende test of het einde van het bestand is de verwachte output.", "dockerTestDirTooltip": "Upload extra bestanden die nodig zijn voor de dockertest.\n\nDeze bestanden zijn beschikbaar in de map `'/shared/extra'`.", @@ -247,7 +247,7 @@ "getStarted": "Aan de slag", "docs": "Documentatie" }, - + "submission": { "submission": "Indiening", "submittedFiles": "Ingediende bestanden:", diff --git a/frontend/src/pages/editProject/EditProject.tsx b/frontend/src/pages/editProject/EditProject.tsx index c5bc4dc9..898e4517 100644 --- a/frontend/src/pages/editProject/EditProject.tsx +++ b/frontend/src/pages/editProject/EditProject.tsx @@ -13,6 +13,7 @@ import { AppRoutes } from "../../@types/routes" import { ProjectContext } from "../../router/ProjectRoutes" import useApi from "../../hooks/useApi" import saveDockerForm, { DockerFormData } from "../../components/common/saveDockerForm" +import {imageToLanguage} from "../../components/forms/projectFormTabs/DockerFormTab"; const EditProject: React.FC = () => { const [form] = Form.useForm() @@ -40,10 +41,9 @@ const EditProject: React.FC = () => { dockerScript: null, dockerImage: null, } + if (response.success) { const tests = response.response.data - console.log(tests) - if (tests.extraFilesName) { const downloadLink = AppRoutes.DOWNLOAD_PROJECT_TESTS.replace(":projectId", projectId).replace(":courseId", courseId!) @@ -64,10 +64,12 @@ const EditProject: React.FC = () => { dockerScript: tests.dockerScript ?? "", dockerImage: tests.dockerImage ?? "", } + const selectedLanguage = imageToLanguage(formVals.dockerImage ?? "") + formVals.dockerScript = selectedLanguage[1] // We only want the script, not the language + form.setFieldValue("languageSelect", selectedLanguage) } form.setFieldsValue(formVals) - setInitialDockerValues(formVals) } @@ -80,6 +82,9 @@ const EditProject: React.FC = () => { const handleCreation = async () => { const values: ProjectFormData & DockerFormData = form.getFieldsValue() + + console.log(values) + if (values.visible) { values.visibleAfter = null } From 368c6f7f216b96f2cb5d454deb6cf007be8d8f93 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Thu, 23 May 2024 00:37:54 +0200 Subject: [PATCH 09/12] start docker toggle fix (doesn't work yet, pushing to get help) --- frontend/public/docker_langauges/bash.svg | 2 +- frontend/public/docker_langauges/custom.svg | 2 +- .../forms/projectFormTabs/DockerFormTab.tsx | 228 ++++++++---------- .../forms/projectFormTabs/GeneralFormTab.tsx | 166 ++++++------- .../src/pages/editProject/EditProject.tsx | 17 +- frontend/src/styles.css | 7 + 6 files changed, 193 insertions(+), 229 deletions(-) diff --git a/frontend/public/docker_langauges/bash.svg b/frontend/public/docker_langauges/bash.svg index 928d5a9d..890b5d92 100644 --- a/frontend/public/docker_langauges/bash.svg +++ b/frontend/public/docker_langauges/bash.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/frontend/public/docker_langauges/custom.svg b/frontend/public/docker_langauges/custom.svg index 39ead495..c3416414 100644 --- a/frontend/public/docker_langauges/custom.svg +++ b/frontend/public/docker_langauges/custom.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx index cf6569cb..f09d02a6 100644 --- a/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx +++ b/frontend/src/components/forms/projectFormTabs/DockerFormTab.tsx @@ -1,15 +1,13 @@ -import { InboxOutlined, UploadOutlined } from "@ant-design/icons" -import {Button, Dropdown, Form, Input, Menu, Select, Switch, Upload} from "antd" +import { CodepenCircleFilled, InboxOutlined, UploadOutlined } from "@ant-design/icons" +import { Button, Dropdown, Form, Input, Menu, Select, SelectProps, Switch, Upload } from "antd" import { TextAreaProps } from "antd/es/input" import { FormInstance } from "antd/lib" -import React, {FC, useEffect, useLayoutEffect, useState} from "react" +import React, { FC, useEffect, useLayoutEffect, useMemo, useState } from "react" import { useTranslation } from "react-i18next" -import { ApiRoutes } from "../../../@types/requests" import useAppApi from "../../../hooks/useAppApi" import MarkdownTooltip from "../../common/MarkdownTooltip" -import { classicNameResolver } from "typescript" import MarkdownTextfield from "../../input/MarkdownTextfield" -import TextArea from "antd/es/input/TextArea"; +import TextArea from "antd/es/input/TextArea" import BashIcon from "../../../../public/docker_langauges/bash.svg" import PythonIcon from "../../../../public/docker_langauges/python.svg" @@ -17,80 +15,66 @@ import NodeIcon from "../../../../public/docker_langauges/node-js.svg" import HaskellIcon from "../../../../public/docker_langauges/haskell.svg" import Custom from "../../../../public/docker_langauges/custom.svg" -const UploadBtn: React.FC<{ form: FormInstance; fieldName: string; textFieldProps?: TextAreaProps; disabled?: boolean }> = ({ form, fieldName, disabled }) => { - const handleFileUpload = (file: File) => { - const reader = new FileReader() - reader.onload = (e) => { - const contents = e.target?.result as string - form.setFieldValue(fieldName, contents) - } - reader.readAsText(file) - // Prevent default upload action - return false - } - return ( - <> -
- - - -
- - ) +type DockerLanguage = "bash" | "python" | "node" | "haskell" | "custom" +const languageOptions: Record = { + bash: "fedora", + python: "python", + node: "node", + haskell: "haskell", + custom: "" } -interface Script { - displayName: string; - image: string; - icon: string; +const imageToLanguage: Record = { + fedora: "bash", + python: "python", + node: "node", + haskell: "haskell", } -interface ScriptCollection { - [key: string]: Script; -} -export const languageOptions: ScriptCollection = { - "bash": { displayName: "Bash", image: "fedora", icon: BashIcon }, - "python": { displayName: "Python", image: "python", icon: PythonIcon }, - "javascript": { displayName: "Javascript (node)", image: "node", icon: NodeIcon }, - "haskell": { displayName: "Haskell", image: "haskell", icon: HaskellIcon }, - "custom": { displayName: "Custom", image: "", icon: Custom } -} - -export function imageToLanguage(script: string): string { - for(const language in languageOptions) { - if(script === languageOptions[language].image) { - return language - } +const languagesSelectorItems:SelectProps["options"] = [ + { + label: <>Bash, + value: "bash", + },{ + label: <>Python, + value: "python", + }, { + label: <>NodeJS, + value: "node", + }, { + label: <>Haskell, + value: "haskell", + }, { + label: <>Custom, + value: "custom", } - return "" -} +] + const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { const { t } = useTranslation() - const {message} = useAppApi() - const [withTemplate, setWithTemplate] = useState(true) - const [selectedLanguage, setSelectedLanguage] = useState("bash") + const { message } = useAppApi() const dockerImage = Form.useWatch("dockerImage", form) + const dockerTemplate = Form.useWatch("dockerTemplate", form) + const dockerMode = Form.useWatch("dockerMode", form) const dockerDisabled = !dockerImage?.length - useEffect(() => { + const withTemplate = (dockerMode === null && !!dockerTemplate?.length) || !!dockerMode + + + useEffect(() => { + form.validateFields(["dockerScript", "dockerTemplate"]) }, [dockerDisabled]) + + const dockerImageSelect= useMemo(()=> imageToLanguage[dockerImage] || "custom",[dockerImage]) + function isValidTemplate(template: string): string { if (template.length === 0) { return t("project.tests.dockerTemplateValidation.emptyTemplate") @@ -118,7 +102,7 @@ const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { const isDescription = line.length >= 13 && line.substring(0, 13).toLowerCase() === ">description=" // option lines if (line.toLowerCase() !== ">required" && line.toLowerCase() !== ">optional" && !isDescription) { - return t("project.tests.dockerTemplateValidation.inValidOptions", { line:lineNumber.toString() }) + return t("project.tests.dockerTemplateValidation.inValidOptions", { line: lineNumber.toString() }) } } else { isConfigurationLine = false @@ -131,74 +115,47 @@ const DockerFormTab: FC<{ form: FormInstance }> = ({ form }) => { return "" } - const normFile = (e: any) => { if (Array.isArray(e)) { - return e; + return e } - return e?.fileList; - }; + return e?.fileList + } - let switchClassName = 'template-switch' + let switchClassName = "template-switch" let scriptPlaceholder if (withTemplate) { - switchClassName += ' template-switch-active' - scriptPlaceholder = "bash /shared/input/helloworld.sh > \"/shared/output/helloWorldTest\"\n"+ - "bash /shared/input/helloug.sh > \"/shared/output/helloUGent\"\n" + switchClassName += " template-switch-active" + scriptPlaceholder = 'bash /shared/input/helloworld.sh > "/shared/output/helloWorldTest"\n' + 'bash /shared/input/helloug.sh > "/shared/output/helloUGent"\n' } else { - switchClassName += ' template-switch-inactive' - scriptPlaceholder = "output=$(bash /shared/input/helloworld.sh)\n"+ - "if [[ \"$output\" == \"Hello World\" ]]; then \n"+ - " echo 'Test one is successful\n"+ - " echo 'PUSH ALLOWED' > /shared/output/testOutput\n"+ - "else\n"+ - " echo 'Test one failed: script failed to print \"Hello World\"'\n"+ - "fi" + switchClassName += " template-switch-inactive" + scriptPlaceholder = "output=$(bash /shared/input/helloworld.sh)\n" + 'if [[ "$output" == "Hello World" ]]; then \n' + " echo 'Test one is successful\n" + " echo 'PUSH ALLOWED' > /shared/output/testOutput\n" + "else\n" + " echo 'Test one failed: script failed to print \"Hello World\"'\n" + "fi" } + return ( <> - } - name="dockerImage" + label={ + + } + name="dockerImage" > - - + form.setFieldValue( "dockerImage", languageOptions[val].image)} - style={{ width: '30%' }} - > - {Object.keys(languageOptions).map((key) => ( - - - {languageOptions[key].displayName} - - {languageOptions[key].displayName} - - ))} - - - - - - + style={{ width: 150 }} + value={dockerImageSelect} + onChange={(val:DockerLanguage) => form.setFieldValue("dockerImage", languageOptions[val])} + options={languagesSelectorItems} + />} + placeholder={t("project.tests.dockerImagePlaceholder")} + /> <> = ({ form }) => {