UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

710 lines (696 loc) • 33.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = require("react"); var _propTypes = _interopRequireDefault(require("prop-types")); var _concat = _interopRequireDefault(require("lodash/fp/concat")); var _find = _interopRequireDefault(require("lodash/fp/find")); var _get = _interopRequireDefault(require("lodash/get")); var _uuid = require("uuid"); var _immutabilityHelper = _interopRequireDefault(require("immutability-helper")); var _findIndex = _interopRequireDefault(require("lodash/findIndex")); var _omit = _interopRequireDefault(require("lodash/omit")); var _isEqual = _interopRequireDefault(require("lodash/isEqual")); var _escape = _interopRequireDefault(require("lodash/escape")); var _uiCheckbox = require("@instructure/ui-checkbox"); var _emotion = require("@instructure/emotion"); var _QuestionSettingsContainer = _interopRequireDefault(require("../../common/edit/components/QuestionSettingsContainer")); var _QuestionContainer = _interopRequireDefault(require("../../common/edit/components/QuestionContainer")); var _rich_fill_blank = _interopRequireDefault(require("../../../records/interactions/rich_fill_blank")); var _BlankTypeSelect = _interopRequireDefault(require("../../fill_blank/Edit/answer_field/BlankTypeSelect")); var _WordBankDistractors = _interopRequireDefault(require("./WordBankDistractors")); var _styles = _interopRequireDefault(require("./styles")); var _theme = _interopRequireDefault(require("./theme")); var _withEditTools = _interopRequireDefault(require("../../../util/withEditTools")); var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message")); var _QuestionSettingsPanel = _interopRequireDefault(require("../../common/edit/components/QuestionSettingsPanel")); var _CalculatorOptionWithOqaatAlert = _interopRequireDefault(require("../../common/edit/components/CalculatorOptionWithOqaatAlert")); var _uiA11yContent = require("@instructure/ui-a11y-content"); var _uiText = require("@instructure/ui-text"); var _quizCommon = require("@instructure/quiz-common"); var _dec, _class, _RichFillBlankEdit; /** @jsx jsx */ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _callSuper(_this, derived, args) { function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { return !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (e) { return false; } } derived = (0, _getPrototypeOf2["default"])(derived); return (0, _possibleConstructorReturn2["default"])(_this, isNativeReflectConstruct() ? Reflect.construct(derived, args || [], (0, _getPrototypeOf2["default"])(_this).constructor) : derived.apply(_this, args)); } /** --- category: RichFillInTheBlank --- Rich Fill in the Blank Edit component ```jsx_example function Example (props) { const exampleProps = { interactionData: { blanks: [{ answerType: 'openEntry', id: 'uuid-blank1' }, { answerType: 'openEntry', id: 'uuid-blank2' }, { answerType: 'openEntry', id: 'uuid-blank3' }, { answerType: 'openEntry', id: 'uuid-blank4' }, { answerType: 'openEntry', id: 'uuid-blank5' }, { answerType: 'dropdown', id: 'uuid-blank6', choices: [ { id: 'uuid6-choice1', position: 1, itemBody: 'with' }, { id: 'uuid6-choice2', position: 2, itemBody: 'on' }, { id: 'uuid6-choice3', position: 3, itemBody: 'which' } ] }, { answerType: 'wordbank', id: 'uuid-blank7', choices: [ { id: 'uuid7-choice1', position: 1, itemBody: 'bathwater' }, { id: 'uuid7-choice2', position: 2, itemBody: 'bathtub' }, { id: 'uuid7-choice3', position: 3, itemBody: 'water' } ] }] }, scoringData: { workingItemBody: "<p>`Don't` `throw` `the` `baby` `out` `with` the `bathwater`.</p>", value: [{ id: 'uuid-blank1', scoringAlgorithm: 'TextCloseEnough', scoringData: { blankText: 'Don\'t', editDistance: '1', ignoreCase: true, value: 'Don\'t' } }, { id: 'uuid-blank2', scoringAlgorithm: 'TextEquivalence', scoringData: { blankText: 'throw', value: 'throw' } }, { id: 'uuid-blank3', scoringAlgorithm: 'TextContainsAnswer', scoringData: { blankText: 'the', value: 'the' } }, { id: 'uuid-blank4', scoringAlgorithm: 'TextInChoices', scoringData: { blankText: 'baby', value: ['baby', 'kid', 'child'] } }, { id: 'uuid-blank5', scoringAlgorithm: 'TextRegex', scoringData: { blankText: 'out', value: 'out' } }, { id: 'uuid-blank6', scoringAlgorithm: 'Equivalence', scoringData: { blankText: 'with', value: 'uuid6-choice1' } }, { id: 'uuid-blank7', scoringAlgorithm: 'Equivalence', scoringData: { blankText: 'bathwater', value: 'uuid7-choice1' } }] } } return ( <RichFillBlankEdit {...exampleProps} {...props} /> ) } <SettingsSwitcher locales={LOCALES}> <EditStateProvider> <Example /> </EditStateProvider> </SettingsSwitcher> ``` **/ var RichFillBlankEdit = exports["default"] = (_dec = (0, _quizCommon.withStyleOverrides)(_styles["default"], _theme["default"]), (0, _withEditTools["default"])(_class = _dec(_class = (_RichFillBlankEdit = /*#__PURE__*/function (_Component) { function RichFillBlankEdit() { var _this2; (0, _classCallCheck2["default"])(this, RichFillBlankEdit); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this2 = _callSuper(this, RichFillBlankEdit, [].concat(args)); (0, _defineProperty2["default"])(_this2, "validBlankRegex", function () { return new RegExp(_this2.props.interactionType.validBlankRegex, 'g'); }); // Other edit components use the `getErrors` helper passed in from the // withEditTools higher-order component, but fill blank has its own error // handling logic (0, _defineProperty2["default"])(_this2, "getErrors", function (path) { if (_this2.props.errorsAreShowing) { return (0, _get["default"])(_this2.props.errors, path, null); } return null; }); (0, _defineProperty2["default"])(_this2, "blankValues", function () { return (_this2.props.scoringData.value || []).map(function (blankValue) { return blankValue.scoringData.blankText; }); }); (0, _defineProperty2["default"])(_this2, "arrayDiff", function (arr1, arr2) { // items in arr1 that are not in arr2 (accounting for duplicate items) // examples (arr1 - arr2 = return): // [a,b,c] - [a] = [b,c] // [a,a,b] - [a] = [a,b] // [a,b] - [b,c] = [a] var arr1Copy = (0, _toConsumableArray2["default"])(arr1); arr2.forEach(function (blank) { var blankIndex = arr1Copy.indexOf(blank); if (blankIndex > -1) { arr1Copy.splice(blankIndex, 1); } }); return arr1Copy; }); (0, _defineProperty2["default"])(_this2, "defaultBlankScoringData", function (blankValue, id) { return { id: id, scoringAlgorithm: 'TextContainsAnswer', scoringData: { value: blankValue, blankText: blankValue } }; }); (0, _defineProperty2["default"])(_this2, "defaultBlankInteractionData", function (blankValue, id) { return { id: id, answerType: 'openEntry' }; }); (0, _defineProperty2["default"])(_this2, "updateScoringDataBlankTexts", function (scoringDataValue, interactionDataBlankValues, blankMatches) { return scoringDataValue.map(function (scoringDataBlankValue, i) { var prevBlankText = scoringDataBlankValue.scoringData.blankText; var newBlankText = blankMatches[i]; if (prevBlankText === newBlankText) { return scoringDataBlankValue; } var scoringAlgorithm = scoringDataBlankValue.scoringAlgorithm; var answerType = interactionDataBlankValues[i].answerType; var scoringDataMods = { blankText: blankMatches[i] }; if (answerType === 'openEntry') { if (['TextRegex', 'TextContainsAnswer', 'TextEquivalence', 'Equivalence', 'TextCloseEnough'].includes(scoringAlgorithm)) { scoringDataMods.value = blankMatches[i]; } else if (scoringAlgorithm === 'TextInChoices') { scoringDataMods.value = scoringDataBlankValue.scoringData.value; scoringDataMods.value[0] = blankMatches[i]; } } if (answerType === 'wordbank' && scoringDataBlankValue.scoringData.choiceId) { scoringDataMods.value = blankMatches[i]; } return _objectSpread(_objectSpread({}, scoringDataBlankValue), {}, { scoringData: _objectSpread(_objectSpread({}, scoringDataBlankValue.scoringData), scoringDataMods) }); }); }); (0, _defineProperty2["default"])(_this2, "updateInteractionDataBlankTexts", function (interactionDataBlankValues, newScoringDataValue, blankMatches) { return interactionDataBlankValues.map(function (interactionDataBlankValue, i) { if (['dropdown', 'wordbank'].includes(interactionDataBlankValue.answerType)) { var choices = interactionDataBlankValue.choices; var blankId = interactionDataBlankValue.id; var blankScoringDataValue = newScoringDataValue.find(function (value) { return value.id === blankId; }); if (choices && blankScoringDataValue) { var correctChoiceIdx = choices.findIndex(function (choice) { return choice.id === blankScoringDataValue.scoringData.value; }); choices[correctChoiceIdx].itemBody = blankMatches[i]; } return _objectSpread(_objectSpread({}, interactionDataBlankValue), choices && { choices: choices }); } return interactionDataBlankValue; }); }); (0, _defineProperty2["default"])(_this2, "updateWordBankChoicesTexts", function (wordBankChoices, scoringDataValue) { if (!wordBankChoices) return; return wordBankChoices.map(function (wordBankChoice) { var choiceScoringData = scoringDataValue.find(function (scoringData) { return scoringData.scoringData.choiceId === wordBankChoice.id; }); return _objectSpread(_objectSpread({}, wordBankChoice), choiceScoringData && { itemBody: choiceScoringData.scoringData.blankText }); }); }); (0, _defineProperty2["default"])(_this2, "indexForWordBankChoice", function (choiceId) { return (0, _findIndex["default"])(_this2.props.interactionData.wordBankChoices, function (wordBankChoice) { return wordBankChoice.id === choiceId; }); }); (0, _defineProperty2["default"])(_this2, "makeNewProperties", function (interactionData) { // syncs shuffling properties data with new interaction data. // this runs each time we changeItemState so that we dont have // to manage syncing properties and interactionData on each individual // change to blank type or blank creation/deletion var blankRules = interactionData.blanks.reduce(function (memo, blank, blankIndex) { // eslint-disable-next-line no-param-reassign memo[blankIndex] = blank.answerType === 'openEntry' ? { children: null } : { children: { choices: { shuffled: true } } }; return memo; }, {}); var newShuffleRules = { shuffleRules: { blanks: { children: blankRules } } }; return Object.assign({}, _this2.props.properties, newShuffleRules); }); (0, _defineProperty2["default"])(_this2, "changeItemState", function (modifications, blankId) { var newestIntData = Object.assign({}, _this2.props.interactionData, modifications.interactionData); var newProperties = _this2.makeNewProperties(newestIntData); var newMods = { properties: newProperties }; if (modifications.scoringData) { newMods.scoringData = modifications.scoringData; } var newModifications = Object.assign({}, modifications, newMods); _this2.props.changeItemState(newModifications, blankId); }); (0, _defineProperty2["default"])(_this2, "insert", function (arr, index) { for (var _len2 = arguments.length, newItems = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { newItems[_key2 - 2] = arguments[_key2]; } return [].concat((0, _toConsumableArray2["default"])(arr.slice(0, index)), newItems, (0, _toConsumableArray2["default"])(arr.slice(index))); }); (0, _defineProperty2["default"])(_this2, "blankIdsFromValues", function (removedBlanks) { var blankIds = []; var scoringDataValue = (0, _toConsumableArray2["default"])(_this2.props.scoringData.value); removedBlanks.forEach(function (blank) { var blankValueIndex = scoringDataValue.findIndex(function (blankValue) { return blankValue.scoringData.blankText === blank; }); if (blankValueIndex > -1) { blankIds.push(scoringDataValue[blankValueIndex].id); scoringDataValue.splice(blankValueIndex, 1); } }); return blankIds; }); // ================ // HANDLERS // ================ (0, _defineProperty2["default"])(_this2, "handleCheckboxChange", function (event) { var interactionData = (0, _immutabilityHelper["default"])(_this2.props.interactionData, (0, _defineProperty2["default"])({}, event.target.value, { $set: !_this2.props.interactionData[event.target.value] })); _this2.changeItemState({ interactionData: interactionData }); }); (0, _defineProperty2["default"])(_this2, "handleCalculatorTypeChange", function (e, value) { _this2.changeItemState({ calculatorType: value }); }); (0, _defineProperty2["default"])(_this2, "updateScoringDataForBlank", function (blankId) { return function (scoringDataMods) { var indexForBlank = _this2.indexForBlank(blankId); var workingItemBody = _this2.props.scoringData.workingItemBody; var index = 0; var newWorkingItemBody = workingItemBody.replace(_this2.validBlankRegex(), function (match) { return index++ === indexForBlank ? "`".concat((0, _escape["default"])(scoringDataMods.scoringData.blankText), "`") : match; }); var scoringData = (0, _immutabilityHelper["default"])(_this2.props.scoringData, { workingItemBody: { $set: newWorkingItemBody }, value: (0, _defineProperty2["default"])({}, indexForBlank, { $merge: scoringDataMods }) }); var interactionData = _this2.props.interactionData; // if the text of a wordbank choice was updated, // reflect the change in the wordBankChoices list if (scoringDataMods.scoringData.choiceId && _this2.props.interactionData.wordBankChoices) { var wordBankChoiceIndex = _this2.indexForWordBankChoice(scoringDataMods.scoringData.choiceId); if (wordBankChoiceIndex > -1) { interactionData = (0, _immutabilityHelper["default"])(interactionData, { wordBankChoices: (0, _defineProperty2["default"])({}, wordBankChoiceIndex, { itemBody: { $set: scoringDataMods.scoringData.blankText } }) }); } } _this2.changeItemState({ scoringData: scoringData, interactionData: interactionData }, blankId); }; }); // Setting choices to null will remove the choice from the blank. This is necessary // because when switching between blank types we need a way to remove the choices // data from the interactionData since it won't be relevant to the new type (not // to mention that leaving it will expose the openEntry's answer) (0, _defineProperty2["default"])(_this2, "updateBlank", function (blankId) { return function (modifications) { var indexForBlank = _this2.indexForBlank(blankId); var blankData = _this2.props.interactionData.blanks[indexForBlank]; var mods = modifications; if (modifications.choices === null) { mods = (0, _omit["default"])(modifications, ['choices']); blankData = (0, _omit["default"])(_this2.props.interactionData.blanks[indexForBlank], ['choices']); } // if there's a new wordbank choice, add it to the wordBankChoice list var wordBankChoicesMods; if (modifications.choice) { wordBankChoicesMods = (0, _immutabilityHelper["default"])(_this2.props.interactionData.wordBankChoices || [{ id: (0, _uuid.v4)(), itemBody: '' }], { $push: [modifications.choice] }); } // omit "choice" because "choice" is added to wordBankChoices, not the blank itself mods = (0, _omit["default"])(modifications, ['choice']); var finalMods = (0, _immutabilityHelper["default"])(blankData, { $merge: mods }); var interactionData = (0, _immutabilityHelper["default"])(_this2.props.interactionData, _objectSpread({ blanks: (0, _defineProperty2["default"])({}, indexForBlank, { $set: finalMods }) }, wordBankChoicesMods && { wordBankChoices: { $set: wordBankChoicesMods } })); // if the blank no longer has answerType "wordbank", // remove the choice from wordBankChoices var noLongerWordbank = blankData.answerType === 'wordbank' && modifications.answerType && modifications.answerType !== 'wordbank'; if (noLongerWordbank && interactionData.wordBankChoices) { var scoringDataForBlank = _this2.props.scoringData.value[indexForBlank]; var wordBankChoiceIndex = _this2.indexForWordBankChoice(scoringDataForBlank.scoringData.choiceId); interactionData = (0, _immutabilityHelper["default"])(interactionData, { wordBankChoices: { $splice: [[wordBankChoiceIndex, 1]] } }); } // if there are aren't any wordbank blanks, // clear out wordBankChoices list if (!interactionData.blanks.some(function (blank) { return blank.answerType === 'wordbank'; })) { interactionData = (0, _immutabilityHelper["default"])(interactionData, { $unset: ['wordBankChoices'] }); } _this2.changeItemState({ interactionData: interactionData }, blankId); }; }); (0, _defineProperty2["default"])(_this2, "handleDescriptionChange", function (itemBody) { var blankMatches = (itemBody.match(_this2.validBlankRegex()) || []).map(function (match) { return _this2.htmlDecode(match.slice(1, -1)); }); var knownBlanks = _this2.blankValues(); var newScoringDataValue = _this2.props.scoringData.value || []; var newInteractionDataBlanks = _this2.props.interactionData.blanks || []; var newWordBankChoices = _this2.props.interactionData.wordBankChoices; var updateBlankTexts = function updateBlankTexts() { newScoringDataValue = _this2.updateScoringDataBlankTexts(newScoringDataValue, newInteractionDataBlanks, blankMatches); newInteractionDataBlanks = _this2.updateInteractionDataBlankTexts(newInteractionDataBlanks, newScoringDataValue, blankMatches); newWordBankChoices = _this2.updateWordBankChoicesTexts(newWordBankChoices, newScoringDataValue); }; if (blankMatches.length === knownBlanks.length) { // update blank values (may or may not have changed) updateBlankTexts(); } else { // remove any removed blanks var removedBlanks = _this2.arrayDiff(knownBlanks, blankMatches); var removedBlankIds = _this2.blankIdsFromValues(removedBlanks); var removedWordBankChoiceIds = []; newScoringDataValue = newScoringDataValue.filter(function (blankValue) { if (removedBlankIds.includes(blankValue.id) && blankValue.scoringData.choiceId) { removedWordBankChoiceIds.push(blankValue.scoringData.choiceId); } return !removedBlankIds.includes(blankValue.id); }); newInteractionDataBlanks = newInteractionDataBlanks.filter(function (blankValue) { return !removedBlankIds.includes(blankValue.id); }); if (newWordBankChoices) { newWordBankChoices = newWordBankChoices.filter(function (wordBankChoice) { return !removedWordBankChoiceIds.includes(wordBankChoice.id); }); // if there are aren't any wordbank blanks, clear out wordBankChoices list if (!newInteractionDataBlanks.some(function (blank) { return blank.answerType === 'wordbank'; })) { newWordBankChoices = null; } } // add any newly added blanks var newBlanks = _this2.arrayDiff(blankMatches, knownBlanks); newBlanks.forEach(function (newBlank) { var id = (0, _uuid.v4)(); var index = blankMatches.indexOf(newBlank); newScoringDataValue = _this2.insert(newScoringDataValue, index, _this2.defaultBlankScoringData(newBlank, id)); newInteractionDataBlanks = _this2.insert(newInteractionDataBlanks, index, _this2.defaultBlankInteractionData(newBlank, id)); }); } // There are many ways for the scoringData/interactionData to get desynced from what the RCE shows, // especially considering we allow blanks to have duplicate blankText, and users can change // multiple blanks at once by pasting anything in the RCE. This check is intended as a failsafe. // If the blankTexts don't match what's in the RCE, just force them to match. var blankTexts = newScoringDataValue.map(function (blankValue) { return blankValue.scoringData.blankText; }); if (!(0, _isEqual["default"])(blankTexts, blankMatches)) { updateBlankTexts(); } _this2.props.changeItemState({ interactionData: _objectSpread({ blanks: newInteractionDataBlanks }, newWordBankChoices && { wordBankChoices: newWordBankChoices }), scoringData: { workingItemBody: itemBody, value: newScoringDataValue } }); }); (0, _defineProperty2["default"])(_this2, "renderExplanation", function () { return (0, _emotion.jsx)(_quizCommon.Flex, { direction: "column", padding: "0 0 small 0" }, (0, _emotion.jsx)(_uiText.Text, null, (0, _formatMessage["default"])('Type a statement and surround a word with backticks to indicate where a student will fill in the answer.'))); }); return _this2; } (0, _inherits2["default"])(RichFillBlankEdit, _Component); return (0, _createClass2["default"])(RichFillBlankEdit, [{ key: "indexForBlank", value: function indexForBlank(blankId) { return (0, _findIndex["default"])(this.props.interactionData.blanks, function (blank) { return blank.id === blankId; }); } }, { key: "htmlDecode", value: function htmlDecode(input) { var doc = new DOMParser().parseFromString(input, 'text/html'); return doc.documentElement.textContent; } }, { key: "renderBlanksOptions", value: // ============= // RENDERING // ============= function renderBlanksOptions() { var _this3 = this; var hasIndividualWordBanks = this.props.interactionData.blanks.some(function (blank) { return blank.answerType === 'wordbank' && blank.choices && blank.choices.length; }); return this.props.interactionData.blanks.map(function (blank, blankIndex) { var blankScoringData = (0, _find["default"])({ id: blank.id }, _this3.props.scoringData.value) || {}; var choicesErrors = (0, _concat["default"])(_this3.getErrors("scoringData.value[".concat(blankIndex, "].scoringData.value.$errors")) || [], _this3.getErrors("interactionData.blanks[".concat(blankIndex, "].choices.$errors")) || []); return (0, _emotion.jsx)(_BlankTypeSelect["default"], { key: blank.id, answerType: blank.answerType, blankPosition: blankIndex + 1, blankScoringAlgorithm: blankScoringData.scoringAlgorithm, blankScoringData: blankScoringData.scoringData, choices: blank.choices, disabled: _this3.props.overrideEditableForRegrading, interactionDataErrors: _this3.getErrors("interactionData.blanks[".concat(blankIndex, "]")) || {}, name: blank.id, notifyScreenreader: _this3.props.notifyScreenreader, onModalClose: _this3.props.onModalClose, onModalOpen: _this3.props.onModalOpen, scoringDataErrors: _this3.getErrors("scoringData.value[".concat(blankIndex, "].scoringData")) || {}, choicesErrors: choicesErrors, validationErrorsFromApi: _this3.props.validationErrorsFromApi[blank.id] || [], wordBankChoices: _this3.props.interactionData.wordBankChoices, updateBlank: _this3.updateBlank(blank.id), updateBlankScoringData: _this3.updateScoringDataForBlank(blank.id), useCommonWordbank: _this3.props.fitbCommonWordbankEnabled && !hasIndividualWordBanks }); }); } }, { key: "renderOptionsDescription", value: function renderOptionsDescription() { return (0, _emotion.jsx)(_uiA11yContent.ScreenReaderContent, null, (0, _formatMessage["default"])('Fill in the blank options')); } }, { key: "render", value: function render() { var stemErrors = this.getErrors('scoringData.workingItemBody') || []; var blankErrors = this.getErrors(['interactionData', 'blanks', '$errors']) || []; return (0, _emotion.jsx)("div", null, this.renderExplanation(), (0, _emotion.jsx)(_QuestionContainer["default"], { disabled: this.props.overrideEditableForRegrading, enableRichContentEditor: this.props.enableRichContentEditor, itemBody: this.props.scoringData.workingItemBody, onDescriptionChange: this.handleDescriptionChange, onModalClose: this.props.onModalClose, onModalOpen: this.props.onModalOpen, openImportModal: this.props.openImportModal, stemErrors: stemErrors.concat(blankErrors) || [] }, this.renderBlanksOptions(), (0, _emotion.jsx)(_WordBankDistractors["default"], { changeItemState: this.props.changeItemState, indexForWordBankChoice: this.indexForWordBankChoice, interactionData: this.props.interactionData, interactionDataErrors: this.getErrors('interactionData.wordBankChoices') || {}, notifyScreenreader: this.props.notifyScreenreader, onModalClose: this.props.onModalClose, onModalOpen: this.props.onModalOpen, overrideEditableForRegrading: this.props.overrideEditableForRegrading, scoringData: this.props.scoringData })), (0, _emotion.jsx)(_QuestionSettingsContainer["default"], { additionalOptions: this.props.additionalOptions }, (0, _emotion.jsx)(_QuestionSettingsPanel["default"], { label: (0, _formatMessage["default"])('Options'), defaultExpanded: true }, (0, _emotion.jsx)(_quizCommon.FormFieldGroup, { rowSpacing: "small", description: this.renderOptionsDescription() }, this.props.interactionData.wordBankChoices && (0, _emotion.jsx)(_uiCheckbox.Checkbox, { label: (0, _formatMessage["default"])('Allow word bank choices to be reused'), value: "reuseWordBankChoices", onChange: this.handleCheckboxChange, checked: this.props.interactionData.reuseWordBankChoices, disabled: this.props.overrideEditableForRegrading }), this.props.showCalculatorOption && (0, _emotion.jsx)(_CalculatorOptionWithOqaatAlert["default"], { disabled: this.props.overrideEditableForRegrading, calculatorValue: this.props.calculatorType, onCalculatorTypeChange: this.handleCalculatorTypeChange, oqaatChecked: this.props.oneQuestionAtATime, onOqaatChange: this.props.setOneQuestionAtATime }))))); } }]); }(_react.Component), (0, _defineProperty2["default"])(_RichFillBlankEdit, "displayName", 'RichFillBlankEdit'), (0, _defineProperty2["default"])(_RichFillBlankEdit, "componentId", "Quizzes".concat(_RichFillBlankEdit.displayName)), (0, _defineProperty2["default"])(_RichFillBlankEdit, "interactionType", _rich_fill_blank["default"]), (0, _defineProperty2["default"])(_RichFillBlankEdit, "propTypes", { additionalOptions: _propTypes["default"].array, calculatorType: _propTypes["default"].string, changeItemState: _propTypes["default"].func.isRequired, enableRichContentEditor: _propTypes["default"].bool, errors: _propTypes["default"].object, errorsAreShowing: _propTypes["default"].bool, fitbCommonWordbankEnabled: _propTypes["default"].bool, interactionData: _propTypes["default"].object.isRequired, interactionType: _propTypes["default"].shape({ validBlankRegex: _propTypes["default"].string }).isRequired, notifyScreenreader: _propTypes["default"].func.isRequired, onModalClose: _propTypes["default"].func, onModalOpen: _propTypes["default"].func, oneQuestionAtATime: _propTypes["default"].bool, openImportModal: _propTypes["default"].func, overrideEditableForRegrading: _propTypes["default"].bool, properties: _propTypes["default"].shape({ shuffleRules: _propTypes["default"].shape({ blanks: _propTypes["default"].shape({ children: _propTypes["default"].object }) }) }), scoringData: _propTypes["default"].object.isRequired, setOneQuestionAtATime: _propTypes["default"].func, validationErrorsFromApi: _propTypes["default"].object, styles: _propTypes["default"].object, showCalculatorOption: _propTypes["default"].bool }), (0, _defineProperty2["default"])(_RichFillBlankEdit, "defaultProps", { calculatorType: 'none', enableRichContentEditor: true, fitbCommonWordbankEnabled: false, oneQuestionAtATime: false, overrideEditableForRegrading: false, setOneQuestionAtATime: Function.prototype, additionalOptions: void 0, errors: void 0, errorsAreShowing: void 0, onModalClose: void 0, onModalOpen: void 0, openImportModal: void 0, properties: {}, scoringData: void 0, validationErrorsFromApi: {}, showCalculatorOption: true }), _RichFillBlankEdit)) || _class) || _class);