Skip to content

Commit 9548d88

Browse files
committed
Refactor ParsonsExerciseTour component to utilize a configuration file for tour steps, improving maintainability and clarity in the tour logic
Add tour functionality to ParsonsExercise components, enhancing user guidance with interactive steps and tooltips Enhance parsonsPreview to include explanations for distractors and paired blocks, improving clarity in block content representation. Refactor BlockItem component to replace comment functionality with explanation management, enhancing user interaction and clarity in the UI. Enhance BlockItem, ParsonsOptions, and ExerciseLayout components to support mode switching between simple and enhanced views with inline controls for distractor and alternative management Enhance BlockItem and SortableBlock components to support first-in-line logic for option visibility and interaction Refactor: simplify line numbering section in ParsonsOptions component and remove unnecessary styles from modernDropdown Remove paired change logic from BlockItem component on distractor toggle Enhance BlockItem component with a toggle switch for block type selection and improve paired checkbox visibility Enhance BlockItem component with options popover for improved interaction and compact action bar Refactor: update UI components and styles for improved layout and accessibility
1 parent 6fa265d commit 9548d88

16 files changed

Lines changed: 2004 additions & 505 deletions

File tree

bases/rsptx/assignment_server_api/assignment_builder/package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bases/rsptx/assignment_server_api/assignment_builder/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"@tiptap/suggestion": "^2.11.5",
4242
"better-react-mathjax": "^2.1.0",
4343
"classnames": "^2.5.1",
44+
"driver.js": "^1.4.0",
4445
"handsontable": "^14.2.0",
4546
"highlight.js": "^11.11.1",
4647
"html-react-parser": "^5.1.18",

bases/rsptx/assignment_server_api/assignment_builder/src/components/routes/AssignmentBuilder/components/exercises/components/CreateExercise/components/ParsonsExercise/ParsonsExercise.tsx

Lines changed: 114 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import React, { FC, useCallback } from "react";
1+
import React, { FC, useCallback, useState } from "react";
2+
3+
import { SelectButton } from "primereact/selectbutton";
4+
import { confirmDialog, ConfirmDialog } from "primereact/confirmdialog";
25

36
import { CreateExerciseFormType } from "@/types/exercises";
47
import { createExerciseId } from "@/utils/exercise";
@@ -20,6 +23,15 @@ import {
2023
ParsonsBlocksManager,
2124
ParsonsOptions
2225
} from "./components";
26+
import { ParsonsExerciseTour } from "./components/ParsonsExerciseTour";
27+
import parsonsStyles from "./components/ParsonsExercise.module.css";
28+
29+
export type ParsonsMode = "simple" | "enhanced";
30+
31+
const MODE_OPTIONS = [
32+
{ label: "Simple", value: "simple" },
33+
{ label: "Enhanced", value: "enhanced" }
34+
];
2335

