diff --git a/assets/src/js/v3/entries/course-builder/components/curriculum/QuestionList.tsx b/assets/src/js/v3/entries/course-builder/components/curriculum/QuestionList.tsx index 0b828516ec..ce9f5a210a 100644 --- a/assets/src/js/v3/entries/course-builder/components/curriculum/QuestionList.tsx +++ b/assets/src/js/v3/entries/course-builder/components/curriculum/QuestionList.tsx @@ -269,6 +269,7 @@ const QuestionList = ({ isEditing }: { isEditing: boolean }) => { }), ...(questionType === 'puzzle' && { puzzle_grid_size: 4, + enable_puzzle_answer_background: true, }), ...(questionType === 'coordinates' && { coordinates_axis_range: 10, diff --git a/assets/src/js/v3/entries/course-builder/components/modals/QuestionPreviewModal.tsx b/assets/src/js/v3/entries/course-builder/components/modals/QuestionPreviewModal.tsx index 950656029d..595a242a28 100644 --- a/assets/src/js/v3/entries/course-builder/components/modals/QuestionPreviewModal.tsx +++ b/assets/src/js/v3/entries/course-builder/components/modals/QuestionPreviewModal.tsx @@ -410,6 +410,7 @@ const renderQuestionPreview = (question: QuizQuestion) => { answers={question.question_answers} gridSize={question.question_settings.puzzle_grid_size} questionId={question.question_id} + showPuzzleAnswerBackground={question.question_settings?.enable_puzzle_answer_background ?? true} /> ); } diff --git a/assets/src/js/v3/entries/course-builder/components/modals/question-previews/PuzzlePreview.tsx b/assets/src/js/v3/entries/course-builder/components/modals/question-previews/PuzzlePreview.tsx index 60fd850175..f9547c4d65 100644 --- a/assets/src/js/v3/entries/course-builder/components/modals/question-previews/PuzzlePreview.tsx +++ b/assets/src/js/v3/entries/course-builder/components/modals/question-previews/PuzzlePreview.tsx @@ -17,13 +17,19 @@ interface PuzzlePreviewProps { gridSize?: number | string; /** Used for hidden input id parity with `puzzle.php` (`tutor-puzzle-state-{id}`). */ questionId: ID; + showPuzzleAnswerBackground?: boolean; } /** * Course Builder puzzle preview — loads Tutor Pro `puzzle-question.js` in the preview iframe * (same pattern as {@link DrawImagePreview}, {@link PinImagePreview}, {@link ScalePreview}). */ -const PuzzlePreview = ({ answers, gridSize: gridSizeProp, questionId }: PuzzlePreviewProps) => { +const PuzzlePreview = ({ + answers, + gridSize: gridSizeProp, + questionId, + showPuzzleAnswerBackground = true, +}: PuzzlePreviewProps) => { const answer = answers[0]; const imageUrl = answer?.image_url || answer?.answer_two_gap_match || ''; const gridSize = clampGridSize(gridSizeProp); @@ -91,11 +97,17 @@ const PuzzlePreview = ({ answers, gridSize: gridSizeProp, questionId }: PuzzlePr const instructionId = `tutor-puzzle-instruction-${questionId}`; const statusId = `tutor-puzzle-status-${questionId}`; const describedByIds = `${instructionId} ${statusId}`; + const wrapperClassName = [ + 'quiz-question-ans-choice-area tutor-mt-40 tutor-puzzle-question question-type-puzzle', + showPuzzleAnswerBackground ? '' : 'tutor-puzzle-question--no-answer-background', + ] + .filter(Boolean) + .join(' '); return (
- {__('Puzzle + {__('Puzzle
{ >; gridSizeControllerProps?: FormControllerProps; gridSizePath?: string; + backgroundControllerProps?: FormControllerProps; } -const FormPuzzle = ({ field, activeQuestionIndex = 0, gridSizeControllerProps, gridSizePath }: FormPuzzleProps) => { +const FormPuzzle = ({ + field, + activeQuestionIndex = 0, + gridSizeControllerProps, + gridSizePath, + backgroundControllerProps, +}: FormPuzzleProps) => { const form = useFormContext(); const option = field.value; const resolvedGridSizePath = gridSizePath ?? (`questions.${activeQuestionIndex}.question_settings.puzzle_grid_size` as const); + const resolvedBackgroundPath = Array.isArray(form?.getValues?.('questions')) + ? (`questions.${activeQuestionIndex}.question_settings.enable_puzzle_answer_background` as const) + : ('question_settings.enable_puzzle_answer_background' as const); const resolvedQuestionDataStatusPath = Array.isArray(form?.getValues?.('questions')) ? (`questions.${activeQuestionIndex}._data_status` as const) : ('_data_status' as const); @@ -122,6 +134,22 @@ const FormPuzzle = ({ field, activeQuestionIndex = 0, gridSizeControllerProps, g return null; } + const renderBackgroundSwitch = (controllerProps: FormControllerProps) => ( + { + if (form && calculateQuizDataStatus(activeQuestionDataStatus, QuizDataStatus.UPDATE)) { + form.setValue( + resolvedQuestionDataStatusPath, + calculateQuizDataStatus(activeQuestionDataStatus, QuizDataStatus.UPDATE) as QuizDataStatus, + ); + } + }} + /> + ); + return (
@@ -158,7 +186,7 @@ const FormPuzzle = ({ field, activeQuestionIndex = 0, gridSizeControllerProps, g helpText={__('Larger grids create more pieces and a harder puzzle for learners.', __TUTOR_TEXT_DOMAIN__)} onChange={(selectedOption) => { gridSizeControllerProps.field.onChange(selectedOption.value); - if (calculateQuizDataStatus(activeQuestionDataStatus, QuizDataStatus.UPDATE)) { + if (form && calculateQuizDataStatus(activeQuestionDataStatus, QuizDataStatus.UPDATE)) { form.setValue( resolvedQuestionDataStatusPath, calculateQuizDataStatus(activeQuestionDataStatus, QuizDataStatus.UPDATE) as QuizDataStatus, @@ -195,6 +223,19 @@ const FormPuzzle = ({ field, activeQuestionIndex = 0, gridSizeControllerProps, g )} /> )} + + + {backgroundControllerProps ? ( + renderBackgroundSwitch(backgroundControllerProps) + ) : ( + + )} +
diff --git a/assets/src/js/v3/shared/utils/quiz.ts b/assets/src/js/v3/shared/utils/quiz.ts index dc086eb1bc..bcebe2b3c9 100644 --- a/assets/src/js/v3/shared/utils/quiz.ts +++ b/assets/src/js/v3/shared/utils/quiz.ts @@ -235,6 +235,10 @@ export const convertedQuestion = (question: Omit): if (rawGridSize !== undefined && rawGridSize !== null && !Number.isNaN(Number(rawGridSize))) { question.question_settings.puzzle_grid_size = Number(rawGridSize); } + question.question_settings.enable_puzzle_answer_background = + question.question_settings.enable_puzzle_answer_background === undefined + ? true + : !!Number(question.question_settings.enable_puzzle_answer_background); } if (question.question_type === 'coordinates') { const rawCoordinatesAxisRange = question.question_settings.coordinates_axis_range; diff --git a/assets/src/js/v3/shared/utils/types.ts b/assets/src/js/v3/shared/utils/types.ts index 0f56e3b012..5ac6db7a29 100644 --- a/assets/src/js/v3/shared/utils/types.ts +++ b/assets/src/js/v3/shared/utils/types.ts @@ -343,6 +343,7 @@ export interface QuizQuestion { is_image_matching: boolean; draw_image_threshold_percent?: number; puzzle_grid_size?: number; + enable_puzzle_answer_background?: boolean; coordinates_axis_range?: number; }; question_answers: QuizQuestionOption[]; @@ -360,6 +361,7 @@ export interface QuizQuestionsForPayload extends Omit