ENCOA-182, ENCOA-185, ENCOA-177, ENCOA-168, ENCOA-186, ENCOA-176, ENCOA-189, ENCOA-167

This commit is contained in:
Carlos Mesquita
2024-09-06 09:39:38 +01:00
parent b6b5f3a9f1
commit 77ac15c2bb
11 changed files with 577 additions and 212 deletions

View File

@@ -85,8 +85,9 @@ export default function Level({ exam, showSolutions = false, onFinish, editing =
const scrollToTop = () => Array.from(document.getElementsByTagName("body")).forEach((body) => body.scrollTo(0, 0));
const [contextWord, setContextWord] = useState<string | undefined>(undefined);
const [contextWordLine, setContextWordLine] = useState<number | undefined>(undefined);
const [contextWords, setContextWords] = useState<{ match: string, originalLine: string }[] | undefined>(undefined);
const [contextWordLines, setContextWordLines] = useState<number[] | undefined>(undefined);
const [totalLines, setTotalLines] = useState<number>(0);
const [showSolutionsSave, setShowSolutionsSave] = useState(showSolutions ? userSolutions.filter((x) => x.module === "level") : undefined)
@@ -206,6 +207,14 @@ export default function Level({ exam, showSolutions = false, onFinish, editing =
if (questionIndex == 0) {
setPartIndex(partIndex - 1);
if (!seenParts.has(partIndex - 1)) {
setBgColor(levelBgColor);
setShowPartDivider(true);
setQuestionIndex(0);
setSeenParts(prev => new Set(prev).add(partIndex - 1));
return;
}
const lastExerciseIndex = exam.parts[partIndex - 1].exercises.length - 1;
const lastExercise = exam.parts[partIndex - 1].exercises[lastExerciseIndex];
setExerciseIndex(lastExerciseIndex);
@@ -260,8 +269,9 @@ export default function Level({ exam, showSolutions = false, onFinish, editing =
{exam.parts[partIndex].context &&
<TextComponent
part={exam.parts[partIndex]}
contextWord={contextWord}
setContextWordLine={setContextWordLine}
contextWords={contextWords}
setContextWordLines={setContextWordLines}
setTotalLines={setTotalLines}
/>}
</div>
</>
@@ -321,35 +331,59 @@ export default function Level({ exam, showSolutions = false, onFinish, editing =
useEffect(() => {
const regex = /.*?['"](.*?)['"] in line (\d+)\?$/;
const findMatch = (index: number) => {
if (currentExercise && currentExercise.type === "multipleChoice" && currentExercise!.questions[index]) {
const match = currentExercise!.questions[index].prompt.match(regex);
if (match) {
return { match: match[1], originalLine: match[2] }
}
}
return;
}
// if the client for some whatever random reason decides
// to add more questions update this
const numberOfQuestions = 2;
if (exam.parts[partIndex].context) {
const hits = Array.from({ length: numberOfQuestions }).reduce<{ match: string, originalLine: string }[]>((acc, _, i) => {
const result = findMatch(questionIndex + i);
if (!!result) {
acc.push(result);
}
return acc;
}, []);
if (hits.length > 0) {
setContextWords(hits)
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentExercise, questionIndex, totalLines]);
useEffect(() => {
if (
exerciseIndex !== -1 && currentExercise &&
currentExercise.type === "multipleChoice" &&
currentExercise.questions[questionIndex] &&
currentExercise.questions[questionIndex].prompt &&
exam.parts[partIndex].context
exam.parts[partIndex].context && contextWordLines
) {
const match = currentExercise.questions[questionIndex].prompt.match(regex);
if (match) {
const word = match[1];
const originalLineNumber = match[2];
if (word !== contextWord) {
setContextWord(word);
}
const updatedPrompt = currentExercise.questions[questionIndex].prompt.replace(
`in line ${originalLineNumber}`,
`in line ${contextWordLine || originalLineNumber}`
);
currentExercise.questions[questionIndex].prompt = updatedPrompt;
if (contextWordLines.length > 0) {
contextWordLines.forEach((n, i) => {
if (contextWords && contextWords[i] && n !== -1) {
const updatedPrompt = currentExercise!.questions[questionIndex + i].prompt.replace(
`in line ${contextWords[i].originalLine}`,
`in line ${n}`
);
currentExercise!.questions[questionIndex + i].prompt = updatedPrompt;
}
})
setChangedPrompt(true);
} else {
setContextWord(undefined);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentExercise, questionIndex, contextWordLine]);
}, [contextWordLines]);
useEffect(() => {
if (continueAnyways) {
@@ -419,7 +453,7 @@ export default function Level({ exam, showSolutions = false, onFinish, editing =
<Button color="purple" onClick={() => setShowSubmissionModal(false)} variant="outline" className="max-w-[200px] self-end w-full !text-xl">
Cancel
</Button>
<Button color="rose" onClick={() => { setShowSubmissionModal(false); setContinueAnyways(true)}} className="max-w-[200px] self-end w-full !text-xl">
<Button color="rose" onClick={() => { setShowSubmissionModal(false); setContinueAnyways(true) }} className="max-w-[200px] self-end w-full !text-xl">
Confirm
</Button>
</div>
@@ -469,6 +503,7 @@ export default function Level({ exam, showSolutions = false, onFinish, editing =
</div>
)}
<ModuleTitle
examLabel={exam.label}
partLabel={partLabel()}
minTimer={exam.minTimer}
exerciseIndex={calculateExerciseIndex()}