feat: add problem type select

Co-authored-by: Kristin Aoki <42981026+KristinAoki@users.noreply.github.com>
Co-authored-by: Raymond Zhou <56318341+rayzhou-bit@users.noreply.github.com>
This commit is contained in:
connorhaugh
2022-12-22 16:52:21 -05:00
committed by GitHub
parent 83cbac6270
commit 2896393c53
48 changed files with 4277 additions and 155 deletions

View File

@@ -6,27 +6,11 @@ exports[`TypeCard snapshot snapshot: renders type setting card 1`] = `
title="Type"
>
<TypeRow
key="stringresponse"
label="Text Input Problem"
lastRow={false}
selected={false}
typeKey="stringresponse"
updateField={[MockFunction args.updateField]}
/>
<TypeRow
key="numericalresponse"
label="Numeric Response Problem"
key="multiplechoiceresponse"
label="Single Select Problem"
lastRow={false}
selected={true}
typeKey="numericalresponse"
updateField={[MockFunction args.updateField]}
/>
<TypeRow
key="optionresponse"
label="Dropdown Problem"
lastRow={false}
selected={true}
typeKey="optionresponse"
typeKey="multiplechoiceresponse"
updateField={[MockFunction args.updateField]}
/>
<TypeRow
@@ -38,11 +22,35 @@ exports[`TypeCard snapshot snapshot: renders type setting card 1`] = `
updateField={[MockFunction args.updateField]}
/>
<TypeRow
key="multiplechoiceresponse"
label="Single Select Problem"
key="optionresponse"
label="Dropdown Problem"
lastRow={false}
selected={true}
typeKey="optionresponse"
updateField={[MockFunction args.updateField]}
/>
<TypeRow
key="numericalresponse"
label="Numeric Response Problem"
lastRow={false}
selected={true}
typeKey="numericalresponse"
updateField={[MockFunction args.updateField]}
/>
<TypeRow
key="stringresponse"
label="Text Input Problem"
lastRow={false}
selected={false}
typeKey="stringresponse"
updateField={[MockFunction args.updateField]}
/>
<TypeRow
key="advanced"
label="Advanced Problem"
lastRow={true}
selected={true}
typeKey="multiplechoiceresponse"
typeKey="advanced"
updateField={[MockFunction args.updateField]}
/>
</SettingsOption>

View File

