ENCOA-182, ENCOA-185, ENCOA-177, ENCOA-168, ENCOA-186, ENCOA-176, ENCOA-189, ENCOA-167
This commit is contained in:
@@ -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()}
|
||||
|
||||
Reference in New Issue
Block a user