add imutable ids to some exam arrays to detect and log changes between two exams.

This commit is contained in:
Joao Correia
2025-03-02 00:10:57 +00:00
parent 4e3cfec9e8
commit 32cd8495d6
12 changed files with 309 additions and 225 deletions

View File

@@ -13,6 +13,7 @@ import validateBlanks from "../validateBlanks";
import { toast } from "react-toastify";
import setEditingAlert from "../../Shared/setEditingAlert";
import PromptEdit from "../../Shared/PromptEdit";
import { uuidv4 } from "@firebase/util";
interface Word {
letter: string;
@@ -72,6 +73,7 @@ const FillBlanksLetters: React.FC<{ exercise: FillBlanksExercise; sectionId: num
...local,
text: blanksState.text,
solutions: Array.from(answers.entries()).map(([id, solution]) => ({
uuid: local.solutions.find(sol => sol.id === id)?.uuid || uuidv4(),
id,
solution
}))
@@ -145,6 +147,7 @@ const FillBlanksLetters: React.FC<{ exercise: FillBlanksExercise; sectionId: num
setLocal(prev => ({
...prev,
solutions: Array.from(newAnswers.entries()).map(([id, solution]) => ({
uuid: prev.solutions.find(sol => sol.id === id)?.uuid || uuidv4(),
id,
solution
}))
@@ -189,6 +192,7 @@ const FillBlanksLetters: React.FC<{ exercise: FillBlanksExercise; sectionId: num
...prev,
words: newWords,
solutions: Array.from(newAnswers.entries()).map(([id, solution]) => ({
uuid: prev.solutions.find(sol => sol.id === id)?.uuid || uuidv4(),
id,
solution
}))
@@ -217,6 +221,7 @@ const FillBlanksLetters: React.FC<{ exercise: FillBlanksExercise; sectionId: num
...prev,
words: newWords,
solutions: Array.from(newAnswers.entries()).map(([id, solution]) => ({
uuid: prev.solutions.find(sol => sol.id === id)?.uuid || uuidv4(),
id,
solution
}))
@@ -234,6 +239,7 @@ const FillBlanksLetters: React.FC<{ exercise: FillBlanksExercise; sectionId: num
setLocal(prev => ({
...prev,
solutions: Array.from(newAnswers.entries()).map(([id, solution]) => ({
uuid: prev.solutions.find(sol => sol.id === id)?.uuid || uuidv4(),
id,
solution
}))

View File

@@ -11,6 +11,7 @@ import { toast } from "react-toastify";
import setEditingAlert from "../../Shared/setEditingAlert";
import { MdEdit, MdEditOff } from "react-icons/md";
import MCOption from "./MCOption";
import { uuidv4 } from "@firebase/util";
const FillBlanksMC: React.FC<{ exercise: FillBlanksExercise; sectionId: number }> = ({ exercise, sectionId }) => {
@@ -69,6 +70,7 @@ const FillBlanksMC: React.FC<{ exercise: FillBlanksExercise; sectionId: number }
...local,
text: blanksState.text,
solutions: Array.from(answers.entries()).map(([id, solution]) => ({
uuid: local.solutions.find(sol => sol.id === id)?.uuid || uuidv4(),
id,
solution
}))
@@ -139,6 +141,7 @@ const FillBlanksMC: React.FC<{ exercise: FillBlanksExercise; sectionId: number }
setLocal(prev => ({
...prev,
solutions: Array.from(newAnswers.entries()).map(([id, solution]) => ({
uuid: prev.solutions.find(sol => sol.id === id)?.uuid || uuidv4(),
id,
solution
}))
@@ -168,6 +171,7 @@ const FillBlanksMC: React.FC<{ exercise: FillBlanksExercise; sectionId: number }
...prev,
words: newWords,
solutions: Array.from(newAnswers.entries()).map(([id, solution]) => ({
uuid: prev.solutions.find(sol => sol.id === id)?.uuid || uuidv4(),
id,
solution
}))
@@ -217,6 +221,7 @@ const FillBlanksMC: React.FC<{ exercise: FillBlanksExercise; sectionId: number }
...prev,
words: (prev.words as FillBlanksMCOption[]).filter(w => w.id !== blankId.toString()),
solutions: Array.from(newAnswers.entries()).map(([id, solution]) => ({
uuid: prev.solutions.find(sol => sol.id === id)?.uuid || uuidv4(),
id,
solution
}))
@@ -234,6 +239,7 @@ const FillBlanksMC: React.FC<{ exercise: FillBlanksExercise; sectionId: number }
blanksMissingWords.forEach(blank => {
const newMCOption: FillBlanksMCOption = {
uuid: uuidv4(),
id: blank.id.toString(),
options: {
A: 'Option A',
@@ -249,6 +255,7 @@ const FillBlanksMC: React.FC<{ exercise: FillBlanksExercise; sectionId: number }
...prev,
words: newWords,
solutions: Array.from(answers.entries()).map(([id, solution]) => ({
uuid: prev.solutions.find(sol => sol.id === id)?.uuid || uuidv4(),
id,
solution
}))

View File

@@ -18,6 +18,7 @@ import { toast } from 'react-toastify';
import { DragEndEvent } from '@dnd-kit/core';
import { handleMatchSentencesReorder } from '@/stores/examEditor/reorder/local';
import PromptEdit from '../Shared/PromptEdit';
import { uuidv4 } from '@firebase/util';
const MatchSentences: React.FC<{ exercise: MatchSentencesExercise, sectionId: number }> = ({ exercise, sectionId }) => {
const { currentModule, dispatch } = useExamEditorStore();
@@ -98,6 +99,7 @@ const MatchSentences: React.FC<{ exercise: MatchSentencesExercise, sectionId: nu
sentences: [
...local.sentences,
{
uuid: uuidv4(),
id: newId,
sentence: "",
solution: ""

View File

@@ -11,6 +11,7 @@ import { useCallback, useEffect, useState } from "react";
import { MdAdd } from "react-icons/md";
import Alert, { AlertItem } from "../../Shared/Alert";
import PromptEdit from "../../Shared/PromptEdit";
import { uuidv4 } from "@firebase/util";
const UnderlineMultipleChoice: React.FC<{exercise: MultipleChoiceExercise, sectionId: number}> = ({
@@ -57,6 +58,7 @@ const UnderlineMultipleChoice: React.FC<{exercise: MultipleChoiceExercise, secti
{
prompt: "",
solution: "",
uuid: uuidv4(),
id: newId,
options,
variant: "text"

View File

@@ -18,6 +18,7 @@ import SortableQuestion from '../../Shared/SortableQuestion';
import setEditingAlert from '../../Shared/setEditingAlert';
import { handleMultipleChoiceReorder } from '@/stores/examEditor/reorder/local';
import PromptEdit from '../../Shared/PromptEdit';
import { uuidv4 } from '@firebase/util';
interface MultipleChoiceProps {
exercise: MultipleChoiceExercise;
@@ -120,6 +121,7 @@ const MultipleChoice: React.FC<MultipleChoiceProps> = ({ exercise, sectionId, op
{
prompt: "",
solution: "",
uuid: uuidv4(),
id: newId,
options,
variant: "text"

View File

@@ -16,6 +16,7 @@ import setEditingAlert from '../Shared/setEditingAlert';
import { DragEndEvent } from '@dnd-kit/core';
import { handleTrueFalseReorder } from '@/stores/examEditor/reorder/local';
import PromptEdit from '../Shared/PromptEdit';
import { uuidv4 } from '@firebase/util';
const TrueFalse: React.FC<{ exercise: TrueFalseExercise, sectionId: number }> = ({ exercise, sectionId }) => {
const { currentModule, dispatch } = useExamEditorStore();
@@ -50,6 +51,7 @@ const TrueFalse: React.FC<{ exercise: TrueFalseExercise, sectionId: number }> =
{
prompt: "",
solution: undefined,
uuid: uuidv4(),
id: newId
}
]

View File

@@ -22,6 +22,7 @@ import { validateEmptySolutions, validateQuestionText, validateWordCount } from
import { handleWriteBlanksReorder } from '@/stores/examEditor/reorder/local';
import { ParsedQuestion, parseText, reconstructText } from './parsing';
import PromptEdit from '../Shared/PromptEdit';
import { uuidv4 } from '@firebase/util';
const WriteBlanks: React.FC<{ sectionId: number; exercise: WriteBlanksExercise; }> = ({ sectionId, exercise }) => {
@@ -105,6 +106,7 @@ const WriteBlanks: React.FC<{ sectionId: number; exercise: WriteBlanksExercise;
const newId = (Math.max(...existingIds, 0) + 1).toString();
const newQuestion = {
uuid: uuidv4(),
id: newId,
questionText: "New question"
};
@@ -113,6 +115,7 @@ const WriteBlanks: React.FC<{ sectionId: number; exercise: WriteBlanksExercise;
const updatedText = reconstructText(updatedQuestions);
const updatedSolutions = [...local.solutions, {
uuid: uuidv4(),
id: newId,
solution: [""]
}];

View File

@@ -17,6 +17,7 @@ import { validateQuestions, validateEmptySolutions, validateWordCount } from "./
import Header from "../../Shared/Header";
import BlanksFormEditor from "./BlanksFormEditor";
import PromptEdit from "../Shared/PromptEdit";
import { uuidv4 } from "@firebase/util";
const WriteBlanksForm: React.FC<{ sectionId: number; exercise: WriteBlanksExercise }> = ({ sectionId, exercise }) => {
@@ -111,6 +112,7 @@ const WriteBlanksForm: React.FC<{ sectionId: number; exercise: WriteBlanksExerci
const newLine = `New question with blank {{${newId}}}`;
const updatedQuestions = [...parsedQuestions, {
uuid: uuidv4(),
id: newId,
parts: parseLine(newLine),
editingPlaceholders: true
@@ -121,6 +123,7 @@ const WriteBlanksForm: React.FC<{ sectionId: number; exercise: WriteBlanksExerci
.join('\\n') + '\\n';
const updatedSolutions = [...local.solutions, {
uuid: uuidv4(),
id: newId,
solution: [""]
}];