@@ -10,6 +10,7 @@ import { EditorContainer } from '../../../EditorContainer';
import { selectors } from '../../../../data/redux';
import ReactStateSettingsParser from '../../data/ReactStateSettingsParser';
import ReactStateOLXParser from '../../data/ReactStateOLXParser';
import { AdvanceProblemKeys } from '../../../../data/constants/problem';
export const EditProblemView = ({
problemType,
@@ -23,6 +24,9 @@ export const EditProblemView = ({
olx: reactOLXParser.buildOLX(),
};
};
if (Object.values(AdvanceProblemKeys).includes(problemType)) {
return `hello raw editor with ${problemType}`;
}
return (
<EditorContainer getContent={parseState(problemState)}>
<Container fluid>

View File

@@ -7,33 +7,38 @@ import {
Button,
ModalDialog,
} from '@edx/paragon';
import { FormattedMessage, injectIntl } from '@edx/frontend-platform/i18n';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import messages from './messages';
import hooks from '../hooks';
import { actions } from '../../../../../data/redux';
export const SelectTypeFooter = ({
selected,
onCancel,
// Redux
onSelect,
selected,
// redux
setProblemType,
updateField,
// injected,
intl,
}) => (
<div className="editor-footer" style={{ position: 'sticky', bottom: 0 }}>
<div className="editor-footer position-sticky" style={{ bottom: 0 }}>
<ModalDialog.Footer className="border-top-0">
<ActionRow>
<ActionRow.Spacer />
<Button
aria-label="TODO: CANCEL"
aria-label={intl.formatMessage(messages.cancelButtonAriaLabel)}
variant="tertiary"
onClick={onCancel}
>
<FormattedMessage {...'TODO-CANCEL'} />
<FormattedMessage {...messages.cancelButtonLabel} />
</Button>
<Button
aria-label="TODO: SELECT"
onClick={onSelect(selected)}
aria-label={intl.formatMessage(messages.selectButtonAriaLabel)}
onClick={hooks.onSelect(setProblemType, selected, updateField)}
disabled={!selected}
>
<FormattedMessage {...'TODO- SELECT'} />
<FormattedMessage {...messages.selectButtonLabel} />
</Button>
</ActionRow>
</ModalDialog.Footer>
@@ -47,14 +52,18 @@ SelectTypeFooter.defaultProps = {
SelectTypeFooter.propTypes = {
onCancel: PropTypes.func.isRequired,
selected: PropTypes.string,
onSelect: PropTypes.func.isRequired,
setProblemType: PropTypes.func.isRequired,
updateField: PropTypes.func.isRequired,
// injected
intl: intlShape.isRequired,
};
export const mapStateToProps = () => ({
});
export const mapDispatchToProps = {
initializeEditor: actions.problem.onSelect,
setProblemType: actions.problem.setProblemType,
updateField: actions.problem.updateField,
};
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(SelectTypeFooter));

View File

@@ -0,0 +1,55 @@
import React from 'react';
import { shallow } from 'enzyme';
import { Button } from '@edx/paragon';
import { formatMessage } from '../../../../../../testUtils';
import * as module from './SelectTypeFooter';
import hooks from '../hooks';
import { actions } from '../../../../../data/redux';
jest.mock('../hooks', () => ({
onSelect: jest.fn().mockName('onSelect'),
}));
describe('SelectTypeFooter', () => {
const props = {
onCancel: jest.fn().mockName('onCancel'),
selected: null,
// redux
setProblemType: jest.fn().mockName('setProblemType'),
// inject
intl: { formatMessage },
};
test('snapshot', () => {
expect(shallow(<module.SelectTypeFooter {...props} />)).toMatchSnapshot();
});
describe('behavior', () => {
let el;
beforeEach(() => {
el = shallow(<module.SelectTypeFooter {...props} />);
});
test('close behavior is linked to modal onCancel', () => {
const expected = props.onCancel;
expect(el.find(Button).first().props().onClick)
.toEqual(expected);
});
test('select behavior is linked to modal onSelect', () => {
const expected = hooks.onSelect(props.setProblemType, props.selected);
expect(el.find(Button).last().props().onClick)
.toEqual(expected);
});
});
describe('mapStateToProps', () => {
test('is empty', () => {
expect(module.mapStateToProps()).toEqual({});
});
});
describe('mapDispatchToProps', () => {
test('loads setProblemType from problem.setProblemType actions', () => {
expect(module.mapDispatchToProps.setProblemType).toEqual(actions.problem.setProblemType);
});
});
});

View File

@@ -0,0 +1,41 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SelectTypeFooter snapshot 1`] = `
<div
className="editor-footer position-sticky"
style={
Object {
"bottom": 0,
}
}
>
<ModalDialog.Footer
className="border-top-0"
>
<ActionRow>
<ActionRow.Spacer />
<Button
aria-label="Cancel"
onClick={[MockFunction onCancel]}
variant="tertiary"
>
<FormattedMessage
defaultMessage="Cancel"
description="Label for cancel button."
id="authoring.problemeditor.selecttype.cancelButton.label"
/>
</Button>
<Button
aria-label="Select"
disabled={true}
>
<FormattedMessage
defaultMessage="Select"
description="Label for select button."
id="authoring.problemeditor.selecttype.selectButton.label"
/>
</Button>
</ActionRow>
</ModalDialog.Footer>
</div>
`;

View File

@@ -0,0 +1,29 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SelectTypeWrapper snapshot 1`] = `
<div>
<ModalDialog.Header>
<ModalDialog.Title>
<p>
Select Problem type
</p>
<div
className="pgn__modal-close-container"
>
<IconButton
iconAs="Icon"
src={[MockFunction icons.Close]}
/>
</div>
</ModalDialog.Title>
</ModalDialog.Header>
<ModalDialog.Body>
<h1>
test child
</h1>
</ModalDialog.Body>
<injectIntl(ShimmedIntlComponent)
selected="iMAsElecTedValUE"
/>
</div>
`;

View File

@@ -8,9 +8,9 @@ import SelectTypeFooter from './SelectTypeFooter';
import * as hooks from '../../../../EditorContainer/hooks';
export const SelectTypeWrapper = ({
selected,
onClose,
children,
onClose,
selected,
}) => {
const handleCancelClicked = hooks.handleCancelClicked({ onClose });
@@ -28,7 +28,9 @@ export const SelectTypeWrapper = ({
</div>
</ModalDialog.Title>
</ModalDialog.Header>
{children}
<ModalDialog.Body>
{children}
</ModalDialog.Body>
<SelectTypeFooter
selected={selected}
onCancel={handleCancelClicked}
@@ -41,7 +43,7 @@ SelectTypeWrapper.defaultProps = {
onClose: null,
};
SelectTypeWrapper.propTypes = {
selected: PropTypes.func.isRequired,
selected: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
onClose: PropTypes.func,
};

View File

@@ -0,0 +1,33 @@
import React from 'react';
import { shallow } from 'enzyme';
import { IconButton } from '@edx/paragon';
import * as module from '.';
import { handleCancelClicked } from '../../../../EditorContainer/hooks';
jest.mock('../../../../EditorContainer/hooks', () => ({
handleCancelClicked: jest.fn().mockName('handleCancelClicked'),
}));
describe('SelectTypeWrapper', () => {
const props = {
children: (<h1>test child</h1>),
onClose: jest.fn(),
selected: 'iMAsElecTedValUE',
};
test('snapshot', () => {
expect(shallow(<module.SelectTypeWrapper {...props} />)).toMatchSnapshot();
});
describe('behavior', () => {
let el;
beforeEach(() => {
el = shallow(<module.SelectTypeWrapper {...props} />);
});
test('close behavior is linked to modal onClose', () => {
const expected = handleCancelClicked({ onClose: props.onClose });
expect(el.find(IconButton).props().onClick)
.toEqual(expected);
});
});
});

View File

@@ -0,0 +1,24 @@
export const messages = {
cancelButtonLabel: {
id: 'authoring.problemeditor.selecttype.cancelButton.label',
defaultMessage: 'Cancel',
description: 'Label for cancel button.',
},
cancelButtonAriaLabel: {
id: 'authoring.problemeditor.selecttype.cancelButton.ariaLabel',
defaultMessage: 'Cancel',
description: 'Screen reader label for cancel button.',
},
selectButtonLabel: {
id: 'authoring.problemeditor.selecttype.selectButton.label',
defaultMessage: 'Select',
description: 'Label for select button.',
},
selectButtonAriaLabel: {
id: 'authoring.problemeditor.selecttype.selectButton.ariaLabel',
defaultMessage: 'Select',
description: 'Screen reader label for select button.',
},
};
export default messages;

View File

@@ -0,0 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SelectTypeModal snapshot 1`] = `
<SelectTypeWrapper
onClose={[MockFunction]}
selected="mOcKsELEcted"
>
<Row
className="justify-content-center align-items-center m-4"
>
<Component>
<injectIntl(ShimmedIntlComponent)
selected="mOcKsELEcted"
setSelected={[MockFunction setSelected]}
/>
</Component>
<Component>
<injectIntl(ShimmedIntlComponent)
problemType="mOcKsELEcted"
/>
</Component>
</Row>
</SelectTypeWrapper>
`;

View File

@@ -0,0 +1,92 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
Form,
ActionRow,
IconButton,
Icon,
OverlayTrigger,
Tooltip,
} from '@edx/paragon';
import { ArrowBack } from '@edx/paragon/icons';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { AdvanceProblems, ProblemTypeKeys } from '../../../../../data/constants/problem';
import messages from './messages';
export const AdvanceTypeSelect = ({
selected,
setSelected,
// injected
intl,
}) => {
const handleChange = e => { setSelected(e.target.value); };
return (
<div className="col col-8 border rounded p-0 justify-content-center">
<Form.Group className="p-0">
<ActionRow className="border-primary-100 border-bottom py-3 pl-2.5 pr-4">
<IconButton src={ArrowBack} iconAs={Icon} onClick={() => setSelected(ProblemTypeKeys.SINGLESELECT)} />
<ActionRow.Spacer />
<Form.Label className="h4">
<FormattedMessage {...messages.advanceMenuTitle} />
</Form.Label>
<ActionRow.Spacer />
</ActionRow>
<Form.RadioSet
name="advanceTypes"
onChange={handleChange}
value={selected}
className="px-4"
>
{Object.entries(AdvanceProblems).map(([type, data]) => {
if (data.status !== '') {
return (
<ActionRow className="border-primary-100 border-bottom m-0 py-3 w-100">
<Form.Radio id={type} value={type}>
{intl.formatMessage(messages.advanceProblemTypeLabel, { problemType: data.title })}
</Form.Radio>
<ActionRow.Spacer />
<OverlayTrigger
placement="right"
overlay={(
<Tooltip>
<div className="text-gray-300 text-left">
{intl.formatMessage(messages.supportStatusTooltipMessage, { supportStatus: data.status.replace(' ', '_') })}
</div>
</Tooltip>
)}
>
<div>
{intl.formatMessage(messages.problemSupportStatus, { supportStatus: data.status })}
</div>
</OverlayTrigger>
</ActionRow>
);
}
return (
<ActionRow className="border-primary-100 border-bottom m-0 py-3 w-100">
<Form.Radio id={type} value={type}>
{intl.formatMessage(messages.advanceProblemTypeLabel, { problemType: data.title })}
</Form.Radio>
<ActionRow.Spacer />
</ActionRow>
);
})}
</Form.RadioSet>
</Form.Group>
</div>
);
};
AdvanceTypeSelect.defaultProps = {
selected: null,
};
AdvanceTypeSelect.propTypes = {
selected: PropTypes.string,
setSelected: PropTypes.func.isRequired,
// injected
intl: intlShape.isRequired,
};
export default injectIntl(AdvanceTypeSelect);

View File

@@ -0,0 +1,55 @@
import React from 'react';
import { shallow } from 'enzyme';
import { formatMessage } from '../../../../../../testUtils';
import * as module from './AdvanceTypeSelect';
describe('AdvanceTypeSelect', () => {
const props = {
intl: { formatMessage },
selected: 'blankadvanced',
setSelected: jest.fn().mockName('setSelect'),
};
describe('snapshots', () => {
test('snapshots: renders as expected with default props', () => {
expect(
shallow(<module.AdvanceTypeSelect {...props} />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is circuitschematic', () => {
expect(
shallow(<module.AdvanceTypeSelect {...props} selected="circuitschematic" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is customgrader', () => {
expect(
shallow(<module.AdvanceTypeSelect {...props} selected="customgrader" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is drag_and_drop', () => {
expect(
shallow(<module.AdvanceTypeSelect {...props} selected="drag_and_drop" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is formularesponse', () => {
expect(
shallow(<module.AdvanceTypeSelect {...props} selected="formularesponse" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is imageresponse', () => {
expect(
shallow(<module.AdvanceTypeSelect {...props} selected="imageresponse" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is jsinput_response', () => {
expect(
shallow(<module.AdvanceTypeSelect {...props} selected="jsinput_response" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is problem_with_hint', () => {
expect(
shallow(<module.AdvanceTypeSelect {...props} selected="problem_with_hint" />),
).toMatchSnapshot();
});
});
});

View File

@@ -1,28 +1,43 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Hyperlink, Image } from '@edx/paragon';
import {
FormattedMessage,
injectIntl,
intlShape,
} from '@edx/frontend-platform/i18n';
import messages from './messages';
import { ProblemTypes } from '../../../../../data/constants/problem';
const Preview = ({
export const Preview = ({
problemType,
// injected
intl,
}) => {
if (problemType === null) {
return null;
}
const data = ProblemTypes[problemType];
return (
<div>
<div>
<p>{data.title}</p>
<div className="bg-light-300 rounded p-4">
<div className="small">
{intl.formatMessage(messages.previewTitle, { previewTitle: data.title })}
</div>
<div>
{data.preview}
</div>
<div>
<p>{data.description}</p>
</div>
<div>
<p>{data.helpLink}</p>
<Image
fluid
className="my-3"
src={data.preview}
alt={intl.formatMessage(messages.previewAltText, { problemType })}
/>
<div className="mb-3">
{intl.formatMessage(messages.previewDescription, { previewDescription: data.description })}
</div>
<Hyperlink
destination={data.helpLink}
target="_blank"
>
<FormattedMessage {...messages.learnMoreButtonLabel} />
</Hyperlink>
</div>
);
};
@@ -30,8 +45,11 @@ const Preview = ({
Preview.defaultProps = {
problemType: null,
};
Preview.propTypes = {
problemType: PropTypes.string,
// injected
intl: intlShape.isRequired,
};
export default Preview;
export default injectIntl(Preview);

View File

@@ -0,0 +1,44 @@
import React from 'react';
import { shallow } from 'enzyme';
import { formatMessage } from '../../../../../../testUtils';
import * as module from './Preview';
describe('Preview', () => {
const props = {
intl: { formatMessage },
problemType: null,
};
describe('snapshots', () => {
test('snapshots: renders as expected with default props', () => {
expect(
shallow(<module.Preview {...props} />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is stringresponse', () => {
expect(
shallow(<module.Preview {...props} problemType="stringresponse" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is numericalresponse', () => {
expect(
shallow(<module.Preview {...props} problemType="numericalresponse" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is optionresponse', () => {
expect(
shallow(<module.Preview {...props} problemType="optionresponse" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is choiceresponse', () => {
expect(
shallow(<module.Preview {...props} problemType="choiceresponse" />),
).toMatchSnapshot();
});
test('snapshots: renders as expected with problemType is multiplechoiceresponse', () => {
expect(
shallow(<module.Preview {...props} problemType="multiplechoiceresponse" />),
).toMatchSnapshot();
});
});
});

View File

@@ -1,31 +1,45 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Form } from '@edx/paragon';
import { ProblemTypes } from '../../../../../data/constants/problem';
import { Button, SelectableBox } from '@edx/paragon';
import { FormattedMessage, injectIntl } from '@edx/frontend-platform/i18n';
import { ProblemTypes, ProblemTypeKeys, AdvanceProblemKeys } from '../../../../../data/constants/problem';
import messages from './messages';
// TODO: problemtype
const ProblemTypeSelect = ({
// redux
export const ProblemTypeSelect = ({
selected,
setSelected,
}) => {
const handleChange = e => setSelected(e.target.value);
const handleClick = () => setSelected(AdvanceProblemKeys.BLANK);
const settings = { 'aria-label': 'checkbox', type: 'radio' };
return (
<Form.Group>
<Form.RadioSet
name="problemtype"
<>
<SelectableBox.Set
columns={1}
onChange={handleChange}
type={settings.type}
value={selected}
>
<Form.Radio value={ProblemTypes.SINGLESELECT}>{ProblemTypes.SINGLESELECT.title}</Form.Radio>
<Form.Radio value={ProblemTypes.MULTISELECT}>{ProblemTypes.MULTISELECT.title}</Form.Radio>
<Form.Radio value={ProblemTypes.DROPDOWN}>{ProblemTypes.DROPDOWN.title}</Form.Radio>
<Form.Radio value={ProblemTypes.NUMERIC}>{ProblemTypes.NUMERIC.title}</Form.Radio>
<Form.Radio value={ProblemTypes.TEXTINPUT}>{ProblemTypes.TEXTINPUT.title}</Form.Radio>
</Form.RadioSet>
</Form.Group>
{Object.values(ProblemTypeKeys).map((key) => (
key !== 'advanced'
? (
<SelectableBox id={key} value={key} {...settings}>
{ProblemTypes[key].title}
</SelectableBox>
)
: null
))}
</SelectableBox.Set>
<Button variant="link" className="pl-0 mt-2" onClick={handleClick}>
<FormattedMessage {...messages.advanceProblemButtonLabel} />
</Button>
</>
);
};
ProblemTypeSelect.propTypes = {
selected: PropTypes.string.isRequired,
setSelected: PropTypes.func.isRequired,
};
export default ProblemTypeSelect;
export default injectIntl(ProblemTypeSelect);

View File

@@ -0,0 +1,39 @@
import React from 'react';
import { shallow } from 'enzyme';
import { ProblemTypeKeys } from '../../../../../data/constants/problem';
import * as module from './ProblemTypeSelect';
describe('ProblemTypeSelect', () => {
const props = {
selected: null,
setSelected: jest.fn(),
};
describe('snapshot', () => {
test('SINGLESELECT', () => {
expect(shallow(
<module.ProblemTypeSelect {...props} selected={ProblemTypeKeys.SINGLESELECT} />,
)).toMatchSnapshot();
});
test('MULTISELECT', () => {
expect(shallow(
<module.ProblemTypeSelect {...props} selected={ProblemTypeKeys.MULTISELECT} />,
)).toMatchSnapshot();
});
test('DROPDOWN', () => {
expect(shallow(
<module.ProblemTypeSelect {...props} selected={ProblemTypeKeys.DROPDOWN} />,
)).toMatchSnapshot();
});
test('NUMERIC', () => {
expect(shallow(
<module.ProblemTypeSelect {...props} selected={ProblemTypeKeys.NUMERIC} />,
)).toMatchSnapshot();
});
test('TEXTINPUT', () => {
expect(shallow(
<module.ProblemTypeSelect {...props} selected={ProblemTypeKeys.TEXTINPUT} />,
)).toMatchSnapshot();
});
});
});

View File

@@ -0,0 +1,2241 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AdvanceTypeSelect snapshots snapshots: renders as expected with default props 1`] = `
<div
className="col col-8 border rounded p-0 justify-content-center"
>
<Form.Group
className="p-0"
>
<ActionRow
className="border-primary-100 border-bottom py-3 pl-2.5 pr-4"
>
<IconButton
iconAs="Icon"
onClick={[Function]}
/>
<ActionRow.Spacer />
<Form.Label
className="h4"
>
<FormattedMessage
defaultMessage="Advanced problems"
description="Title for advanced problem menu"
id="authoring.problemEditor.advanceProblem.menu.title"
/>
</Form.Label>
<ActionRow.Spacer />
</ActionRow>
<RadioSet
className="px-4"
name="advanceTypes"
onChange={[Function]}
value="blankadvanced"
>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="blankadvanced"
value="blankadvanced"
>
Blank advance problem
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="circuitschematic"
value="circuitschematic"
>
Circuit schematic builder
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="jsinputresponse"
value="jsinputresponse"
>
Custom JavaScript display and grading
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="customgrader"
value="customgrader"
>
Custom Python-evaluated input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Provisional
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="draganddrop"
value="draganddrop"
>
Drag and drop (deprecated version)
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="imageresponse"
value="imageresponse"
>
Image mapped input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="formularesponse"
value="formularesponse"
>
Math expression input
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="problemwithhint"
value="problemwithhint"
>
Problem with adaptive hint
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
</RadioSet>
</Form.Group>
</div>
`;
exports[`AdvanceTypeSelect snapshots snapshots: renders as expected with problemType is circuitschematic 1`] = `
<div
className="col col-8 border rounded p-0 justify-content-center"
>
<Form.Group
className="p-0"
>
<ActionRow
className="border-primary-100 border-bottom py-3 pl-2.5 pr-4"
>
<IconButton
iconAs="Icon"
onClick={[Function]}
/>
<ActionRow.Spacer />
<Form.Label
className="h4"
>
<FormattedMessage
defaultMessage="Advanced problems"
description="Title for advanced problem menu"
id="authoring.problemEditor.advanceProblem.menu.title"
/>
</Form.Label>
<ActionRow.Spacer />
</ActionRow>
<RadioSet
className="px-4"
name="advanceTypes"
onChange={[Function]}
value="circuitschematic"
>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="blankadvanced"
value="blankadvanced"
>
Blank advance problem
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="circuitschematic"
value="circuitschematic"
>
Circuit schematic builder
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="jsinputresponse"
value="jsinputresponse"
>
Custom JavaScript display and grading
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="customgrader"
value="customgrader"
>
Custom Python-evaluated input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Provisional
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="draganddrop"
value="draganddrop"
>
Drag and drop (deprecated version)
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="imageresponse"
value="imageresponse"
>
Image mapped input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="formularesponse"
value="formularesponse"
>
Math expression input
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="problemwithhint"
value="problemwithhint"
>
Problem with adaptive hint
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
</RadioSet>
</Form.Group>
</div>
`;
exports[`AdvanceTypeSelect snapshots snapshots: renders as expected with problemType is customgrader 1`] = `
<div
className="col col-8 border rounded p-0 justify-content-center"
>
<Form.Group
className="p-0"
>
<ActionRow
className="border-primary-100 border-bottom py-3 pl-2.5 pr-4"
>
<IconButton
iconAs="Icon"
onClick={[Function]}
/>
<ActionRow.Spacer />
<Form.Label
className="h4"
>
<FormattedMessage
defaultMessage="Advanced problems"
description="Title for advanced problem menu"
id="authoring.problemEditor.advanceProblem.menu.title"
/>
</Form.Label>
<ActionRow.Spacer />
</ActionRow>
<RadioSet
className="px-4"
name="advanceTypes"
onChange={[Function]}
value="customgrader"
>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="blankadvanced"
value="blankadvanced"
>
Blank advance problem
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="circuitschematic"
value="circuitschematic"
>
Circuit schematic builder
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="jsinputresponse"
value="jsinputresponse"
>
Custom JavaScript display and grading
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="customgrader"
value="customgrader"
>
Custom Python-evaluated input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Provisional
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="draganddrop"
value="draganddrop"
>
Drag and drop (deprecated version)
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="imageresponse"
value="imageresponse"
>
Image mapped input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="formularesponse"
value="formularesponse"
>
Math expression input
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="problemwithhint"
value="problemwithhint"
>
Problem with adaptive hint
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
</RadioSet>
</Form.Group>
</div>
`;
exports[`AdvanceTypeSelect snapshots snapshots: renders as expected with problemType is drag_and_drop 1`] = `
<div
className="col col-8 border rounded p-0 justify-content-center"
>
<Form.Group
className="p-0"
>
<ActionRow
className="border-primary-100 border-bottom py-3 pl-2.5 pr-4"
>
<IconButton
iconAs="Icon"
onClick={[Function]}
/>
<ActionRow.Spacer />
<Form.Label
className="h4"
>
<FormattedMessage
defaultMessage="Advanced problems"
description="Title for advanced problem menu"
id="authoring.problemEditor.advanceProblem.menu.title"
/>
</Form.Label>
<ActionRow.Spacer />
</ActionRow>
<RadioSet
className="px-4"
name="advanceTypes"
onChange={[Function]}
value="drag_and_drop"
>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="blankadvanced"
value="blankadvanced"
>
Blank advance problem
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="circuitschematic"
value="circuitschematic"
>
Circuit schematic builder
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="jsinputresponse"
value="jsinputresponse"
>
Custom JavaScript display and grading
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="customgrader"
value="customgrader"
>
Custom Python-evaluated input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Provisional
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="draganddrop"
value="draganddrop"
>
Drag and drop (deprecated version)
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="imageresponse"
value="imageresponse"
>
Image mapped input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="formularesponse"
value="formularesponse"
>
Math expression input
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="problemwithhint"
value="problemwithhint"
>
Problem with adaptive hint
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
</RadioSet>
</Form.Group>
</div>
`;
exports[`AdvanceTypeSelect snapshots snapshots: renders as expected with problemType is formularesponse 1`] = `
<div
className="col col-8 border rounded p-0 justify-content-center"
>
<Form.Group
className="p-0"
>
<ActionRow
className="border-primary-100 border-bottom py-3 pl-2.5 pr-4"
>
<IconButton
iconAs="Icon"
onClick={[Function]}
/>
<ActionRow.Spacer />
<Form.Label
className="h4"
>
<FormattedMessage
defaultMessage="Advanced problems"
description="Title for advanced problem menu"
id="authoring.problemEditor.advanceProblem.menu.title"
/>
</Form.Label>
<ActionRow.Spacer />
</ActionRow>
<RadioSet
className="px-4"
name="advanceTypes"
onChange={[Function]}
value="formularesponse"
>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="blankadvanced"
value="blankadvanced"
>
Blank advance problem
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="circuitschematic"
value="circuitschematic"
>
Circuit schematic builder
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="jsinputresponse"
value="jsinputresponse"
>
Custom JavaScript display and grading
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="customgrader"
value="customgrader"
>
Custom Python-evaluated input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Provisional
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="draganddrop"
value="draganddrop"
>
Drag and drop (deprecated version)
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="imageresponse"
value="imageresponse"
>
Image mapped input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="formularesponse"
value="formularesponse"
>
Math expression input
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="problemwithhint"
value="problemwithhint"
>
Problem with adaptive hint
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
</RadioSet>
</Form.Group>
</div>
`;
exports[`AdvanceTypeSelect snapshots snapshots: renders as expected with problemType is imageresponse 1`] = `
<div
className="col col-8 border rounded p-0 justify-content-center"
>
<Form.Group
className="p-0"
>
<ActionRow
className="border-primary-100 border-bottom py-3 pl-2.5 pr-4"
>
<IconButton
iconAs="Icon"
onClick={[Function]}
/>
<ActionRow.Spacer />
<Form.Label
className="h4"
>
<FormattedMessage
defaultMessage="Advanced problems"
description="Title for advanced problem menu"
id="authoring.problemEditor.advanceProblem.menu.title"
/>
</Form.Label>
<ActionRow.Spacer />
</ActionRow>
<RadioSet
className="px-4"
name="advanceTypes"
onChange={[Function]}
value="imageresponse"
>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="blankadvanced"
value="blankadvanced"
>
Blank advance problem
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="circuitschematic"
value="circuitschematic"
>
Circuit schematic builder
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="jsinputresponse"
value="jsinputresponse"
>
Custom JavaScript display and grading
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="customgrader"
value="customgrader"
>
Custom Python-evaluated input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Provisional
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="draganddrop"
value="draganddrop"
>
Drag and drop (deprecated version)
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="imageresponse"
value="imageresponse"
>
Image mapped input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="formularesponse"
value="formularesponse"
>
Math expression input
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="problemwithhint"
value="problemwithhint"
>
Problem with adaptive hint
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
</RadioSet>
</Form.Group>
</div>
`;
exports[`AdvanceTypeSelect snapshots snapshots: renders as expected with problemType is jsinput_response 1`] = `
<div
className="col col-8 border rounded p-0 justify-content-center"
>
<Form.Group
className="p-0"
>
<ActionRow
className="border-primary-100 border-bottom py-3 pl-2.5 pr-4"
>
<IconButton
iconAs="Icon"
onClick={[Function]}
/>
<ActionRow.Spacer />
<Form.Label
className="h4"
>
<FormattedMessage
defaultMessage="Advanced problems"
description="Title for advanced problem menu"
id="authoring.problemEditor.advanceProblem.menu.title"
/>
</Form.Label>
<ActionRow.Spacer />
</ActionRow>
<RadioSet
className="px-4"
name="advanceTypes"
onChange={[Function]}
value="jsinput_response"
>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="blankadvanced"
value="blankadvanced"
>
Blank advance problem
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="circuitschematic"
value="circuitschematic"
>
Circuit schematic builder
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="jsinputresponse"
value="jsinputresponse"
>
Custom JavaScript display and grading
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="customgrader"
value="customgrader"
>
Custom Python-evaluated input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Provisional
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="draganddrop"
value="draganddrop"
>
Drag and drop (deprecated version)
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="imageresponse"
value="imageresponse"
>
Image mapped input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="formularesponse"
value="formularesponse"
>
Math expression input
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="problemwithhint"
value="problemwithhint"
>
Problem with adaptive hint
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
</RadioSet>
</Form.Group>
</div>
`;
exports[`AdvanceTypeSelect snapshots snapshots: renders as expected with problemType is problem_with_hint 1`] = `
<div
className="col col-8 border rounded p-0 justify-content-center"
>
<Form.Group
className="p-0"
>
<ActionRow
className="border-primary-100 border-bottom py-3 pl-2.5 pr-4"
>
<IconButton
iconAs="Icon"
onClick={[Function]}
/>
<ActionRow.Spacer />
<Form.Label
className="h4"
>
<FormattedMessage
defaultMessage="Advanced problems"
description="Title for advanced problem menu"
id="authoring.problemEditor.advanceProblem.menu.title"
/>
</Form.Label>
<ActionRow.Spacer />
</ActionRow>
<RadioSet
className="px-4"
name="advanceTypes"
onChange={[Function]}
value="problem_with_hint"
>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="blankadvanced"
value="blankadvanced"
>
Blank advance problem
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="circuitschematic"
value="circuitschematic"
>
Circuit schematic builder
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="jsinputresponse"
value="jsinputresponse"
>
Custom JavaScript display and grading
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="customgrader"
value="customgrader"
>
Custom Python-evaluated input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Provisional
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="draganddrop"
value="draganddrop"
>
Drag and drop (deprecated version)
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="imageresponse"
value="imageresponse"
>
Image mapped input
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="formularesponse"
value="formularesponse"
>
Math expression input
</Radio>
<ActionRow.Spacer />
</ActionRow>
<ActionRow
className="border-primary-100 border-bottom m-0 py-3 w-100"
>
<Radio
id="problemwithhint"
value="problemwithhint"
>
Problem with adaptive hint
</Radio>
<ActionRow.Spacer />
<OverlayTrigger
overlay={
<Tooltip>
<div
className="text-gray-300 text-left"
>
{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}
</div>
</Tooltip>
}
placement="right"
>
<div>
Not supported
</div>
</OverlayTrigger>
</ActionRow>
</RadioSet>
</Form.Group>
</div>
`;

View File

@@ -0,0 +1,203 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Preview snapshots snapshots: renders as expected with default props 1`] = `""`;
exports[`Preview snapshots snapshots: renders as expected with problemType is choiceresponse 1`] = `
<div
className="bg-light-300 rounded p-4"
>
<div
className="small"
>
Multi Select Problem
</div>
<Image
alt="A preview illustration of a {problemType, select,
multiplechoiceresponse {single select}
stringreponse {text input}
numericalresponse {numerical input}
optionresponse {dropdown}
choiceresponse {multiple select}
other {null}
} problem"
className="my-3"
fluid={true}
src="test-file-stub"
/>
<div
className="mb-3"
>
Specify one or more correct answers from a list of possible options.
</div>
<Hyperlink
destination="https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/checkbox.html"
target="_blank"
>
<FormattedMessage
defaultMessage="Learn More"
description="Label for Learn More button"
id="authoring.problemEditor.learnMoreButtonLabel.label"
/>
</Hyperlink>
</div>
`;
exports[`Preview snapshots snapshots: renders as expected with problemType is multiplechoiceresponse 1`] = `
<div
className="bg-light-300 rounded p-4"
>
<div
className="small"
>
Single Select Problem
</div>
<Image
alt="A preview illustration of a {problemType, select,
multiplechoiceresponse {single select}
stringreponse {text input}
numericalresponse {numerical input}
optionresponse {dropdown}
choiceresponse {multiple select}
other {null}
} problem"
className="my-3"
fluid={true}
src="test-file-stub"
/>
<div
className="mb-3"
>
Specify one correct answer from a list of possible options
</div>
<Hyperlink
destination="https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/multiple_choice.html"
target="_blank"
>
<FormattedMessage
defaultMessage="Learn More"
description="Label for Learn More button"
id="authoring.problemEditor.learnMoreButtonLabel.label"
/>
</Hyperlink>
</div>
`;
exports[`Preview snapshots snapshots: renders as expected with problemType is numericalresponse 1`] = `
<div
className="bg-light-300 rounded p-4"
>
<div
className="small"
>
Numeric Response Problem
</div>
<Image
alt="A preview illustration of a {problemType, select,
multiplechoiceresponse {single select}
stringreponse {text input}
numericalresponse {numerical input}
optionresponse {dropdown}
choiceresponse {multiple select}
other {null}
} problem"
className="my-3"
fluid={true}
src="test-file-stub"
/>
<div
className="mb-3"
>
Specify one or more correct numeric answers, submitted in a response field.
</div>
<Hyperlink
destination="https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/numerical_input.html"
target="_blank"
>
<FormattedMessage
defaultMessage="Learn More"
description="Label for Learn More button"
id="authoring.problemEditor.learnMoreButtonLabel.label"
/>
</Hyperlink>
</div>
`;
exports[`Preview snapshots snapshots: renders as expected with problemType is optionresponse 1`] = `
<div
className="bg-light-300 rounded p-4"
>
<div
className="small"
>
Dropdown Problem
</div>
<Image
alt="A preview illustration of a {problemType, select,
multiplechoiceresponse {single select}
stringreponse {text input}
numericalresponse {numerical input}
optionresponse {dropdown}
choiceresponse {multiple select}
other {null}
} problem"
className="my-3"
fluid={true}
src="test-file-stub"
/>
<div
className="mb-3"
>
Specify one correct answer from a list of possible options, selected in a dropdown menu.
</div>
<Hyperlink
destination="https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/dropdown.html"
target="_blank"
>
<FormattedMessage
defaultMessage="Learn More"
description="Label for Learn More button"
id="authoring.problemEditor.learnMoreButtonLabel.label"
/>
</Hyperlink>
</div>
`;
exports[`Preview snapshots snapshots: renders as expected with problemType is stringresponse 1`] = `
<div
className="bg-light-300 rounded p-4"
>
<div
className="small"
>
Text Input Problem
</div>
<Image
alt="A preview illustration of a {problemType, select,
multiplechoiceresponse {single select}
stringreponse {text input}
numericalresponse {numerical input}
optionresponse {dropdown}
choiceresponse {multiple select}
other {null}
} problem"
className="my-3"
fluid={true}
src="test-file-stub"
/>
<div
className="mb-3"
>
Specify one or more correct text answers, including numbers and special characters, submitted in a response field.
</div>
<Hyperlink
destination="https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/text_input.html"
target="_blank"
>
<FormattedMessage
defaultMessage="Learn More"
description="Label for Learn More button"
id="authoring.problemEditor.learnMoreButtonLabel.label"
/>
</Hyperlink>
</div>
`;

View File

@@ -0,0 +1,316 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ProblemTypeSelect snapshot DROPDOWN 1`] = `
<Fragment>
<SelectableBox.Set
columns={1}
onChange={[Function]}
type="radio"
value="optionresponse"
>
<SelectableBox
aria-label="checkbox"
id="multiplechoiceresponse"
type="radio"
value="multiplechoiceresponse"
>
Single Select Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="choiceresponse"
type="radio"
value="choiceresponse"
>
Multi Select Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="optionresponse"
type="radio"
value="optionresponse"
>
Dropdown Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="numericalresponse"
type="radio"
value="numericalresponse"
>
Numeric Response Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="stringresponse"
type="radio"
value="stringresponse"
>
Text Input Problem
</SelectableBox>
</SelectableBox.Set>
<Button
className="pl-0 mt-2"
onClick={[Function]}
variant="link"
>
<FormattedMessage
defaultMessage="Advance problem types"
description="Button label for advance problem types option"
id="authoring.problemEditor.problemSelect.advanceButton.label"
/>
</Button>
</Fragment>
`;
exports[`ProblemTypeSelect snapshot MULTISELECT 1`] = `
<Fragment>
<SelectableBox.Set
columns={1}
onChange={[Function]}
type="radio"
value="choiceresponse"
>
<SelectableBox
aria-label="checkbox"
id="multiplechoiceresponse"
type="radio"
value="multiplechoiceresponse"
>
Single Select Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="choiceresponse"
type="radio"
value="choiceresponse"
>
Multi Select Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="optionresponse"
type="radio"
value="optionresponse"
>
Dropdown Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="numericalresponse"
type="radio"
value="numericalresponse"
>
Numeric Response Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="stringresponse"
type="radio"
value="stringresponse"
>
Text Input Problem
</SelectableBox>
</SelectableBox.Set>
<Button
className="pl-0 mt-2"
onClick={[Function]}
variant="link"
>
<FormattedMessage
defaultMessage="Advance problem types"
description="Button label for advance problem types option"
id="authoring.problemEditor.problemSelect.advanceButton.label"
/>
</Button>
</Fragment>
`;
exports[`ProblemTypeSelect snapshot NUMERIC 1`] = `
<Fragment>
<SelectableBox.Set
columns={1}
onChange={[Function]}
type="radio"
value="numericalresponse"
>
<SelectableBox
aria-label="checkbox"
id="multiplechoiceresponse"
type="radio"
value="multiplechoiceresponse"
>
Single Select Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="choiceresponse"
type="radio"
value="choiceresponse"
>
Multi Select Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="optionresponse"
type="radio"
value="optionresponse"
>
Dropdown Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="numericalresponse"
type="radio"
value="numericalresponse"
>
Numeric Response Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="stringresponse"
type="radio"
value="stringresponse"
>
Text Input Problem
</SelectableBox>
</SelectableBox.Set>
<Button
className="pl-0 mt-2"
onClick={[Function]}
variant="link"
>
<FormattedMessage
defaultMessage="Advance problem types"
description="Button label for advance problem types option"
id="authoring.problemEditor.problemSelect.advanceButton.label"
/>
</Button>
</Fragment>
`;
exports[`ProblemTypeSelect snapshot SINGLESELECT 1`] = `
<Fragment>
<SelectableBox.Set
columns={1}
onChange={[Function]}
type="radio"
value="multiplechoiceresponse"
>
<SelectableBox
aria-label="checkbox"
id="multiplechoiceresponse"
type="radio"
value="multiplechoiceresponse"
>
Single Select Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="choiceresponse"
type="radio"
value="choiceresponse"
>
Multi Select Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="optionresponse"
type="radio"
value="optionresponse"
>
Dropdown Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="numericalresponse"
type="radio"
value="numericalresponse"
>
Numeric Response Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="stringresponse"
type="radio"
value="stringresponse"
>
Text Input Problem
</SelectableBox>
</SelectableBox.Set>
<Button
className="pl-0 mt-2"
onClick={[Function]}
variant="link"
>
<FormattedMessage
defaultMessage="Advance problem types"
description="Button label for advance problem types option"
id="authoring.problemEditor.problemSelect.advanceButton.label"
/>
</Button>
</Fragment>
`;
exports[`ProblemTypeSelect snapshot TEXTINPUT 1`] = `
<Fragment>
<SelectableBox.Set
columns={1}
onChange={[Function]}
type="radio"
value="stringresponse"
>
<SelectableBox
aria-label="checkbox"
id="multiplechoiceresponse"
type="radio"
value="multiplechoiceresponse"
>
Single Select Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="choiceresponse"
type="radio"
value="choiceresponse"
>
Multi Select Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="optionresponse"
type="radio"
value="optionresponse"
>
Dropdown Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="numericalresponse"
type="radio"
value="numericalresponse"
>
Numeric Response Problem
</SelectableBox>
<SelectableBox
aria-label="checkbox"
id="stringresponse"
type="radio"
value="stringresponse"
>
Text Input Problem
</SelectableBox>
</SelectableBox.Set>
<Button
className="pl-0 mt-2"
onClick={[Function]}
variant="link"
>
<FormattedMessage
defaultMessage="Advance problem types"
description="Button label for advance problem types option"
id="authoring.problemEditor.problemSelect.advanceButton.label"
/>
</Button>
</Fragment>
`;

