@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
710 lines (696 loc) • 33.3 kB
JavaScript
"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);