diff --git a/.gitignore b/.gitignore
index d10bc1963..ef085bb6d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -110,3 +110,6 @@ dist
### local overrides ###
module.config.js
+
+### Code editors ###
+.vscode
\ No newline at end of file
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/CardSection.jsx b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/CardSection.jsx
new file mode 100644
index 000000000..de0b37b10
--- /dev/null
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/CardSection.jsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import { Collapsible, Card } from '@edx/paragon';
+import {
+ bool, string, node,
+} from 'prop-types';
+
+const CardSection = ({
+ children, none, isCardCollapsibleOpen, summary,
+}) => {
+ const show = isCardCollapsibleOpen || summary;
+ if (!show) { return null; }
+
+ return (
+
+
+
+ {summary}
+
+
+
+
+ {children}
+
+
+
+ );
+};
+CardSection.propTypes = {
+ none: bool,
+ children: node.isRequired,
+ summary: string,
+ isCardCollapsibleOpen: bool.isRequired,
+};
+CardSection.defaultProps = {
+ none: false,
+ summary: null,
+};
+
+export default CardSection;
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/CardSection.test.jsx b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/CardSection.test.jsx
new file mode 100644
index 000000000..5d3dd8a37
--- /dev/null
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/CardSection.test.jsx
@@ -0,0 +1,12 @@
+import { shallow } from 'enzyme';
+import CardSection from './CardSection';
+
+describe('CardSection', () => {
+ test('open', () => {
+ expect(shallow(Section Text
)).toMatchSnapshot();
+ });
+
+ test('closed', () => {
+ expect(shallow(Section Text
)).toMatchSnapshot();
+ });
+});
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/SettingsOption.jsx b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/SettingsOption.jsx
index 8efba552a..0bf304d2c 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/SettingsOption.jsx
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/SettingsOption.jsx
@@ -1,23 +1,22 @@
import React from 'react';
import { Collapsible, Icon, Card } from '@edx/paragon';
import { KeyboardArrowUp, KeyboardArrowDown } from '@edx/paragon/icons';
-import PropTypes from 'prop-types';
+import {
+ arrayOf, shape, string, node,
+} from 'prop-types';
import { showFullCard } from './hooks';
+import CardSection from './CardSection';
export const SettingsOption = ({
- title,
- summary,
- none,
- children,
- className,
+ title, className, extraSections, children, summary, ...passThroughProps
}) => {
- const { isCardCollapsed, toggleCardCollapse } = showFullCard();
+ const { isCardCollapsibleOpen, toggleCardCollapse } = showFullCard();
return (
-
+
@@ -31,36 +30,33 @@ export const SettingsOption = ({
-
-
-
- {summary}
-
-
-
-
- {children}
-
-
-
+
+ {children}
+
+ {extraSections.map((section, index) => (
+ <>
+ {isCardCollapsibleOpen &&
}
+ {/* eslint-disable-next-line react/no-array-index-key */}
+
+ {section.children}
+
+ >
+ ))}
);
};
-
SettingsOption.propTypes = {
- title: PropTypes.string.isRequired,
- summary: PropTypes.string.isRequired,
- none: PropTypes.bool,
- className: PropTypes.string,
- children: PropTypes.node.isRequired,
+ title: string.isRequired,
+ children: node.isRequired,
+ className: string,
+ summary: string.isRequired,
+ extraSections: arrayOf(shape({
+ children: node,
+ })),
};
SettingsOption.defaultProps = {
- none: false,
className: '',
+ extraSections: [],
};
export default SettingsOption;
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/SettingsOption.test.jsx b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/SettingsOption.test.jsx
index ff53a6979..dd53fd12d 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/SettingsOption.test.jsx
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/SettingsOption.test.jsx
@@ -3,10 +3,21 @@ import { shallow } from 'enzyme';
import SettingsOption from './SettingsOption';
describe('SettingsOption', () => {
- describe('render', () => {
- const testContent = (
My test content
);
+ describe('default with children', () => {
+ const children = (My test content
);
test('snapshot: renders correct', () => {
- expect(shallow({testContent})).toMatchSnapshot();
+ expect(shallow({children})).toMatchSnapshot();
+ });
+ });
+ describe('with additional sections', () => {
+ const children = (First Section
);
+ const sections = [Second Section
, Third Section
];
+ test('snapshot: renders correct', () => {
+ expect(shallow(
+
+ {children}
+ ,
+ )).toMatchSnapshot();
});
});
});
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/__snapshots__/CardSection.test.jsx.snap b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/__snapshots__/CardSection.test.jsx.snap
new file mode 100644
index 000000000..e4aaeef38
--- /dev/null
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/__snapshots__/CardSection.test.jsx.snap
@@ -0,0 +1,34 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`CardSection closed 1`] = `""`;
+
+exports[`CardSection open 1`] = `
+
+
+
+
+ summary
+
+
+
+
+
+
+ Section Text
+
+
+
+
+`;
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/__snapshots__/SettingsOption.test.jsx.snap b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/__snapshots__/SettingsOption.test.jsx.snap
index 399359e7a..3699736bd 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/__snapshots__/SettingsOption.test.jsx.snap
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/__snapshots__/SettingsOption.test.jsx.snap
@@ -1,11 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`SettingsOption render snapshot: renders correct 1`] = `
+exports[`SettingsOption default with children snapshot: renders correct 1`] = `
-
-
-
-
- Settings Option Summary
-
-
-
-
-
-
- My test content
-
-
-
-
+
+ My test content
+
+
+
+`;
+
+exports[`SettingsOption with additional sections snapshot: renders correct 1`] = `
+
+
+
+
+
+ Settings Option Title
+
+
+
+
+
+
+
+
+
+
+
+
+ First Section
+
+
+
+
`;
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/hooks.js b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/hooks.js
index 92072b309..ca5b9ef18 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/hooks.js
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/hooks.js
@@ -21,10 +21,10 @@ export const showAdvancedSettingsCards = () => {
};
export const showFullCard = () => {
- const [isCardCollapsed, setIsCardCollapsed] = module.state.cardCollapsed(false);
+ const [isCardCollapsibleOpen, setIsCardCollapsibleOpen] = module.state.cardCollapsed(false);
return {
- isCardCollapsed,
- toggleCardCollapse: () => setIsCardCollapsed(!isCardCollapsed),
+ isCardCollapsibleOpen,
+ toggleCardCollapse: () => setIsCardCollapsibleOpen(!isCardCollapsibleOpen),
};
};
@@ -147,8 +147,9 @@ export const scoringCardHooks = (scoring, updateSettings) => {
};
};
-export const showAnswerCardHooks = (showAnswer, updateSettings) => {
+export const useAnswerSettings = (showAnswer, updateSettings) => {
const [showAttempts, setShowAttempts] = module.state.showAttempts(false);
+
const numberOfAttemptsChoice = [
ShowAnswerTypesKeys.AFTER_SOME_NUMBER_OF_ATTEMPTS,
ShowAnswerTypesKeys.AFTER_ALL_ATTEMPTS,
@@ -173,9 +174,14 @@ export const showAnswerCardHooks = (showAnswer, updateSettings) => {
updateSettings({ showAnswer: { ...showAnswer, afterAttempts: attempts } });
};
+ const handleExplanationChange = (event) => {
+ updateSettings({ solutionExplanation: event.target.value });
+ };
+
return {
handleShowAnswerChange,
handleAttemptsChange,
+ handleExplanationChange,
showAttempts,
};
};
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/hooks.test.js b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/hooks.test.js
index bf23778b5..8f907c4a1 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/hooks.test.js
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/hooks.test.js
@@ -53,7 +53,7 @@ describe('Problem settings hooks', () => {
output = hooks.showFullCard();
});
test('test default state is false', () => {
- expect(output.isCardCollapsed).toBeFalsy();
+ expect(output.isCardCollapsibleOpen).toBeFalsy();
});
test('test toggleCardCollapse to true', () => {
output.toggleCardCollapse();
@@ -220,7 +220,7 @@ describe('Problem settings hooks', () => {
afterAttempts: 5,
};
beforeEach(() => {
- output = hooks.showAnswerCardHooks(showAnswer, updateSettings);
+ output = hooks.useAnswerSettings(showAnswer, updateSettings);
});
test('test handleShowAnswerChange', () => {
const value = 'always';
@@ -232,6 +232,11 @@ describe('Problem settings hooks', () => {
output.handleAttemptsChange({ target: { value } });
expect(updateSettings).toHaveBeenCalledWith({ showAnswer: { ...showAnswer, afterAttempts: parseInt(value) } });
});
+ test('handleExplanationChange should update settings', () => {
+ const value = 'explanation';
+ output.handleExplanationChange({ target: { value } });
+ expect(updateSettings).toHaveBeenCalledWith({ solutionExplanation: value });
+ });
});
describe('Timer card hooks', () => {
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx
index b2caf9a8d..229363a32 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/index.jsx
@@ -67,7 +67,11 @@ export const SettingsWidget = ({
-
+
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/messages.js b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/messages.js
index f8bf23431..09a6007cf 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/messages.js
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/messages.js
@@ -194,6 +194,16 @@ export const messages = {
defaultMessage: 'Switch To Advanced Editor',
description: 'message to confirm that a user wants to use the advanced editor',
},
+ explanationInputLabel: {
+ id: 'authoring.problemeditor.settings.showAnswer.explanation.inputLabel',
+ defaultMessage: 'Explanation',
+ description: 'answer explanation input label',
+ },
+ explanationSettingText: {
+ id: 'authoring.problemeditor.settings.showAnswer.explanation.text',
+ defaultMessage: 'Provide an explanation for the correct answer.',
+ description: 'Solution Explanation text',
+ },
};
export default messages;
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/ShowAnswerCard.jsx b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/ShowAnswerCard.jsx
index cdd8186ac..4a8c9cc56 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/ShowAnswerCard.jsx
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/ShowAnswerCard.jsx
@@ -7,10 +7,11 @@ import SettingsOption from '../SettingsOption';
import { ShowAnswerTypes, ShowAnswerTypesKeys } from '../../../../../../data/constants/problem';
import { selectors } from '../../../../../../data/redux';
import messages from '../messages';
-import { showAnswerCardHooks } from '../hooks';
+import { useAnswerSettings } from '../hooks';
export const ShowAnswerCard = ({
showAnswer,
+ solutionExplanation,
updateSettings,
// inject
intl,
@@ -21,24 +22,23 @@ export const ShowAnswerCard = ({
const {
handleShowAnswerChange,
handleAttemptsChange,
+ handleExplanationChange,
showAttempts,
- } = showAnswerCardHooks(showAnswer, updateSettings);
- return (
-
-
+ } = useAnswerSettings(showAnswer, updateSettings);
+
+ const showAnswerSection = (
+ <>
+
-
+
-
+
{showAttempts
&& (
-
+
)}
+ >
+ );
+
+ const explanationSection = (
+ <>
+
+
+
+
+
+
+
+
+ >
+ );
+
+ return (
+
+ {showAnswerSection}
);
};
@@ -73,10 +100,14 @@ ShowAnswerCard.propTypes = {
intl: intlShape.isRequired,
// eslint-disable-next-line
showAnswer: PropTypes.any.isRequired,
+ solutionExplanation: PropTypes.string,
updateSettings: PropTypes.func.isRequired,
studioEndpointUrl: PropTypes.string.isRequired,
learningContextId: PropTypes.string.isRequired,
};
+ShowAnswerCard.defaultProps = {
+ solutionExplanation: '',
+};
export const mapStateToProps = (state) => ({
studioEndpointUrl: selectors.app.studioEndpointUrl(state),
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/ShowAnswerCard.test.jsx b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/ShowAnswerCard.test.jsx
index 63d2e2bfe..c4c5652e4 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/ShowAnswerCard.test.jsx
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/ShowAnswerCard.test.jsx
@@ -3,10 +3,10 @@ import { shallow } from 'enzyme';
import { formatMessage } from '../../../../../../../testUtils';
import { selectors } from '../../../../../../data/redux';
import { ShowAnswerCard, mapStateToProps, mapDispatchToProps } from './ShowAnswerCard';
-import { showAnswerCardHooks } from '../hooks';
+import { useAnswerSettings } from '../hooks';
jest.mock('../hooks', () => ({
- showAnswerCardHooks: jest.fn(),
+ useAnswerSettings: jest.fn(),
}));
jest.mock('../../../../../../data/redux', () => ({
@@ -34,17 +34,17 @@ describe('ShowAnswerCard', () => {
learningContextId: 'sOMEcouRseId',
};
- const showAnswerCardHooksProps = {
- handleShowAnswerChange: jest.fn().mockName('showAnswerCardHooks.handleShowAnswerChange'),
- handleAttemptsChange: jest.fn().mockName('showAnswerCardHooks.handleAttemptsChange'),
+ const useAnswerSettingsProps = {
+ handleShowAnswerChange: jest.fn().mockName('useAnswerSettings.handleShowAnswerChange'),
+ handleAttemptsChange: jest.fn().mockName('useAnswerSettings.handleAttemptsChange'),
};
- showAnswerCardHooks.mockReturnValue(showAnswerCardHooksProps);
+ useAnswerSettings.mockReturnValue(useAnswerSettingsProps);
describe('behavior', () => {
- it(' calls showAnswerCardHooks when initialized', () => {
+ it(' calls useAnswerSettings when initialized', () => {
shallow();
- expect(showAnswerCardHooks).toHaveBeenCalledWith(showAnswer, props.updateSettings);
+ expect(useAnswerSettings).toHaveBeenCalledWith(showAnswer, props.updateSettings);
});
});
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/HintsCard.test.jsx.snap b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/HintsCard.test.jsx.snap
index abecf5039..6a3700a8c 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/HintsCard.test.jsx.snap
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/HintsCard.test.jsx.snap
@@ -3,6 +3,7 @@
exports[`HintsCard snapshot snapshot: renders hints setting card multiple hints 1`] = `
@@ -65,7 +65,7 @@ exports[`ResetCard snapshot snapshot: renders reset true setting card 1`] = `
exports[`ResetCard snapshot snapshot: renders reset true setting card 2`] = `
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/ScoringCard.test.jsx.snap b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/ScoringCard.test.jsx.snap
index 6a28aa416..397b39802 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/ScoringCard.test.jsx.snap
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/ScoringCard.test.jsx.snap
@@ -3,7 +3,7 @@
exports[`ScoringCard snapshot snapshot: scoring setting card 1`] = `
@@ -52,7 +52,7 @@ exports[`ScoringCard snapshot snapshot: scoring setting card 1`] = `
exports[`ScoringCard snapshot snapshot: scoring setting card max attempts 1`] = `
@@ -101,7 +101,7 @@ exports[`ScoringCard snapshot snapshot: scoring setting card max attempts 1`] =
exports[`ScoringCard snapshot snapshot: scoring setting card zero zero weight 1`] = `
diff --git a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/ShowAnswerCard.test.jsx.snap b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/ShowAnswerCard.test.jsx.snap
index 18ebdbb3d..d16dbc7d8 100644
--- a/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/ShowAnswerCard.test.jsx.snap
+++ b/src/editors/containers/ProblemEditor/components/EditProblemView/SettingsWidget/settingsComponents/__snapshots__/ShowAnswerCard.test.jsx.snap
@@ -3,12 +3,38 @@
exports[`ShowAnswerCard snapshot snapshot: show answer setting card 1`] = `
+
+
+
+
+
+
+
+
+ ,
+ },
+ ]
+ }
summary="After Some Number of Attempts"
title="Show answer"
>
-
+