View File

@@ -0,0 +1,69 @@
export const messages = {
advanceProblemButtonLabel: {
id: 'authoring.problemEditor.problemSelect.advanceButton.label',
defaultMessage: 'Advance problem types',
description: 'Button label for advance problem types option',
},
advanceMenuTitle: {
id: 'authoring.problemEditor.advanceProblem.menu.title',
defaultMessage: 'Advanced problems',
description: 'Title for advanced problem menu',
},
advanceProblemTypeLabel: {
id: 'authoring.problemEditor.advanceProblem.problemType.label',
defaultMessage: '{problemType}',
description: 'Label for advance problem type radio select',
},
problemSupportStatus: {
id: 'authoring.problemEditor.advanceProblem.supportStatus',
defaultMessage: '{supportStatus}',
description: 'Text for advance problem type\'s support status',
},
supportStatusTooltipMessage: {
id: 'authoring.problemEditor.advanceProblem.supportStatus.tooltipMessage',
defaultMessage: `{supportStatus, select,
Provisional {Provisionally supported tools might lack the robustness of functionality
that your courses require. edX does not have control over the quality of the software,
or of the content that can be provided using these tools.
\n \n
Test these tools thoroughly before using them in your course, especially in graded
sections. Complete documentstion might not be available for provisionally supported
tools, or documentation might be available from sources other than edX.}
Not_supported {Tools with no support are not maintained by edX, and might be deprecated
in the future. They are not recommened for use in courses due to non-compliance with one
or more of the base requirements, such as testing, accessibility, internationalization,
and documentation.}
other { }
}`,
description: 'Message for support status tooltip',
},
previewTitle: {
id: 'authoring.problemEditor.preview.title',
defaultMessage: '{previewTitle}',
description: 'Title for the problem preview column',
},
previewAltText: {
id: 'authoring.problemEditor.preview.altText',
defaultMessage: `A preview illustration of a {problemType, select,
multiplechoiceresponse {single select}
stringreponse {text input}
numericalresponse {numerical input}
optionresponse {dropdown}
choiceresponse {multiple select}
other {null}
} problem`,
description: 'Alt text for the illustration of the problem preview',
},
previewDescription: {
id: 'authoring.problemEditor.preview.description',
defaultMessage: '{previewDescription}',
description: 'Description of the selected problem type',
},
learnMoreButtonLabel: {
id: 'authoring.problemEditor.learnMoreButtonLabel.label',
defaultMessage: 'Learn More',
description: 'Label for Learn More button',
},
};
export default messages;

