Feat add templates for default problems after problem select (#185)
https://2u-internal.atlassian.net/browse/TNL-10316 is the relevant bug. Problems have default values when created using the select type page.
This commit is contained in:
@@ -17,7 +17,6 @@ export const SelectTypeFooter = ({
|
||||
onCancel,
|
||||
selected,
|
||||
// redux
|
||||
setProblemType,
|
||||
updateField,
|
||||
// injected,
|
||||
intl,
|
||||
@@ -35,7 +34,7 @@ export const SelectTypeFooter = ({
|
||||
</Button>
|
||||
<Button
|
||||
aria-label={intl.formatMessage(messages.selectButtonAriaLabel)}
|
||||
onClick={hooks.onSelect(setProblemType, selected, updateField)}
|
||||
onClick={hooks.onSelect(selected, updateField)}
|
||||
disabled={!selected}
|
||||
>
|
||||
<FormattedMessage {...messages.selectButtonLabel} />
|
||||
@@ -52,7 +51,6 @@ SelectTypeFooter.defaultProps = {
|
||||
SelectTypeFooter.propTypes = {
|
||||
onCancel: PropTypes.func.isRequired,
|
||||
selected: PropTypes.string,
|
||||
setProblemType: PropTypes.func.isRequired,
|
||||
updateField: PropTypes.func.isRequired,
|
||||
// injected
|
||||
intl: intlShape.isRequired,
|
||||
@@ -62,7 +60,6 @@ export const mapStateToProps = () => ({
|
||||
});
|
||||
|
||||
export const mapDispatchToProps = {
|
||||
setProblemType: actions.problem.setProblemType,
|
||||
updateField: actions.problem.updateField,
|
||||
};
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ describe('SelectTypeFooter', () => {
|
||||
onCancel: jest.fn().mockName('onCancel'),
|
||||
selected: null,
|
||||
// redux
|
||||
setProblemType: jest.fn().mockName('setProblemType'),
|
||||
updateField: jest.fn().mockName('UpdateField'),
|
||||
// inject
|
||||
intl: { formatMessage },
|
||||
};
|
||||
@@ -36,7 +36,7 @@ describe('SelectTypeFooter', () => {
|
||||
.toEqual(expected);
|
||||
});
|
||||
test('select behavior is linked to modal onSelect', () => {
|
||||
const expected = hooks.onSelect(props.setProblemType, props.selected);
|
||||
const expected = hooks.onSelect(props.selected, props.updateField);
|
||||
expect(el.find(Button).last().props().onClick)
|
||||
.toEqual(expected);
|
||||
});
|
||||
@@ -48,8 +48,8 @@ describe('SelectTypeFooter', () => {
|
||||
});
|
||||
});
|
||||
describe('mapDispatchToProps', () => {
|
||||
test('loads setProblemType from problem.setProblemType actions', () => {
|
||||
expect(module.mapDispatchToProps.setProblemType).toEqual(actions.problem.setProblemType);
|
||||
test('loads updateField from problem.updateField actions', () => {
|
||||
expect(module.mapDispatchToProps.updateField).toEqual(actions.problem.updateField);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
} from '../../../../data/constants/problem';
|
||||
import { StrictDict } from '../../../../utils';
|
||||
import * as module from './hooks';
|
||||
import { getDataFromOlx } from '../../../../data/redux/thunkActions/problem';
|
||||
|
||||
export const state = StrictDict({
|
||||
selected: (val) => useState(val),
|
||||
@@ -17,12 +18,14 @@ export const selectHooks = () => {
|
||||
};
|
||||
};
|
||||
|
||||
export const onSelect = (setProblemType, selected, updateField) => () => {
|
||||
export const onSelect = (selected, updateField) => () => {
|
||||
if (Object.values(AdvanceProblemKeys).includes(selected)) {
|
||||
updateField({ problemType: ProblemTypeKeys.ADVANCED, rawOLX: AdvanceProblems[selected].template });
|
||||
return;
|
||||
updateField({ problemType: ProblemTypeKeys.ADVANCED, rawOLX: AdvanceProblems[selected] });
|
||||
} else {
|
||||
const newOLX = ProblemTypes[selected].template;
|
||||
const { settings, ...newState } = getDataFromOlx({ rawOLX: newOLX, rawSettings: {} });
|
||||
updateField({ ...newState });
|
||||
}
|
||||
setProblemType({ selected });
|
||||
};
|
||||
|
||||
export const useArrowNav = (selected, setSelected) => {
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
import React from 'react';
|
||||
import { MockUseState } from '../../../../../testUtils';
|
||||
import * as module from './hooks';
|
||||
import { AdvanceProblems, ProblemTypeKeys } from '../../../../data/constants/problem';
|
||||
import { AdvanceProblems, ProblemTypeKeys, ProblemTypes } from '../../../../data/constants/problem';
|
||||
import { OLXParser } from '../../data/OLXParser';
|
||||
|
||||
jest.mock('react', () => ({
|
||||
...jest.requireActual('react'),
|
||||
@@ -11,10 +12,9 @@ jest.mock('react', () => ({
|
||||
}));
|
||||
|
||||
const state = new MockUseState(module);
|
||||
const mockSetProblemType = jest.fn().mockName('setProblemType');
|
||||
const mockUpdateField = jest.fn().mockName('updateField');
|
||||
const mockSelected = 'vAl';
|
||||
const mockAdvancedSelected = 'blankadvanced';
|
||||
const mockSelected = 'multiplechoiceresponse';
|
||||
const mockAdvancedSelected = 'circuitschematic';
|
||||
const mockSetSelected = jest.fn().mockName('setSelected');
|
||||
|
||||
let hook;
|
||||
@@ -45,15 +45,20 @@ describe('SelectTypeModal hooks', () => {
|
||||
|
||||
describe('onSelect', () => {
|
||||
test('updateField is called with selected templated if selected is an Advanced Problem', () => {
|
||||
module.onSelect(mockSetProblemType, mockAdvancedSelected, mockUpdateField)();
|
||||
module.onSelect(mockAdvancedSelected, mockUpdateField)();
|
||||
expect(mockUpdateField).toHaveBeenCalledWith({
|
||||
problemType: ProblemTypeKeys.ADVANCED,
|
||||
rawOLX: AdvanceProblems[mockAdvancedSelected].template,
|
||||
rawOLX: AdvanceProblems[mockAdvancedSelected],
|
||||
});
|
||||
});
|
||||
test('setProblemType is called with selected', () => {
|
||||
module.onSelect(mockSetProblemType, mockSelected, mockUpdateField)();
|
||||
expect(mockSetProblemType).toHaveBeenCalledWith({ selected: mockSelected });
|
||||
test('updateField is called with selected on visual propblems', () => {
|
||||
module.onSelect(mockSelected, mockUpdateField)();
|
||||
const testOlXParser = new OLXParser(ProblemTypes[mockSelected].template);
|
||||
const { settings, ...testState } = testOlXParser.getParsedOLXData();
|
||||
expect(mockUpdateField).toHaveBeenCalledWith({
|
||||
...testState,
|
||||
rawOLX: ProblemTypes[mockSelected].template,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
12
src/editors/data/constants/advancedOlxTemplates/index.js
Normal file
12
src/editors/data/constants/advancedOlxTemplates/index.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import { StrictDict } from '../../../utils';
|
||||
import circuitSchematic from './circuitschematic';
|
||||
import customGrader from './customgrader';
|
||||
import dragAndDrop from './drag_and_drop';
|
||||
import formulaResponse from './formularesponse';
|
||||
import imageResponse from './imageresponse';
|
||||
import jsInputResponse from './jsinput_response';
|
||||
import problemWithHint from './problem_with_hint';
|
||||
|
||||
export default StrictDict({
|
||||
circuitSchematic, customGrader, dragAndDrop, formulaResponse, imageResponse, jsInputResponse, problemWithHint,
|
||||
});
|
||||
15
src/editors/data/constants/basicOlxTemplates/dropdown.js
Normal file
15
src/editors/data/constants/basicOlxTemplates/dropdown.js
Normal file
@@ -0,0 +1,15 @@
|
||||
/* eslint-disable */
|
||||
export const dropdown = `<problem>
|
||||
<optionresponse>
|
||||
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for dropdown problems. Edit this component to replace this template with your own assessment.</p>
|
||||
<label>Add the question text, or prompt, here. This text is required.</label>
|
||||
<description>You can add an optional tip or note related to the prompt like this. </description>
|
||||
<optioninput>
|
||||
<option correct="False">an incorrect answer</option>
|
||||
<option correct="True">the correct answer</option>
|
||||
<option correct="False">an incorrect answer</option>
|
||||
</optioninput>
|
||||
</optionresponse>
|
||||
</problem>`
|
||||
|
||||
export default dropdown;
|
||||
10
src/editors/data/constants/basicOlxTemplates/index.js
Normal file
10
src/editors/data/constants/basicOlxTemplates/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import { StrictDict } from '../../../utils';
|
||||
import dropdown from './dropdown';
|
||||
import multiSelect from './multiSelect';
|
||||
import numeric from './numeric';
|
||||
import singleSelect from './singleSelect';
|
||||
import textInput from './textInput';
|
||||
|
||||
export default StrictDict({
|
||||
dropdown, multiSelect, numeric, singleSelect, textInput,
|
||||
});
|
||||
15
src/editors/data/constants/basicOlxTemplates/multiSelect.js
Normal file
15
src/editors/data/constants/basicOlxTemplates/multiSelect.js
Normal file
@@ -0,0 +1,15 @@
|
||||
/* eslint-disable */
|
||||
const multiSelect= `<problem>
|
||||
<choiceresponse>
|
||||
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for checkboxes problems. Edit this component to replace this template with your own assessment.</p>
|
||||
<label>Add the question text, or prompt, here. This text is required.</label>
|
||||
<description>You can add an optional tip or note related to the prompt like this. </description>
|
||||
<checkboxgroup>
|
||||
<choice correct="true">a correct answer</choice>
|
||||
<choice correct="false">an incorrect answer</choice>
|
||||
<choice correct="false">an incorrect answer</choice>
|
||||
<choice correct="true">a correct answer</choice>
|
||||
</checkboxgroup>
|
||||
</choiceresponse>
|
||||
</problem>`
|
||||
export default multiSelect;
|
||||
12
src/editors/data/constants/basicOlxTemplates/numeric.js
Normal file
12
src/editors/data/constants/basicOlxTemplates/numeric.js
Normal file
@@ -0,0 +1,12 @@
|
||||
/* eslint-disable */
|
||||
export const numeric = `<problem>
|
||||
<numericalresponse answer="100">
|
||||
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for numerical input problems. Edit this component to replace this template with your own assessment.</p>
|
||||
<label>Add the question text, or prompt, here. This text is required.</label>
|
||||
<description>You can add an optional tip or note related to the prompt like this. </description>
|
||||
<responseparam type="tolerance" default="5"/>
|
||||
<formulaequationinput/>
|
||||
</numericalresponse>
|
||||
</problem>`
|
||||
|
||||
export default numeric;
|
||||
14
src/editors/data/constants/basicOlxTemplates/singleSelect.js
Normal file
14
src/editors/data/constants/basicOlxTemplates/singleSelect.js
Normal file
@@ -0,0 +1,14 @@
|
||||
/* eslint-disable */
|
||||
export const singleSelect = `<problem>
|
||||
<multiplechoiceresponse>
|
||||
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for multiple choice problems. Edit this component to replace this template with your own assessment.</p>
|
||||
<label>Add the question text, or prompt, here. This text is required.</label>
|
||||
<description>You can add an optional tip or note related to the prompt like this.</description>
|
||||
<choicegroup>
|
||||
<choice correct="false">an incorrect answer</choice>
|
||||
<choice correct="true">the correct answer</choice>
|
||||
<choice correct="false">an incorrect answer</choice>
|
||||
</choicegroup>
|
||||
</multiplechoiceresponse>
|
||||
</problem>`
|
||||
export default singleSelect;
|
||||
11
src/editors/data/constants/basicOlxTemplates/textInput.js
Normal file
11
src/editors/data/constants/basicOlxTemplates/textInput.js
Normal file
@@ -0,0 +1,11 @@
|
||||
/* eslint-disable */
|
||||
const textInput =`<problem>
|
||||
<stringresponse answer="the correct answer" type="ci">
|
||||
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for text input problems. Edit this component to replace this template with your own assessment.</p>
|
||||
<label>Add the question text, or prompt, here. This text is required.</label>
|
||||
<description>You can add an optional tip or note related to the prompt like this. </description>
|
||||
<additional_answer answer="optional acceptable variant of the correct answer"/>
|
||||
<textline size="20"/>
|
||||
</stringresponse>
|
||||
</problem>`
|
||||
export default textInput;
|
||||
@@ -4,13 +4,8 @@ import multiSelect from '../images/multiSelect.png';
|
||||
import dropdown from '../images/dropdown.png';
|
||||
import numericalInput from '../images/numericalInput.png';
|
||||
import textInput from '../images/textInput.png';
|
||||
import { circuitSchematic } from './olxTemplates/circuitschematic';
|
||||
import { customGrader } from './olxTemplates/customgrader';
|
||||
import { dragAndDrop } from './olxTemplates/drag_and_drop';
|
||||
import { formulaResponse } from './olxTemplates/formularesponse';
|
||||
import { imageResponse } from './olxTemplates/imageresponse';
|
||||
import { jsInputResponse } from './olxTemplates/jsinput_response';
|
||||
import { problemWithHint } from './olxTemplates/problem_with_hint';
|
||||
import advancedOlxTemplates from './advancedOlxTemplates';
|
||||
import basicOlxTemplates from './basicOlxTemplates';
|
||||
|
||||
export const ProblemTypeKeys = StrictDict({
|
||||
SINGLESELECT: 'multiplechoiceresponse',
|
||||
@@ -29,6 +24,8 @@ export const ProblemTypes = StrictDict({
|
||||
helpLink: 'https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/multiple_choice.html',
|
||||
prev: ProblemTypeKeys.TEXTINPUT,
|
||||
next: ProblemTypeKeys.MULTISELECT,
|
||||
template: basicOlxTemplates.singleSelect,
|
||||
|
||||
},
|
||||
[ProblemTypeKeys.MULTISELECT]: {
|
||||
title: 'Multi Select Problem',
|
||||
@@ -37,6 +34,7 @@ export const ProblemTypes = StrictDict({
|
||||
helpLink: 'https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/checkbox.html',
|
||||
next: ProblemTypeKeys.DROPDOWN,
|
||||
prev: ProblemTypeKeys.SINGLESELECT,
|
||||
template: basicOlxTemplates.multiSelect,
|
||||
},
|
||||
[ProblemTypeKeys.DROPDOWN]: {
|
||||
title: 'Dropdown Problem',
|
||||
@@ -45,6 +43,7 @@ export const ProblemTypes = StrictDict({
|
||||
helpLink: 'https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/dropdown.html',
|
||||
next: ProblemTypeKeys.NUMERIC,
|
||||
prev: ProblemTypeKeys.MULTISELECT,
|
||||
template: basicOlxTemplates.dropdown,
|
||||
},
|
||||
[ProblemTypeKeys.NUMERIC]: {
|
||||
title: 'Numeric Response Problem',
|
||||
@@ -53,6 +52,7 @@ export const ProblemTypes = StrictDict({
|
||||
helpLink: 'https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/numerical_input.html',
|
||||
next: ProblemTypeKeys.TEXTINPUT,
|
||||
prev: ProblemTypeKeys.DROPDOWN,
|
||||
template: basicOlxTemplates.numeric,
|
||||
},
|
||||
[ProblemTypeKeys.TEXTINPUT]: {
|
||||
title: 'Text Input Problem',
|
||||
@@ -61,6 +61,7 @@ export const ProblemTypes = StrictDict({
|
||||
helpLink: 'https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/text_input.html',
|
||||
prev: ProblemTypeKeys.NUMERIC,
|
||||
next: ProblemTypeKeys.SINGLESELECT,
|
||||
template: basicOlxTemplates.textInput,
|
||||
},
|
||||
[ProblemTypeKeys.ADVANCED]: {
|
||||
title: 'Advanced Problem',
|
||||
@@ -90,37 +91,37 @@ export const AdvanceProblems = StrictDict({
|
||||
[AdvanceProblemKeys.CIRCUITSCHEMATIC]: {
|
||||
title: 'Circuit schematic builder',
|
||||
status: 'Not supported',
|
||||
template: circuitSchematic,
|
||||
template: advancedOlxTemplates.circuitSchematic,
|
||||
},
|
||||
[AdvanceProblemKeys.JSINPUT]: {
|
||||
title: 'Custom JavaScript display and grading',
|
||||
status: '',
|
||||
template: jsInputResponse,
|
||||
template: advancedOlxTemplates.jsInputResponse,
|
||||
},
|
||||
[AdvanceProblemKeys.CUSTOMGRADER]: {
|
||||
title: 'Custom Python-evaluated input',
|
||||
status: 'Provisional',
|
||||
template: customGrader,
|
||||
template: advancedOlxTemplates.customGrader,
|
||||
},
|
||||
[AdvanceProblemKeys.DRAGANDDROP]: {
|
||||
title: 'Drag and drop (deprecated version)',
|
||||
status: 'Not supported',
|
||||
template: dragAndDrop,
|
||||
template: advancedOlxTemplates.dragAndDrop,
|
||||
},
|
||||
[AdvanceProblemKeys.IMAGE]: {
|
||||
title: 'Image mapped input',
|
||||
status: 'Not supported',
|
||||
template: imageResponse,
|
||||
template: advancedOlxTemplates.imageResponse,
|
||||
},
|
||||
[AdvanceProblemKeys.FORMULA]: {
|
||||
title: 'Math expression input',
|
||||
status: '',
|
||||
template: formulaResponse,
|
||||
template: advancedOlxTemplates.formulaResponse,
|
||||
},
|
||||
[AdvanceProblemKeys.PROBLEMWITHHINT]: {
|
||||
title: 'Problem with adaptive hint',
|
||||
status: 'Not supported',
|
||||
template: problemWithHint,
|
||||
template: advancedOlxTemplates.problemWithHint,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -144,10 +144,6 @@ const problem = createSlice({
|
||||
...state,
|
||||
problemType: null,
|
||||
}),
|
||||
setProblemType: (state, { payload: { selected } }) => ({
|
||||
...state,
|
||||
problemType: selected,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ export const fetchBlockById = ({ blockId, studioEndpointUrl }) => {
|
||||
let data = {};
|
||||
if (blockId === 'html-block-id') {
|
||||
data = {
|
||||
data: '<p>Test prompt content</p>',
|
||||
data: `<problem>
|
||||
</problem>`,
|
||||
display_name: 'My Text Prompt',
|
||||
metadata: {
|
||||
display_name: 'Welcome!',
|
||||
|
||||
Reference in New Issue
Block a user