2436
const PARSONS_STEPS = [
2537
{ label: "Language" },
@@ -170,6 +182,82 @@ export const ParsonsExercise: FC<ExerciseComponentProps> = ({
170182
updateFormData("blocks", [...(formData.blocks || []), newBlock]);
171183
}, [updateFormData, formData.blocks]);
172184

185+
// --- Mode switcher ---
186+
const isEnhancedExercise =
187+
isEdit &&
188+
(initialData?.grader === "dag" ||
189+
initialData?.orderMode === "custom" ||
190+
initialData?.numbered === "right" ||
191+
initialData?.numbered === "none" ||
192+
initialData?.noindent === true);
193+
194+
const [mode, setMode] = useState<ParsonsMode>(isEnhancedExercise ? "enhanced" : "simple");
195+
196+
const directSetMode = useCallback((newMode: ParsonsMode) => {
197+
setMode(newMode);
198+
}, []);
199+
200+
const tourButton = (
201+
<ParsonsExerciseTour
202+
mode={mode}
203+
formData={formData}
204+
onModeChange={directSetMode}
205+
updateFormData={updateFormData as (key: string, value: any) => void}
206+
/>
207+
);
208+
209+
const handleModeChange = useCallback(
210+
(newMode: ParsonsMode) => {
211+
if (newMode === mode || !newMode) return;
212+
213+
if (newMode === "simple") {
214+
// Enhanced → Simple: confirm and reset
215+
confirmDialog({
216+
message:
217+
"Switching to Simple Mode will reset Grader, Order, Line Numbers, and No Indent to their default values. Block dropdown settings (DAG tags, dependencies, custom order) will be cleared. Continue?",
218+
header: "Switch to Simple Mode",
219+
icon: "pi pi-exclamation-triangle",
220+
acceptClassName: "p-button-warning",
221+
accept: () => {
222+
// Reset locked fields
223+
updateFormData("grader", "line");
224+
updateFormData("orderMode", "random");
225+
updateFormData("numbered", "left");
226+
updateFormData("noindent", false);
227+
updateFormData("adaptive", true);
228+
updateFormData("customOrder", []);
229+
// Clear DAG / order block fields
230+
const clearedBlocks = (formData.blocks || []).map((block) => ({
231+
...block,
232+
tag: undefined,
233+
depends: undefined,
234+
displayOrder: undefined
235+
}));
236+
updateFormData("blocks", clearedBlocks);
237+
setMode("simple");
238+
}
239+
});
240+
} else {
241+
// Simple → Enhanced: no data loss, just switch
242+
setMode("enhanced");
243+
}
244+
},
245+
[mode, updateFormData, formData.blocks]
246+
);
247+
248+
const modeSwitcher = (
249+
<div className={parsonsStyles.modeSwitcher} data-tour="mode-switcher">
250+
<span className={parsonsStyles.modeSwitcherLabel}>Mode</span>
251+
<SelectButton
252+
value={mode}
253+
options={MODE_OPTIONS}
254+
onChange={(e) => handleModeChange(e.value)}
255+
className={parsonsStyles.modeSwitcherButton}
256+
allowEmpty={false}
257+
/>
258+
</div>
259+
);
260+
173261
const renderStepContent = () => {
174262
switch (activeStep) {
175263
case 0:
@@ -197,6 +285,7 @@ export const ParsonsExercise: FC<ExerciseComponentProps> = ({
197285
noindent={formData.noindent ?? false}
198286
grader={formData.grader ?? "line"}
199287
orderMode={formData.orderMode ?? "random"}
288+
mode={mode}
200289
onAdaptiveChange={(value: boolean) => updateFormData("adaptive", value)}
201290
onNumberedChange={(value: "left" | "right" | "none") =>
202291
updateFormData("numbered", value)
@@ -218,13 +307,15 @@ export const ParsonsExercise: FC<ExerciseComponentProps> = ({
218307
}}
219308
onOrderModeChange={(value: "random" | "custom") => updateFormData("orderMode", value)}
220309
onAddBlock={handleAddBlock}
310+
tourButton={tourButton}
221311
/>
222312
<ParsonsBlocksManager
223313
blocks={formData.blocks || []}
224314
onChange={(blocks: ParsonsBlock[]) => updateFormData("blocks", blocks)}
225315
language={formData.language || "python"}
226316
grader={formData.grader ?? "line"}
227317
orderMode={formData.orderMode ?? "random"}
318+
mode={mode}
228319
/>
229320
</div>
230321
);
@@ -255,23 +346,27 @@ export const ParsonsExercise: FC<ExerciseComponentProps> = ({
255346
};
256347

257348
return (
258-
<ExerciseLayout
259-
title="Parsons Exercise"
260-
exerciseType="parsonsprob"
261-
isEdit={isEdit}
262-
steps={PARSONS_STEPS}
263-
activeStep={activeStep}
264-
isCurrentStepValid={isCurrentStepValid}
265-
isSaving={isSaving}
266-
stepsValidity={stepsValidity}
267-
onCancel={onCancel}
268-
onBack={goToPrevStep}
269-
onNext={handleNext}
270-
onSave={handleSave}
271-
onStepSelect={handleStepSelect}
272-
validation={validation}
273-
>
274-
{renderStepContent()}
275-
</ExerciseLayout>
349+
<>
350+
<ConfirmDialog />
351+
<ExerciseLayout
352+
title="Parsons Exercise"
353+
exerciseType="parsonsprob"
354+
isEdit={isEdit}
355+
steps={PARSONS_STEPS}
356+
activeStep={activeStep}
357+
isCurrentStepValid={isCurrentStepValid}
358+
isSaving={isSaving}
359+
stepsValidity={stepsValidity}
360+
onCancel={onCancel}
361+
onBack={goToPrevStep}
362+
onNext={handleNext}
363+
onSave={handleSave}
364+
onStepSelect={handleStepSelect}
365+
validation={validation}
366+
headerExtra={modeSwitcher}
367+
>
368+
{renderStepContent()}
369+
</ExerciseLayout>
370+
</>
276371
);
277372
};

0 commit comments

Comments
 (0)