View File

@@ -1,10 +1,59 @@
import { useEffect, useState } from 'react';
import {
useState,
} from 'react';
AdvanceProblemKeys, AdvanceProblems, ProblemTypeKeys, ProblemTypes,
} from '../../../../data/constants/problem';
import { StrictDict } from '../../../../utils';
import * as module from './hooks';
export const state = StrictDict({
selected: (val) => useState(val),
});
export default { state };
export const selectHooks = () => {
const [selected, setSelected] = module.state.selected(ProblemTypeKeys.SINGLESELECT);
return {
selected,
setSelected,
};
};
export const onSelect = (setProblemType, selected, updateField) => () => {
if (Object.values(AdvanceProblemKeys).includes(selected)) {
updateField({ rawOLX: AdvanceProblems[selected].template });
}
setProblemType({ selected });
};
export const useArrowNav = (selected, setSelected) => {
const detectKeyDown = (e) => {
const problemTypeValues = Object.values(ProblemTypeKeys);
switch (e.key) {
case 'ArrowUp':
if (problemTypeValues.includes(selected) && ProblemTypes[selected].prev) {
setSelected(ProblemTypes[selected].prev);
document.getElementById(ProblemTypes[selected].prev).focus();
}
break;
case 'ArrowDown':
if (problemTypeValues.includes(selected) && ProblemTypes[selected].next) {
setSelected(ProblemTypes[selected].next);
document.getElementById(ProblemTypes[selected].next).focus();
}
break;
default:
}
};
useEffect(() => {
document.addEventListener('keydown', detectKeyDown, true);
return () => {
document.removeEventListener('keydown', detectKeyDown, true);
};
}, [selected, setSelected]);
};
export default {
state,
selectHooks,
onSelect,
useArrowNav,
};

