@@ -14,7 +14,12 @@ import { validateCommonFields } from "../../utils/validation";
1414
1515import { ParsonsExerciseSettings } from "./ParsonsExerciseSettings" ;
1616import { ParsonsPreview } from "./ParsonsPreview" ;
17- import { ParsonsInstructions , ParsonsLanguageSelector , ParsonsBlocksManager } from "./components" ;
17+ import {
18+ ParsonsInstructions ,
19+ ParsonsLanguageSelector ,
20+ ParsonsBlocksManager ,
21+ ParsonsOptions
22+ } from "./components" ;
1823
1924const PARSONS_STEPS = [
2025 { label : "Language" } ,
@@ -39,7 +44,13 @@ const getDefaultFormData = (): ParsonsData => ({
3944 question_type : "parsonsprob" ,
4045 language : "" ,
4146 instructions : "" ,
42- blocks : [ { id : `block-${ Date . now ( ) } ` , content : "" , indent : 0 } ]
47+ blocks : [ { id : `block-${ Date . now ( ) } ` , content : "" , indent : 0 } ] ,
48+ adaptive : true ,
49+ numbered : "left" ,
50+ noindent : false ,
51+ grader : "line" ,
52+ orderMode : "random" ,
53+ customOrder : [ ]
4354} ) ;
4455
4556const generatePreview = ( data : ParsonsData ) : string => {
@@ -48,10 +59,13 @@ const generatePreview = (data: ParsonsData): string => {
4859 blocks : data . blocks || [ ] ,
4960 name : data . name || "parsons_exercise" ,
5061 language : data . language || "python" ,
51- adaptive : true ,
52- numbered : "left" ,
53- noindent : false ,
54- questionLabel : data . name
62+ adaptive : data . adaptive ?? true ,
63+ numbered : data . numbered ?? "left" ,
64+ noindent : data . noindent ?? false ,
65+ questionLabel : data . name ,
66+ grader : data . grader ?? "line" ,
67+ orderMode : data . orderMode ?? "random" ,
68+ customOrder : data . customOrder
5569 } ) ;
5670} ;
5771
@@ -61,10 +75,13 @@ const generateExerciseHtmlSrc = (data: ParsonsData): string => {
6175 instructions : data . instructions || "" ,
6276 blocks : data . blocks || [ ] ,
6377 language : data . language || "python" ,
64- adaptive : true ,
65- numbered : "left" ,
66- noindent : false ,
67- questionLabel : data . name
78+ adaptive : data . adaptive ?? true ,
79+ numbered : data . numbered ?? "left" ,
80+ noindent : data . noindent ?? false ,
81+ questionLabel : data . name ,
82+ grader : data . grader ?? "line" ,
83+ orderMode : data . orderMode ?? "random" ,
84+ customOrder : data . customOrder
6885 } ) ;
6986} ;
7087
@@ -144,6 +161,15 @@ export const ParsonsExercise: FC<ExerciseComponentProps> = ({
144161 [ updateFormData , formData . language , formData . tags ]
145162 ) ;
146163
164+ const handleAddBlock = useCallback ( ( ) => {
165+ const newBlock : ParsonsBlock = {
166+ id : `block-${ Date . now ( ) } ` ,
167+ content : "" ,
168+ indent : 0
169+ } ;
170+ updateFormData ( "blocks" , [ ...( formData . blocks || [ ] ) , newBlock ] ) ;
171+ } , [ updateFormData , formData . blocks ] ) ;
172+
147173 const renderStepContent = ( ) => {
148174 switch ( activeStep ) {
149175 case 0 :
@@ -164,11 +190,43 @@ export const ParsonsExercise: FC<ExerciseComponentProps> = ({
164190
165191 case 2 :
166192 return (
167- < ParsonsBlocksManager
168- blocks = { formData . blocks || [ ] }
169- onChange = { ( blocks : ParsonsBlock [ ] ) => updateFormData ( "blocks" , blocks ) }
170- language = { formData . language || "python" }
171- />
193+ < div className = "flex flex-column gap-4" >
194+ < ParsonsOptions
195+ adaptive = { formData . adaptive ?? true }
196+ numbered = { formData . numbered ?? "left" }
197+ noindent = { formData . noindent ?? false }
198+ grader = { formData . grader ?? "line" }
199+ orderMode = { formData . orderMode ?? "random" }
200+ onAdaptiveChange = { ( value : boolean ) => updateFormData ( "adaptive" , value ) }
201+ onNumberedChange = { ( value : "left" | "right" | "none" ) =>
202+ updateFormData ( "numbered" , value )
203+ }
204+ onNoindentChange = { ( value : boolean ) => updateFormData ( "noindent" , value ) }
205+ onGraderChange = { ( value : "line" | "dag" ) => {
206+ updateFormData ( "grader" , value ) ;
207+ if ( value === "dag" ) {
208+ updateFormData ( "adaptive" , false ) ;
209+ // Auto-assign tags to blocks that don't have them
210+ const updatedBlocks = ( formData . blocks || [ ] ) . map ( ( block , idx ) => {
211+ if ( ! block . tag && ! block . isDistractor && ! block . groupId ) {
212+ return { ...block , tag : String ( idx ) } ;
213+ }
214+ return block ;
215+ } ) ;
216+ updateFormData ( "blocks" , updatedBlocks ) ;
217+ }
218+ } }
219+ onOrderModeChange = { ( value : "random" | "custom" ) => updateFormData ( "orderMode" , value ) }
220+ onAddBlock = { handleAddBlock }
221+ />
222+ < ParsonsBlocksManager
223+ blocks = { formData . blocks || [ ] }
224+ onChange = { ( blocks : ParsonsBlock [ ] ) => updateFormData ( "blocks" , blocks ) }
225+ language = { formData . language || "python" }
226+ grader = { formData . grader ?? "line" }
227+ orderMode = { formData . orderMode ?? "random" }
228+ />
229+ </ div >
172230 ) ;
173231
174232 case 3 :
@@ -181,10 +239,13 @@ export const ParsonsExercise: FC<ExerciseComponentProps> = ({
181239 blocks = { formData . blocks || [ ] }
182240 language = { formData . language || "python" }
183241 name = { formData . name || "" }
184- adaptive = { true }
185- numbered = "left"
186- noindent = { false }
242+ adaptive = { formData . adaptive ?? true }
243+ numbered = { formData . numbered ?? "left" }
244+ noindent = { formData . noindent ?? false }
187245 questionLabel = { formData . name }
246+ grader = { formData . grader ?? "line" }
247+ orderMode = { formData . orderMode ?? "random" }
248+ customOrder = { formData . customOrder }
188249 />
189250 ) ;
190251
0 commit comments