improve edited exam changes again

This commit is contained in:
Joao Correia
2025-02-10 11:30:24 +00:00
parent c14f16c97a
commit e214d8b598
2 changed files with 46 additions and 21 deletions

View File

@@ -557,7 +557,7 @@ export default function Home({ user, initialWorkflow, id, workflowAssignees, wor
<div className="p-3 border border-gray-300 rounded-xl bg-white bg-opacity-80 overflow-y-auto max-h-40"> <div className="p-3 border border-gray-300 rounded-xl bg-white bg-opacity-80 overflow-y-auto max-h-40">
{currentWorkflow.steps[selectedStepIndex].examChanges?.length ? ( {currentWorkflow.steps[selectedStepIndex].examChanges?.length ? (
currentWorkflow.steps[selectedStepIndex].examChanges!.map((change, index) => ( currentWorkflow.steps[selectedStepIndex].examChanges!.map((change, index) => (
<p key={index} className="text-sm text-gray-500 mb-2"> <p key={index} className="whitespace-pre-wrap text-sm text-gray-500 mb-2">
{change} {change}
</p> </p>
)) ))

View File

@@ -1,9 +1,10 @@
import { Exam } from "@/interfaces/exam"; import { Exam } from "@/interfaces/exam";
import { diff, Diff } from "deep-diff"; import { diff, Diff } from "deep-diff";
const EXCLUDED_KEYS = new Set(["_id", "id", "createdAt", "createdBy", "entities", "isDiagnostic", "private", "access", "requiresApproval"]); const EXCLUDED_KEYS = new Set<string>(["_id", "id", "createdAt", "createdBy", "entities", "isDiagnostic", "private", "requiresApproval", "exerciseID", "questionID"]);
const PATH_LABELS: Record<string, string> = { const PATH_LABELS: Record<string, string> = {
access: "Access Type",
parts: "Parts", parts: "Parts",
exercises: "Exercises", exercises: "Exercises",
userSolutions: "User Solutions", userSolutions: "User Solutions",
@@ -20,6 +21,9 @@ const PATH_LABELS: Record<string, string> = {
prefix: "Prefix", prefix: "Prefix",
suffix: "Suffix", suffix: "Suffix",
topic: "Topic", topic: "Topic",
allowRepetition: "Allow Repetition",
maxWords: "Max Words",
minTimer: "Timer",
}; };
export function generateExamDifferences(oldExam: Exam, newExam: Exam): string[] { export function generateExamDifferences(oldExam: Exam, newExam: Exam): string[] {
@@ -28,9 +32,7 @@ export function generateExamDifferences(oldExam: Exam, newExam: Exam): string[]
} }
function formatDifference(change: Diff<any, any>): string | undefined { function formatDifference(change: Diff<any, any>): string | undefined {
if (!change.path) { if (!change.path) return;
return;
}
if (change.path.some((segment) => EXCLUDED_KEYS.has(segment))) { if (change.path.some((segment) => EXCLUDED_KEYS.has(segment))) {
return; return;
@@ -85,30 +87,53 @@ function formatValue(value: any): string {
if (typeof value === "object") { if (typeof value === "object") {
try { try {
return JSON.stringify( const sanitized = removeExcludedKeysDeep(value, EXCLUDED_KEYS);
value,
(key, val) => { const renamed = renameKeysDeep(sanitized, PATH_LABELS);
if (EXCLUDED_KEYS.has(key)) {
return undefined; return JSON.stringify(renamed, null, 2);
}
return val;
},
2 // optional indentation for readability
);
} catch { } catch {
return String(value); return String(value);
} }
} }
return JSON.stringify(value); return JSON.stringify(value);
} }
function removeExcludedKeysDeep(obj: any, excludedKeys: Set<string>): any {
if (Array.isArray(obj)) {
return obj.map((item) => removeExcludedKeysDeep(item, excludedKeys));
} else if (obj && typeof obj === "object") {
const newObj: any = {};
for (const key of Object.keys(obj)) {
if (excludedKeys.has(key)) {
// Skip this key entirely
continue;
}
newObj[key] = removeExcludedKeysDeep(obj[key], excludedKeys);
}
return newObj;
}
return obj;
}
function renameKeysDeep(obj: any, renameMap: Record<string, string>): any {
if (Array.isArray(obj)) {
return obj.map((item) => renameKeysDeep(item, renameMap));
} else if (obj && typeof obj === "object") {
const newObj: any = {};
for (const key of Object.keys(obj)) {
const newKey = renameMap[key] ?? key; // Use friendly label if available
newObj[newKey] = renameKeysDeep(obj[key], renameMap);
}
return newObj;
}
return obj;
}
/** /**
* Convert an array of path segments into a friendlier string. * Convert an array of path segments into a user-friendly string.
* Example: * e.g. ["parts", 0, "exercises", 1, "prompt"]
* ["parts", 0, "exercises", 1, "prompt"] * → "Parts → [#1] → Exercises → [#2] → Prompt"
* becomes:
* "Parts → [#1] → Exercises → [#2] → Prompt"
*/ */
function pathToHumanReadable(pathSegments: Array<string | number>): string { function pathToHumanReadable(pathSegments: Array<string | number>): string {
return pathSegments return pathSegments