View File

@@ -0,0 +1,168 @@
/* eslint-disable prefer-destructuring */
import React from 'react';
import { MockUseState } from '../../../../../testUtils';
import * as module from './hooks';
import { AdvanceProblems, ProblemTypeKeys } from '../../../../data/constants/problem';
jest.mock('react', () => ({
...jest.requireActual('react'),
useState: (val) => ({ useState: val }),
useEffect: jest.fn(),
}));
const state = new MockUseState(module);
const mockSetProblemType = jest.fn().mockName('setProblemType');
const mockUpdateField = jest.fn().mockName('updateField');
const mockSelected = 'vAl';
const mockAdvancedSelected = 'blankadvanced';
const mockSetSelected = jest.fn().mockName('setSelected');
let hook;
describe('SelectTypeModal hooks', () => {
beforeEach(() => {
state.mock();
});
afterEach(() => {
state.restore();
jest.clearAllMocks();
});
describe('selectHooks', () => {
beforeEach(() => {
hook = module.selectHooks();
});
test('selected defaults to SINGLESELECT', () => {
expect(hook.selected).toEqual(ProblemTypeKeys.SINGLESELECT);
});
test('setSelected sets state as expected', () => {
const expectedArg = 'neWvAl';
state.mockVal(state.keys.selected, 'mOcKvAl');
hook.setSelected(expectedArg);
expect(state.setState.selected).toHaveBeenCalledWith(expectedArg);
});
});
describe('onSelect', () => {
test('updateField is called with selected templated if selected is an Advanced Problem', () => {
module.onSelect(mockSetProblemType, mockAdvancedSelected, mockUpdateField)();
expect(mockUpdateField).toHaveBeenCalledWith({
rawOLX: AdvanceProblems[mockAdvancedSelected].template,
});
});
test('setProblemType is called with selected', () => {
module.onSelect(mockSetProblemType, mockSelected, mockUpdateField)();
expect(mockSetProblemType).toHaveBeenCalledWith({ selected: mockSelected });
});
});
describe('useArrowNav', () => {
document.body.innerHTML = `
<div id="multiplechoiceresponse" />
<div id="choiceresponse" />
<div id="optionresponse" />
<div id="numericalresponse" />
<div id="stringresponse" />
`;
const mockKeyUp = new KeyboardEvent('keydown', { key: 'ArrowUp' });
const mockKeyDown = new KeyboardEvent('keydown', { key: 'ArrowDown' });
let cb;
let prereqs;
describe('SINGLESELECT', () => {
beforeEach(() => {
module.useArrowNav(ProblemTypeKeys.SINGLESELECT, mockSetSelected);
[cb, prereqs] = React.useEffect.mock.calls[0];
cb();
});
test('pressing up arrow sets MULTISELECT', () => {
expect(React.useEffect.mock.calls.length).toEqual(1);
expect(prereqs).toStrictEqual([ProblemTypeKeys.SINGLESELECT, mockSetSelected]);
document.dispatchEvent(mockKeyUp);
expect(mockSetSelected).toHaveBeenCalledWith(ProblemTypeKeys.TEXTINPUT);
});
test('pressing down arrow sets MULTISELECT', () => {
expect(React.useEffect.mock.calls.length).toEqual(1);
expect(prereqs).toStrictEqual([ProblemTypeKeys.SINGLESELECT, mockSetSelected]);
document.dispatchEvent(mockKeyDown);
expect(mockSetSelected).toHaveBeenCalledWith(ProblemTypeKeys.MULTISELECT);
});
});
describe('MULTISELECT', () => {
beforeEach(() => {
module.useArrowNav(ProblemTypeKeys.MULTISELECT, mockSetSelected);
[cb, prereqs] = React.useEffect.mock.calls[0];
cb();
});
test('pressing up arrow sets SINGLESELECT', () => {
expect(React.useEffect.mock.calls.length).toEqual(1);
expect(prereqs).toStrictEqual([ProblemTypeKeys.MULTISELECT, mockSetSelected]);
document.dispatchEvent(mockKeyUp);
expect(mockSetSelected).toHaveBeenCalledWith(ProblemTypeKeys.SINGLESELECT);
});
test('pressing down arrow sets DROPDOWN', () => {
expect(React.useEffect.mock.calls.length).toEqual(1);
expect(prereqs).toStrictEqual([ProblemTypeKeys.MULTISELECT, mockSetSelected]);
document.dispatchEvent(mockKeyDown);
expect(mockSetSelected).toHaveBeenCalledWith(ProblemTypeKeys.DROPDOWN);
});
});
describe('DROPDOWN', () => {
beforeEach(() => {
module.useArrowNav(ProblemTypeKeys.DROPDOWN, mockSetSelected);
[cb, prereqs] = React.useEffect.mock.calls[0];
cb();
});
test('pressing up arrow sets MULTISELECT', () => {
expect(React.useEffect.mock.calls.length).toEqual(1);
expect(prereqs).toStrictEqual([ProblemTypeKeys.DROPDOWN, mockSetSelected]);
document.dispatchEvent(mockKeyUp);
expect(mockSetSelected).toHaveBeenCalledWith(ProblemTypeKeys.MULTISELECT);
});
test('pressing down arrow sets NUMERIC', () => {
expect(React.useEffect.mock.calls.length).toEqual(1);
expect(prereqs).toStrictEqual([ProblemTypeKeys.DROPDOWN, mockSetSelected]);
document.dispatchEvent(mockKeyDown);
expect(mockSetSelected).toHaveBeenCalledWith(ProblemTypeKeys.NUMERIC);
});
});
describe('NUMERIC', () => {
beforeEach(() => {
module.useArrowNav(ProblemTypeKeys.NUMERIC, mockSetSelected);
[cb, prereqs] = React.useEffect.mock.calls[0];
cb();
});
test('pressing up arrow sets DROPDOWN', () => {
expect(React.useEffect.mock.calls.length).toEqual(1);
expect(prereqs).toStrictEqual([ProblemTypeKeys.NUMERIC, mockSetSelected]);
document.dispatchEvent(mockKeyUp);
expect(mockSetSelected).toHaveBeenCalledWith(ProblemTypeKeys.DROPDOWN);
});
test('pressing down arrow sets TEXTINPUT', () => {
expect(React.useEffect.mock.calls.length).toEqual(1);
expect(prereqs).toStrictEqual([ProblemTypeKeys.NUMERIC, mockSetSelected]);
document.dispatchEvent(mockKeyDown);
expect(mockSetSelected).toHaveBeenCalledWith(ProblemTypeKeys.TEXTINPUT);
});
});
describe('TEXTINPUT', () => {
beforeEach(() => {
module.useArrowNav(ProblemTypeKeys.TEXTINPUT, mockSetSelected);
[cb, prereqs] = React.useEffect.mock.calls[0];
cb();
});
test('pressing up arrow sets NUMERIC', () => {
expect(React.useEffect.mock.calls.length).toEqual(1);
expect(prereqs).toStrictEqual([ProblemTypeKeys.TEXTINPUT, mockSetSelected]);
document.dispatchEvent(mockKeyUp);
expect(mockSetSelected).toHaveBeenCalledWith(ProblemTypeKeys.NUMERIC);
});
test('pressing down arrow sets SINGLESELECT', () => {
expect(React.useEffect.mock.calls.length).toEqual(1);
expect(prereqs).toStrictEqual([ProblemTypeKeys.TEXTINPUT, mockSetSelected]);
document.dispatchEvent(mockKeyDown);
expect(mockSetSelected).toHaveBeenCalledWith(ProblemTypeKeys.SINGLESELECT);
});
});
});
});

View File

@@ -1,23 +1,40 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Col, Row } from '@edx/paragon';
import ProblemTypeSelect from './content/ProblemTypeSelect';
import Preview from './content/Preview';
import AdvanceTypeSelect from './content/AdvanceTypeSelect';
import SelectTypeWrapper from './SelectTypeWrapper';
import * as hooks from './hooks';
import hooks from './hooks';
import { AdvanceProblemKeys } from '../../../../data/constants/problem';
export const SelectTypeModal = () => {
const { selected, setSelected } = hooks.state.selected(null);
export const SelectTypeModal = ({
onClose,
}) => {
const { selected, setSelected } = hooks.selectHooks();
hooks.useArrowNav(selected, setSelected);
return (
<div>
<SelectTypeWrapper selected={selected}>
<ProblemTypeSelect setSelected={setSelected} />
<Preview
problemType={selected}
/>
</SelectTypeWrapper>
</div>
<SelectTypeWrapper onClose={onClose} selected={selected}>
<Row className="justify-content-center align-items-center m-4">
{(!Object.values(AdvanceProblemKeys).includes(selected)) ? (
<>
<Col>
<ProblemTypeSelect selected={selected} setSelected={setSelected} />
</Col>
<Col>
<Preview problemType={selected} />
</Col>
</>
) : <AdvanceTypeSelect selected={selected} setSelected={setSelected} />}
</Row>
</SelectTypeWrapper>
);
};
SelectTypeModal.propTypes = {
onClose: PropTypes.func.isRequired,
};
export default SelectTypeModal;

View File

@@ -0,0 +1,21 @@
import React from 'react';
import { shallow } from 'enzyme';
import * as module from '.';
jest.mock('./hooks', () => ({
selectHooks: jest.fn(() => ({
selected: 'mOcKsELEcted',
setSelected: jest.fn().mockName('setSelected'),
})),
useArrowNav: jest.fn().mockName('useArrowNav'),
}));
describe('SelectTypeModal', () => {
const props = {
onClose: jest.fn(),
};
test('snapshot', () => {
expect(shallow(<module.SelectTypeModal {...props} />)).toMatchSnapshot();
});
});

View File

@@ -331,12 +331,12 @@ export class OLXParser {
getProblemType() {
const problemKeys = Object.keys(this.problem);
const intersectedProblems = _.intersection(Object.values(ProblemTypeKeys), problemKeys);
if (intersectedProblems.length === 0) {
return null;
}
if (intersectedProblems.length > 1) {
const errorMessage = {
code: 500,
message: 'More than one problem type is not supported!',
};
throw errorMessage;
return ProblemTypeKeys.ADVANCED;
}
const problemType = intersectedProblems[0];
return problemType;
@@ -352,10 +352,6 @@ export class OLXParser {
const problemType = this.getProblemType();
const hints = this.getHints();
const question = this.parseQuestions(problemType);
const errorMessage = {
code: 500,
message: 'The problem type is not supported!',
};
switch (problemType) {
case ProblemTypeKeys.DROPDOWN:
answersObject = this.parseMultipleChoiceAnswers(ProblemTypeKeys.DROPDOWN, 'optioninput', 'option');
@@ -372,8 +368,11 @@ export class OLXParser {
case ProblemTypeKeys.SINGLESELECT:
answersObject = this.parseMultipleChoiceAnswers(ProblemTypeKeys.SINGLESELECT, 'choicegroup', 'choice');
break;
case ProblemTypeKeys.ADVANCED:
break;
default:
throw errorMessage;
// if problem is unset, return null
return {};
}
if (_.has(answersObject, 'additionalStringAttributes')) {

View File

@@ -55,10 +55,10 @@ exports[`TranscriptWidget component snapshots snapshot: renders ErrorAlert with
/>
</div>
</Form.Checkbox>
<OverLayTrigger
<OverlayTrigger
key="top"
overlay={
<ToolTip
<Tooltip
id="tooltip-top"
>
<FormattedMessage
@@ -66,7 +66,7 @@ exports[`TranscriptWidget component snapshots snapshot: renders ErrorAlert with
description="Message for show by default checkbox"
id="authoring.videoeditor.transcripts.upload.allowDownloadTooltipMessage"
/>
</ToolTip>
</Tooltip>
}
placement="top"
>
@@ -78,7 +78,7 @@ exports[`TranscriptWidget component snapshots snapshot: renders ErrorAlert with
}
}
/>
</OverLayTrigger>
</OverlayTrigger>
<ActionRow.Spacer />
</ActionRow>
<Form.Checkbox
@@ -176,10 +176,10 @@ exports[`TranscriptWidget component snapshots snapshot: renders ErrorAlert with
/>
</div>
</Form.Checkbox>
<OverLayTrigger
<OverlayTrigger
key="top"
overlay={
<ToolTip
<Tooltip
id="tooltip-top"
>
<FormattedMessage
@@ -187,7 +187,7 @@ exports[`TranscriptWidget component snapshots snapshot: renders ErrorAlert with
description="Message for show by default checkbox"
id="authoring.videoeditor.transcripts.upload.allowDownloadTooltipMessage"
/>
</ToolTip>
</Tooltip>
}
placement="top"
>
@@ -199,7 +199,7 @@ exports[`TranscriptWidget component snapshots snapshot: renders ErrorAlert with
}
}
/>
</OverLayTrigger>
</OverlayTrigger>
<ActionRow.Spacer />
</ActionRow>
<Form.Checkbox
@@ -293,10 +293,10 @@ exports[`TranscriptWidget component snapshots snapshots: renders as expected wit
/>
</div>
</Form.Checkbox>
<OverLayTrigger
<OverlayTrigger
key="top"
overlay={
<ToolTip
<Tooltip
id="tooltip-top"
>
<FormattedMessage
@@ -304,7 +304,7 @@ exports[`TranscriptWidget component snapshots snapshots: renders as expected wit
description="Message for show by default checkbox"
id="authoring.videoeditor.transcripts.upload.allowDownloadTooltipMessage"
/>
</ToolTip>
</Tooltip>
}
placement="top"
>
@@ -316,7 +316,7 @@ exports[`TranscriptWidget component snapshots snapshots: renders as expected wit
}
}
/>
</OverLayTrigger>
</OverlayTrigger>
<ActionRow.Spacer />
</ActionRow>
<Form.Checkbox
@@ -467,10 +467,10 @@ exports[`TranscriptWidget component snapshots snapshots: renders as expected wit
/>
</div>
</Form.Checkbox>
<OverLayTrigger
<OverlayTrigger
key="top"
overlay={
<ToolTip
<Tooltip
id="tooltip-top"
>
<FormattedMessage
@@ -478,7 +478,7 @@ exports[`TranscriptWidget component snapshots snapshots: renders as expected wit
description="Message for show by default checkbox"
id="authoring.videoeditor.transcripts.upload.allowDownloadTooltipMessage"
/>
</ToolTip>
</Tooltip>
}
placement="top"
>
@@ -490,7 +490,7 @@ exports[`TranscriptWidget component snapshots snapshots: renders as expected wit
}
}
/>
</OverLayTrigger>
</OverlayTrigger>
<ActionRow.Spacer />
</ActionRow>
<Form.Checkbox
@@ -584,10 +584,10 @@ exports[`TranscriptWidget component snapshots snapshots: renders as expected wit
/>
</div>
</Form.Checkbox>
<OverLayTrigger
<OverlayTrigger
key="top"
overlay={
<ToolTip
<Tooltip
id="tooltip-top"
>
<FormattedMessage
@@ -595,7 +595,7 @@ exports[`TranscriptWidget component snapshots snapshots: renders as expected wit
description="Message for show by default checkbox"
id="authoring.videoeditor.transcripts.upload.allowDownloadTooltipMessage"
/>
</ToolTip>
</Tooltip>
}
placement="top"
>
@@ -607,7 +607,7 @@ exports[`TranscriptWidget component snapshots snapshots: renders as expected wit
}
}
/>
</OverLayTrigger>
</OverlayTrigger>
<ActionRow.Spacer />
</ActionRow>
<Form.Checkbox

View File

@@ -95,10 +95,10 @@ exports[`VideoSourceWidget snapshots snapshots: renders as expected with default
/>
</div>
</Form.Checkbox>
<OverLayTrigger
<OverlayTrigger
key="top"
overlay={
<ToolTip
<Tooltip
id="tooltip-top"
>
<FormattedMessage
@@ -108,7 +108,7 @@ exports[`VideoSourceWidget snapshots snapshots: renders as expected with default
description="Message for allow video downloads checkbox"
id="authoring.videoeditor.videoSource.fallbackVideo.allowDownloadTooltipMessage"
/>
</ToolTip>
</Tooltip>
}
placement="top"
>
@@ -120,7 +120,7 @@ exports[`VideoSourceWidget snapshots snapshots: renders as expected with default
}
}
/>
</OverLayTrigger>
</OverlayTrigger>
<ActionRow.Spacer />
</ActionRow>
</Form.Group>

View File

@@ -0,0 +1,92 @@
/* eslint-disable */
// ---
// metadata:
// display_name: Circuit Schematic Builder
// markdown: !!null
// data: |
export const circuitSchematic = `<problem>
<p>
Circuit schematic problems allow students to create virtual circuits by
arranging elements such as voltage sources, capacitors, resistors, and
MOSFETs on an interactive grid. The system evaluates a DC, AC, or
transient analysis of the circuit.
</p>
<p>
For more information, see
<a href="https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/circuit_schematic_builder.html" target="_blank">
Circuit Schematic Builder Problem</a> in <i>Building and Running an edX Course</i>.
</p>
<p>
When you add the problem, be sure to select <strong>Settings</strong>
to specify a <strong>Display Name</strong> and other values that apply.
</p>
<p>You can use the following example problems as models.</p>
<schematicresponse>
<p>Make a voltage divider that splits the provided voltage evenly.</p>
<center>
<schematic height="500" width="600" parts="g,r" analyses="dc"
initial_value="[[&quot;v&quot;,[168,144,0],{&quot;value&quot;:&quot;dc(1)&quot;,&quot;_json_&quot;:0},[&quot;1&quot;,&quot;0&quot;]],[&quot;r&quot;,[296,120,0],{&quot;r&quot;:&quot;1&quot;,&quot;_json_&quot;:1},[&quot;1&quot;,&quot;output&quot;]],[&quot;L&quot;,[296,168,3],{&quot;label&quot;:&quot;output&quot;,&quot;_json_&quot;:2},[&quot;output&quot;]],[&quot;w&quot;,[296,216,168,216]],[&quot;w&quot;,[168,216,168,192]],[&quot;w&quot;,[168,144,168,120]],[&quot;w&quot;,[168,120,296,120]],[&quot;g&quot;,[168,216,0],{&quot;_json_&quot;:7},[&quot;0&quot;]],[&quot;view&quot;,-67.49999999999994,-78.49999999999994,1.6000000000000003,&quot;50&quot;,&quot;10&quot;,&quot;1G&quot;,null,&quot;100&quot;,&quot;1&quot;,&quot;1000&quot;]]"/>
</center>
<answer type="loncapa/python">
dc_value = "dc analysis not found"
for response in submission[0]:
if response[0] == 'dc':
for node in response[1:]:
dc_value = node['output']
if dc_value == .5:
correct = ['correct']
else:
correct = ['incorrect']
</answer>
<solution>
<div class="detailed-solution">
<p>Explanation</p>
<p>
You can form a voltage divider that evenly divides the input
voltage with two identically valued resistors, with the sampled
voltage taken in between the two.
</p>
<p><img src="/static/images/voltage_divider.png" alt=""/></p>
</div>
</solution>
</schematicresponse>
<schematicresponse>
<p>Make a high-pass filter.</p>
<center>
<schematic height="500" width="600" parts="g,r,s,c" analyses="ac"
submit_analyses="{&quot;ac&quot;:[[&quot;NodeA&quot;,1,9]]}"
initial_value="[[&quot;v&quot;,[160,152,0],{&quot;name&quot;:&quot;v1&quot;,&quot;value&quot;:&quot;sin(0,1,1,0,0)&quot;,&quot;_json_&quot;:0},[&quot;1&quot;,&quot;0&quot;]],[&quot;w&quot;,[160,200,240,200]],[&quot;g&quot;,[160,200,0],{&quot;_json_&quot;:2},[&quot;0&quot;]],[&quot;L&quot;,[240,152,3],{&quot;label&quot;:&quot;NodeA&quot;,&quot;_json_&quot;:3},[&quot;NodeA&quot;]],[&quot;s&quot;,[240,152,0],{&quot;color&quot;:&quot;cyan&quot;,&quot;offset&quot;:&quot;0&quot;,&quot;_json_&quot;:4},[&quot;NodeA&quot;]],[&quot;view&quot;,64.55878906250004,54.114697265625054,2.5000000000000004,&quot;50&quot;,&quot;10&quot;,&quot;1G&quot;,null,&quot;100&quot;,&quot;1&quot;,&quot;1000&quot;]]"/>
</center>
<answer type="loncapa/python">
ac_values = None
for response in submission[0]:
if response[0] == 'ac':
for node in response[1:]:
ac_values = node['NodeA']
print "the ac analysis value:", ac_values
if ac_values == None:
correct = ['incorrect']
elif ac_values[0][1] &lt; ac_values[1][1]:
correct = ['correct']
else:
correct = ['incorrect']
</answer>
<solution>
<div class="detailed-solution">
<p>Explanation</p>
<p>
You can form a simple high-pass filter without any further
constraints by simply putting a resistor in series with a
capacitor. The actual values of the components do not really
matter in this problem.
</p>
<p><img src="/static/images/high_pass_filter.png" alt=""/></p>
</div>
</solution>
</schematicresponse>
</problem>`;
export default { circuitSchematic };

View File

@@ -0,0 +1,79 @@
/* eslint-disable */
// ---
// metadata:
// display_name: Custom Python-Evaluated Input
// markdown: !!null
// data: |
export const customGrader = `<problem>
<p>
In custom Python-evaluated input (also called "write-your-own-grader"
problems), the grader uses a Python script that you create and embed in
the problem to evaluate a learner's response or provide hints. These
problems can be any type. Numerical input and text input problems are
the most common write-your-own-grader problems.
</p>
<p>
You can use script tag format or answer tag format to create these problems.
</p>
<p>
You can create custom Python-evaluated input problems that provide
partial credit or that randomize variables in the Python code. You can
also add images to the solution by using an HTML "img" tag. Note that
the "img" tag must be between the "div" tags that are inside the
"solution" tags, and that learners do not see these images until they
click the "Show Answer" button.
</p>
<p>
For more information, see <a href="https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/custom_python.html" target="_blank">
Write-Your-Own-Grader Problem</a> in <i>Building and Running an edX Course</i>.
</p>
<p>
When you add the problem, be sure to select <strong>Settings</strong>
to specify a <strong>Display Name</strong> and other values that apply.
</p>
<p>You can use the following example problem as a model.</p>
<hr/>
<customresponse cfn="test_add_to_ten">
<script type="loncapa/python">
def test_add_to_ten(expect, ans):
return test_add(10, ans)
</script>
<label>Enter two integers that sum to 10.</label>
<textline size="40" correct_answer="3" label="Enter first number" /><br/>
<textline size="40" correct_answer="7" label="Enter second number" />
<solution>
<div class="detailed-solution">
<p>Explanation</p>
<p>Any set of integers on the line \(y = 10 - x\) satisfy these constraints.</p>
</div>
</solution>
</customresponse>
<customresponse cfn="test_add" expect="20">
<script type="loncapa/python">
def test_add(expect, ans):
try:
a1=int(ans[0])
a2=int(ans[1])
return (a1+a2) == int(expect)
except ValueError:
return False
</script>
<label>Enter two integers that sum to 20.</label>
<textline size="40" correct_answer="11" label="Enter first number" /><br/>
<textline size="40" correct_answer="9" label="Enter second number" />
<solution>
<div class="detailed-solution">
<p>Explanation</p>
<p>Any set of integers on the line \(y = 20 - x\) satisfy these constraints.</p>
<p>To add an image to the solution, use an HTML "img" tag. Make sure to include alt text.</p>
<img src="/static/images/placeholder-image.png" width="400"
alt="Description of image, with a primary goal of explaining its
relevance to the problem or concept being illustrated for someone
who is unable to see the image."/>
</div>
</solution>
</customresponse>
</problem>`;
export default { customGrader };

View File

@@ -0,0 +1,88 @@
/* eslint-disable */
// ---
// metadata:
// display_name: Drag and Drop (Deprecated Version)
// markdown: !!null
// showanswer: never
// data: |
export const dragAndDrop = `<problem>
<p>In drag and drop problems, students respond to a question by dragging text or objects to a specific location on an image.</p>
<p>
For more information, see
<a href="https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/drag_and_drop_deprecated.html" target="_blank">
Drag and Drop Problem (Deprecated)</a> in <i>Building and Running an edX Course</i>.
</p>
<p>
When you add the problem, be sure to select <strong>Settings</strong>
to specify a <strong>Display Name</strong> and other values that apply.
</p>
<p>You can use the following example problems as models.</p>
<hr/>
<customresponse>
<h3>Simple Drag and Drop</h3>
<p>Drag each word in the scrollbar to the bucket that matches the number of letters in the word.</p>
<drag_and_drop_input img="https://studio.edx.org/c4x/edX/DemoX/asset/L9_buckets.png">
<draggable id="1" label="a"/>
<draggable id="2" label="bog"/>
<draggable id="3" label="droll"/>
<draggable id="4" label="oboe"/>
<draggable id="5" label="swain"/>
<draggable id="6" label="in"/>
<draggable id="7" label="onyx"/>
<draggable id="8" label="of"/>
<draggable id="9" label="tap"/>
<draggable id="10" label="strop"/>
<draggable id="11" label="few"/>
</drag_and_drop_input>
<answer type="loncapa/python">
correct_answer = {
'1': [[70, 150], 121],
'6': [[190, 150], 121],
'8': [[190, 150], 121],
'2': [[310, 150], 121],
'9': [[310, 150], 121],
'11': [[310, 150], 121],
'4': [[420, 150], 121],
'7': [[420, 150], 121],
'3': [[550, 150], 121],
'5': [[550, 150], 121],
'10': [[550, 150], 121]}
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
</answer>
</customresponse>
<customresponse>
<h3>Drag and Drop with Outline</h3>
<p>Label the hydrogen atoms connected with the left carbon atom.</p>
<drag_and_drop_input img="https://studio.edx.org/c4x/edX/DemoX/asset/ethglycol.jpg" target_outline="true" one_per_target="true" no_labels="true" label_bg_color="rgb(222, 139, 238)">
<draggable id="1" label="Hydrogen" />
<draggable id="2" label="Hydrogen" />
<target id="t1_o" x="10" y="67" w="100" h="100"/>
<target id="t2" x="133" y="3" w="70" h="70"/>
<target id="t3" x="2" y="384" w="70" h="70"/>
<target id="t4" x="95" y="386" w="70" h="70"/>
<target id="t5_c" x="94" y="293" w="91" h="91"/>
<target id="t6_c" x="328" y="294" w="91" h="91"/>
<target id="t7" x="393" y="463" w="70" h="70"/>
<target id="t8" x="344" y="214" w="70" h="70"/>
<target id="t9_o" x="445" y="162" w="100" h="100"/>
<target id="t10" x="591" y="132" w="70" h="70"/>
</drag_and_drop_input>
<answer type="loncapa/python">
correct_answer = [{
'draggables': ['1', '2'],
'targets': ['t2', 't3', 't4' ],
'rule':'anyof'
}]
if draganddrop.grade(submission[0], correct_answer):
correct = ['correct']
else:
correct = ['incorrect']
</answer>
</customresponse>
</problem>`;
export default { dragAndDrop };

View File

@@ -0,0 +1,16 @@
/* eslint-disable */
// ---
// metadata:
// display_name: Math Expression Input
// markdown: !!null
// data: |
export const formulaResponse = `<problem>
<formularesponse type="ci" samples="R_1,R_2,R_3@1,2,3:3,4,5#10" answer="R_1*R_2/R_3">
<p>You can use this template as a guide to the OLX markup to use for math expression problems. Edit this component to replace the example with your own assessment.</p>
<label>Add the question text, or prompt, here. This text is required. Example: Write an expression for the product of R_1, R_2, and the inverse of R_3.</label>
<description>You can add an optional tip or note related to the prompt like this. Example: To test this example, the correct answer is R_1*R_2/R_3</description>
<responseparam type="tolerance" default="0.00001"/>
<formulaequationinput size="40"/>
</formularesponse>
</problem>`;
export default { formulaResponse };

View File

@@ -0,0 +1,33 @@
/* eslint-disable */
// ---
// metadata:
// display_name: Image Mapped Input
// markdown: !!null
// data: |
export const imageResponse = `<problem>
<p>
In an image mapped input problem, also known as a "pointing on a picture" problem, students click inside a defined region in an image. You define this region by including coordinates in the body of the problem. You can define one rectangular region,
multiple rectangular regions, or one non-rectangular region. For more information, see
<a href="https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/image_mapped_input.html" target="_blank">Image Mapped Input Problem</a>
in
<i>Building and Running an edx Course</i>.
</p>
<p>When you add the problem, be sure to select
<strong>Settings</strong>
to specify a
<strong>Display Name</strong>
and other values that apply.</p>
<p>You can use the following example problem as a model.</p>
<imageresponse>
<p>What country is home to the Great Pyramid of Giza as well as the cities of Cairo and Memphis? Click the country on the map below.</p>
<imageinput src="https://studio.edx.org/c4x/edX/DemoX/asset/Africa.png" width="600" height="638" rectangle="(338,98)-(412,168)" alt="Map of Africa"/>
<solution>
<div class="detailed-solution">
<p>Explanation</p>
<p>Egypt is home to not only the Pyramids, Cairo, and Memphis, but also the Sphinx and the ancient Royal Library of Alexandria.</p>
</div>
</solution>
</imageresponse>
</problem>`;
export default { imageResponse };

View File

@@ -0,0 +1,81 @@
/* eslint-disable */
// ---
// metadata:
// display_name: Custom JavaScript Display and Grading
// markdown: !!null
// showanswer: never
// data: |
export const jsInputResponse = `<problem>
<p>
In these problems (also called custom JavaScript problems or JS Input
problems), you add a problem or tool that uses JavaScript in Studio.
Studio embeds the problem in an IFrame so that your learners can
interact with it in the LMS. You can grade your learners' work using
JavaScript and some basic Python, and the grading is integrated into the
edX grading system.
</p>
<p>
The JS Input problem that you create must use HTML, JavaScript, and
cascading style sheets (CSS). You can use any application creation tool,
such as the Google Web Toolkit (GWT), to create your JS Input problem.
</p>
<p>
For more information, see
<a href="https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/custom_javascript.html" target="_blank">
Custom JavaScript Problem</a> in <i>Building and Running an edX Course</i>.
</p>
<p>
JavaScript developers can also see
<a href="https://edx.readthedocs.io/projects/edx-developer-guide/en/latest/extending_platform/javascript.html" target="_blank">
Custom JavaScript Applications</a> in the <i>EdX Developer's Guide</i>.
</p>
<p>
When you add the problem, be sure to select <strong>Settings</strong>
to specify a <strong>Display Name</strong> and other values that apply.
Also, be sure to specify a <strong>title</strong> attribute on the <strong>jsinput</strong> tag;
this title is used for the title attribute on the generated IFrame. Generally,
the title attribute on the IFrame should match the title tag of the HTML hosted
within the IFrame, which is specified by the <strong>html_file</strong> attribute.
</p>
<p>You can use the following example problem as a model.</p>
<customresponse cfn="check_function">
<script type="loncapa/python">
<![CDATA[
import json
def check_function(e, ans):
"""
"response" is a dictionary that contains two keys, "answer" and "state".
The value of "answer" is the JSON string that "getGrade" returns.
The value of "state" is the JSON string that "getState" returns.
Clicking either "Submit" or "Save" registers the current state.
"""
response = json.loads(ans)
# You can use the value of the answer key to grade:
answer = json.loads(response["answer"])
return answer == "correct"
# Or you can use the value of the state key to grade:
"""
state = json.loads(response["state"])
return state["selectedChoice"] == "correct"
"""
]]>
</script>
<p>This is paragraph text displayed before the IFrame.</p>
<jsinput
gradefn="JSInputDemo.getGrade"
get_statefn="JSInputDemo.getState"
set_statefn="JSInputDemo.setState"
initial_state='{"selectedChoice": "incorrect1", "availableChoices": ["incorrect1", "correct", "incorrect2"]}'
width="600"
height="100"
html_file="https://files.edx.org/custom-js-example/jsinput_example.html"
title="Dropdown with Dynamic Text"
sop="false"
/>
</customresponse>
</problem>`;
export default { jsInputResponse };

View File

@@ -0,0 +1,46 @@
/* eslint-disable */
// ---
// metadata:
// display_name: Problem with Adaptive Hint
// markdown: !!null
// data: |
export const problemWithHint = `<problem>
<text>
<p><h4>Problem With Adaptive Hint</h4></p>
<p>This problem demonstrates a question with hints, based on using the <tt class="tt">hintfn</tt> method. </p>
<customresponse cfn="test_str" expect="python">
<script type="text/python" system_path="python_lib">
def test_str(expect, ans):
print(expect, ans)
ans = ans.strip("'")
ans = ans.strip('"')
return expect == ans.lower()
def hint_fn(answer_ids, student_answers, new_cmap, old_cmap):
aid = answer_ids[0]
ans = str(student_answers[aid]).lower()
print('hint_fn called, ans=', ans)
hint = ''
if 'java' in ans:
hint = 'that is only good for drinking'
elif 'perl' in ans:
hint = 'not that rich'
elif 'pascal' in ans:
hint = 'that is a beatnick language'
elif 'fortran' in ans:
hint = 'those were the good days'
elif 'clu' in ans:
hint = 'you must be invariant'
if hint:
hint = "&lt;font color='blue'&gt;Hint: {0}&lt;/font&gt;".format(hint)
new_cmap.set_hint_and_mode(aid,hint,'always')
</script>
<label>What is the best programming language that exists today? You may enter your answer in upper or lower case, with or without quotes.</label>
<textline correct_answer="python"/>
<hintgroup hintfn="hint_fn"/>
</customresponse>
</text>
</problem>`;
export default { problemWithHint };

View File

@@ -1,46 +1,129 @@
import { StrictDict } from '../../utils';
import singleSelect from '../images/singleSelect.png';
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';
export const ProblemTypeKeys = StrictDict({
TEXTINPUT: 'stringresponse',
NUMERIC: 'numericalresponse',
DROPDOWN: 'optionresponse',
MULTISELECT: 'choiceresponse',
SINGLESELECT: 'multiplechoiceresponse',
MULTISELECT: 'choiceresponse',
DROPDOWN: 'optionresponse',
NUMERIC: 'numericalresponse',
TEXTINPUT: 'stringresponse',
ADVANCED: 'advanced',
});
export const ProblemTypes = StrictDict({
[ProblemTypeKeys.SINGLESELECT]: {
title: 'Single Select Problem',
preview: ('<div />'),
preview: singleSelect,
description: 'Specify one correct answer from a list of possible options',
helpLink: 'something.com',
helpLink: 'https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/multiple_choice.html',
prev: ProblemTypeKeys.TEXTINPUT,
next: ProblemTypeKeys.MULTISELECT,
},
[ProblemTypeKeys.MULTISELECT]: {
title: 'Multi Select Problem',
preview: ('<div />'),
preview: multiSelect,
description: 'Specify one or more correct answers from a list of possible options.',
helpLink: 'something.com',
helpLink: 'https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/checkbox.html',
next: ProblemTypeKeys.DROPDOWN,
prev: ProblemTypeKeys.SINGLESELECT,
},
[ProblemTypeKeys.DROPDOWN]: {
title: 'Dropdown Problem',
preview: ('<div />'),
preview: dropdown,
description: 'Specify one correct answer from a list of possible options, selected in a dropdown menu.',
helpLink: 'something.com',
helpLink: 'https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/dropdown.html',
next: ProblemTypeKeys.NUMERIC,
prev: ProblemTypeKeys.MULTISELECT,
},
[ProblemTypeKeys.NUMERIC]: {
title: 'Numeric Response Problem',
preview: ('<div />'),
preview: numericalInput,
description: 'Specify one or more correct numeric answers, submitted in a response field.',
helpLink: 'something.com',
helpLink: 'https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/numerical_input.html',
next: ProblemTypeKeys.TEXTINPUT,
prev: ProblemTypeKeys.DROPDOWN,
},
[ProblemTypeKeys.TEXTINPUT]: {
title: 'Text Input Problem',
preview: ('<div />'),
preview: textInput,
description: 'Specify one or more correct text answers, including numbers and special characters, submitted in a response field.',
helpLink: 'https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/text_input.html',
prev: ProblemTypeKeys.NUMERIC,
next: ProblemTypeKeys.SINGLESELECT,
},
[ProblemTypeKeys.ADVANCED]: {
title: 'Advanced Problem',
preview: ('<div />'),
description: 'An Advanced Problem Type',
helpLink: 'something.com',
},
});
export const AdvanceProblemKeys = StrictDict({
BLANK: 'blankadvanced',
CIRCUITSCHEMATIC: 'circuitschematic',
JSINPUT: 'jsinputresponse',
CUSTOMGRADER: 'customgrader',
DRAGANDDROP: 'draganddrop',
IMAGE: 'imageresponse',
FORMULA: 'formularesponse',
PROBLEMWITHHINT: 'problemwithhint',
});
export const AdvanceProblems = StrictDict({
[AdvanceProblemKeys.BLANK]: {
title: 'Blank advance problem',
status: '',
template: '<problem></problem>',
},
[AdvanceProblemKeys.CIRCUITSCHEMATIC]: {
title: 'Circuit schematic builder',
status: 'Not supported',
template: circuitSchematic,
},
[AdvanceProblemKeys.JSINPUT]: {
title: 'Custom JavaScript display and grading',
status: '',
template: jsInputResponse,
},
[AdvanceProblemKeys.CUSTOMGRADER]: {
title: 'Custom Python-evaluated input',
status: 'Provisional',
template: customGrader,
},
[AdvanceProblemKeys.DRAGANDDROP]: {
title: 'Drag and drop (deprecated version)',
status: 'Not supported',
template: dragAndDrop,
},
[AdvanceProblemKeys.IMAGE]: {
title: 'Image mapped input',
status: 'Not supported',
template: imageResponse,
},
[AdvanceProblemKeys.FORMULA]: {
title: 'Math expression input',
status: '',
template: formulaResponse,
},
[AdvanceProblemKeys.PROBLEMWITHHINT]: {
title: 'Problem with adaptive hint',
status: 'Not supported',
template: problemWithHint,
},
});
export const ShowAnswerTypesKeys = StrictDict({
ALWAYS: 'always',
ANSWERED: 'answered',

View File

@@ -22,4 +22,6 @@ export const RequestKeys = StrictDict({
fetchCourseDetails: 'fetchCourseDetails',
updateTranscriptLanguage: 'updateTranscriptLanguage',
getTranscriptFile: 'getTranscriptFile',
uploadImage: 'uploadImage',
fetchAdvanceSettings: 'fetchAdvanceSettings',
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -7,7 +7,7 @@ import { ProblemTypeKeys, ShowAnswerTypesKeys } from '../../constants/problem';
const nextAlphaId = (lastId) => String.fromCharCode(lastId.charCodeAt(0) + 1);
const initialState = {
rawOLX: '',
problemType: ProblemTypeKeys.SINGLESELECT,
problemType: null,
question: '',
answers: [],
groupFeedbackList: [],
@@ -124,9 +124,13 @@ const problem = createSlice({
},
...payload,
}),
onSelect: (state, { payload }) => ({
setEnableTypeSelection: (state) => ({
...state,
...payload,
problemType: null,
}),
setProblemType: (state, { payload: { selected } }) => ({
...state,
problemType: selected,
}),
},
});

View File

@@ -1,22 +1,31 @@
import _ from 'lodash-es';
import * as requests from './requests';
import { actions } from '..';
import { OLXParser } from '../../../containers/ProblemEditor/data/OLXParser';
import { parseSettings } from '../../../containers/ProblemEditor/data/SettingsParser';
export const initializeProblem = (blockValue) => (dispatch) => {
const rawOLX = _.get(blockValue, 'data.data', {});
try {
const olxParser = new OLXParser(rawOLX);
const { ...data } = olxParser.getParsedOLXData();
let { settings } = olxParser.getParsedOLXData();
settings = { ...settings, ...parseSettings(_.get(blockValue, 'data.metadata', {})) };
if (!_.isEmpty(rawOLX) && !_.isEmpty(data)) {
dispatch(actions.problem.load({ ...data, rawOLX, settings }));
}
} catch (error) {
// eslint-disable-next-line
console.error(error);
const olxParser = new OLXParser(rawOLX);
const parsedProblem = olxParser.getParsedOLXData();
if (_.isEmpty(parsedProblem)) {
// if problem is blank, enable selection.
dispatch(actions.problem.setEnableTypeSelection());
}
const { settings, ...data } = parsedProblem;
const parsedSettings = { ...settings, ...parseSettings(_.get(blockValue, 'data.metadata', {})) };
if (!_.isEmpty(rawOLX) && !_.isEmpty(data)) {
dispatch(actions.problem.load({ ...data, rawOLX, settings: parsedSettings }));
}
dispatch(requests.fetchAdvanceSettings({
onSuccess: (response) => {
console.log(response);
if (response.data.allow_unsupported_xblocks.value) {
console.log(response.allow_unsupported_xblocks.value);
}
},
}));
};
export default { initializeProblem };

View File

@@ -236,6 +236,17 @@ export const fetchCourseDetails = ({ ...rest }) => (dispatch, getState) => {
}));
};
export const fetchAdvanceSettings = ({ ...rest }) => (dispatch, getState) => {
dispatch(module.networkRequest({
requestKey: RequestKeys.fetchAdvanceSettings,
promise: api.fetchAdvanceSettings({
studioEndpointUrl: selectors.app.studioEndpointUrl(getState()),
learningContextId: selectors.app.learningContextId(getState()),
}),
...rest,
}));
};
export default StrictDict({
fetchBlock,
fetchStudioView,
@@ -250,4 +261,5 @@ export default StrictDict({
updateTranscriptLanguage,
fetchCourseDetails,
getTranscriptFile,
fetchAdvanceSettings,
});

View File

@@ -21,6 +21,9 @@ export const apiMethods = {
fetchCourseDetails: ({ studioEndpointUrl, learningContextId }) => get(
urls.courseDetailsUrl({ studioEndpointUrl, learningContextId }),
),
fetchAdvanceSettings: ({ studioEndpointUrl, learningContextId }) => get(
urls.courseAdvanceSettings({ studioEndpointUrl, learningContextId }),
),
uploadAsset: ({
learningContextId,
studioEndpointUrl,

View File

@@ -35,17 +35,7 @@ export const fetchBlockById = ({ blockId, studioEndpointUrl }) => {
} else if (blockId === 'problem-block-id') {
data = {
data: `<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>`,
</problem>`,
display_name: 'Dropdown',
metadata: {
markdown: `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.
@@ -135,6 +125,10 @@ export const fetchCourseDetails = ({ studioEndpointUrl, learningContextId }) =>
export const allowThumbnailUpload = ({ studioEndpointUrl }) => mockPromise({
data: true,
});
// eslint-disable-next-line
export const fetchAdvanceSettings = ({ studioEndpointUrl, learningContextId }) => mockPromise({
data: { allow_unsupported_xblocks: { value: true } },
});
export const normalizeContent = ({
blockId,

View File

@@ -54,3 +54,7 @@ export const downloadVideoHandoutUrl = ({ studioEndpointUrl, handout }) => (
export const courseDetailsUrl = ({ studioEndpointUrl, learningContextId }) => (
`${studioEndpointUrl}/settings/details/${learningContextId}`
);
export const courseAdvanceSettings = ({ studioEndpointUrl, learningContextId }) => (
`${studioEndpointUrl}/api/contentstore/v0/advanced_settings/${learningContextId}`
);

View File

@@ -111,7 +111,11 @@ jest.mock('@edx/paragon', () => jest.requireActual('testUtils').mockNestedCompon
Label: 'Form.Label',
Text: 'Form.Text',
Row: 'Form.Row',
Radio: 'Radio',
RadioSet: 'RadioSet',
},
OverlayTrigger: 'OverlayTrigger',
Tooltip: 'Tooltip',
FullscreenModal: 'FullscreenModal',
Row: 'Row',
Scrollable: 'Scrollable',
@@ -122,9 +126,7 @@ jest.mock('@edx/paragon', () => jest.requireActual('testUtils').mockNestedCompon
Spinner: 'Spinner',
Stack: 'Stack',
Toast: 'Toast',
Tooltip: 'ToolTip',
Truncate: 'Truncate',
OverlayTrigger: 'OverLayTrigger',
}));
jest.mock('@edx/paragon/icons', () => ({