@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
703 lines (702 loc) • 32.1 kB
JavaScript
/** @jsx jsx */ function _array_like_to_array(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
return arr2;
}
function _array_without_holes(arr) {
if (Array.isArray(arr)) return _array_like_to_array(arr);
}
function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _iterable_to_array(iter) {
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _non_iterable_spread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _object_spread(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
_define_property(target, key, source[key]);
});
}
return target;
}
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 _object_spread_props(target, source) {
source = source != null ? source : {};
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 _object_without_properties(source, excluded) {
if (source == null) return {};
var target = _object_without_properties_loose(source, excluded);
var key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for(i = 0; i < sourceSymbolKeys.length; i++){
key = sourceSymbolKeys[i];
if (excluded.indexOf(key) >= 0) continue;
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
target[key] = source[key];
}
}
return target;
}
function _object_without_properties_loose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for(i = 0; i < sourceKeys.length; i++){
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _to_consumable_array(arr) {
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
}
function _unsupported_iterable_to_array(o, minLen) {
if (!o) return;
if (typeof o === "string") return _array_like_to_array(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
}
import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import concat from 'lodash/fp/concat';
import find from 'lodash/fp/find';
import get from 'lodash/get';
import { v4 as uuid } from 'uuid';
import update from 'immutability-helper';
import isEqual from 'lodash/isEqual';
import escape from 'lodash/escape';
import { Checkbox } from '@instructure/ui-checkbox';
import { jsx } from '@instructure/emotion';
import QuestionSettingsContainer from '../../common/edit/components/QuestionSettingsContainer';
import QuestionContainer from '../../common/edit/components/QuestionContainer';
import RichFillBlankInteractionType from '../../../records/interactions/rich_fill_blank';
import BlankTypeSelect from '../../fill_blank/Edit/answer_field/BlankTypeSelect';
import WordBankDistractors from './WordBankDistractors';
import generateStyle from './styles';
import generateComponentTheme from './theme';
import withEditTools from '../../../util/withEditTools';
import t from '@instructure/quiz-i18n/format-message';
import QuestionSettingsPanel from '../../common/edit/components/QuestionSettingsPanel';
import CalculatorOptionWithOqaatAlert from '../../common/edit/components/CalculatorOptionWithOqaatAlert';
import { ScreenReaderContent } from '@instructure/ui-a11y-content';
import { Text } from '@instructure/ui-text';
import { Flex, withStyleOverrides, FormFieldGroup } from '@instructure/quiz-common';
function BlanksOptions(param) {
var blanks = param.blanks, scoringDataValue = param.scoringDataValue, fitbCommonWordbankEnabled = param.fitbCommonWordbankEnabled, overrideEditableForRegrading = param.overrideEditableForRegrading, wordBankChoices = param.wordBankChoices, notifyScreenreader = param.notifyScreenreader, onModalClose = param.onModalClose, onModalOpen = param.onModalOpen, validationErrorsFromApi = param.validationErrorsFromApi, getErrors = param.getErrors, updateBlank = param.updateBlank, updateScoringDataForBlank = param.updateScoringDataForBlank, isSurvey = param.isSurvey;
var hasIndividualWordBanks = blanks.some(function(blank) {
return blank.answerType === 'wordbank' && blank.choices && blank.choices.length;
});
return blanks.map(function(blank, blankIndex) {
var blankScoringData = find({
id: blank.id
}, scoringDataValue) || {};
var choicesErrors = concat(getErrors("scoringData.value[".concat(blankIndex, "].scoringData.value.$errors")) || [], getErrors("interactionData.blanks[".concat(blankIndex, "].choices.$errors")) || []);
return /*#__PURE__*/ jsx(BlankTypeSelect, {
key: blank.id,
answerType: blank.answerType,
blankPosition: blankIndex + 1,
blankScoringAlgorithm: blankScoringData.scoringAlgorithm,
blankScoringData: blankScoringData.scoringData,
choices: blank.choices,
disabled: overrideEditableForRegrading,
interactionDataErrors: getErrors("interactionData.blanks[".concat(blankIndex, "]")) || {},
name: blank.id,
notifyScreenreader: notifyScreenreader,
onModalClose: onModalClose,
onModalOpen: onModalOpen,
scoringDataErrors: getErrors("scoringData.value[".concat(blankIndex, "].scoringData")) || {},
choicesErrors: choicesErrors,
validationErrorsFromApi: validationErrorsFromApi[blank.id] || [],
wordBankChoices: wordBankChoices,
updateBlank: updateBlank(blank.id),
updateBlankScoringData: updateScoringDataForBlank(blank.id),
useCommonWordbank: fitbCommonWordbankEnabled && !hasIndividualWordBanks,
isSurvey: isSurvey
});
});
}
BlanksOptions.propTypes = {
blanks: PropTypes.array.isRequired,
scoringDataValue: PropTypes.array,
fitbCommonWordbankEnabled: PropTypes.bool,
overrideEditableForRegrading: PropTypes.bool,
wordBankChoices: PropTypes.array,
notifyScreenreader: PropTypes.func.isRequired,
onModalClose: PropTypes.func,
onModalOpen: PropTypes.func,
validationErrorsFromApi: PropTypes.object,
getErrors: PropTypes.func.isRequired,
updateBlank: PropTypes.func.isRequired,
updateScoringDataForBlank: PropTypes.func.isRequired,
isSurvey: PropTypes.bool
};
var RichFillBlankEdit = /*#__PURE__*/ React.forwardRef(function(props, ref) {
var validBlankRegex = useMemo(function() {
return new RegExp(props.interactionType.validBlankRegex, 'g');
}, [
props.interactionType.validBlankRegex
]);
// Other edit components use the `getErrors` helper passed in from the
// withEditTools higher-order component, but fill blank has its own error
// handling logic
var getErrors = function(path) {
if (props.errorsAreShowing) {
return get(props.errors, path, null);
}
return null;
};
var blankValues = function() {
return (props.scoringData.value || []).map(function(blankValue) {
return blankValue.scoringData.blankText;
});
};
var 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 = _to_consumable_array(arr1);
arr2.forEach(function(blank) {
var blankIndex = arr1Copy.indexOf(blank);
if (blankIndex > -1) {
arr1Copy.splice(blankIndex, 1);
}
});
return arr1Copy;
};
var defaultBlankScoringData = function(blankValue, id) {
return {
id: id,
scoringAlgorithm: 'TextContainsAnswer',
scoringData: {
value: blankValue,
blankText: blankValue
}
};
};
var defaultBlankInteractionData = function(blankValue, id) {
return {
id: id,
answerType: 'openEntry'
};
};
var 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 _object_spread_props(_object_spread({}, scoringDataBlankValue), {
scoringData: _object_spread({}, scoringDataBlankValue.scoringData, scoringDataMods)
});
});
};
var 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 _object_spread({}, interactionDataBlankValue, choices && {
choices: choices
});
}
return interactionDataBlankValue;
});
};
var 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 _object_spread({}, wordBankChoice, choiceScoringData && {
itemBody: choiceScoringData.scoringData.blankText
});
});
};
var insert = function(arr, index) {
for(var _len = arguments.length, newItems = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++){
newItems[_key - 2] = arguments[_key];
}
return _to_consumable_array(arr.slice(0, index)).concat(_to_consumable_array(newItems), _to_consumable_array(arr.slice(index)));
};
var blankIdsFromValues = function(removedBlanks) {
var blankIds = [];
var scoringDataValue = _to_consumable_array(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;
};
function indexForBlank(blankId) {
return props.interactionData.blanks.findIndex(function(blank) {
return blank.id === blankId;
});
}
var indexForWordBankChoice = function(choiceId) {
return props.interactionData.wordBankChoices.findIndex(function(wordBankChoice) {
return wordBankChoice.id === choiceId;
});
};
var 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({}, props.properties, newShuffleRules);
};
var changeItemState = function(modifications, blankId) {
var newestIntData = Object.assign({}, props.interactionData, modifications.interactionData);
var newProperties = makeNewProperties(newestIntData);
var newMods = {
properties: newProperties
};
if (modifications.scoringData) {
newMods.scoringData = modifications.scoringData;
}
var newModifications = Object.assign({}, modifications, newMods);
props.changeItemState(newModifications, blankId);
};
// ================
// HANDLERS
// ================
var handleCheckboxChange = function(event) {
var interactionData = update(props.interactionData, _define_property({}, event.target.value, {
$set: !props.interactionData[event.target.value]
}));
changeItemState({
interactionData: interactionData
});
};
var handleCalculatorTypeChange = function(e, value) {
changeItemState({
calculatorType: value
});
};
var updateScoringDataForBlank = function(blankId) {
return function(scoringDataMods) {
var indexForBlankValue = indexForBlank(blankId);
var workingItemBody = props.scoringData.workingItemBody;
var index = 0;
var newWorkingItemBody = workingItemBody.replace(validBlankRegex, function(match) {
return index++ === indexForBlankValue ? "`".concat(escape(scoringDataMods.scoringData.blankText), "`") : match;
});
var scoringData = update(props.scoringData, {
workingItemBody: {
$set: newWorkingItemBody
},
value: _define_property({}, indexForBlankValue, {
$merge: scoringDataMods
})
});
var interactionData = props.interactionData;
// if the text of a wordbank choice was updated,
// reflect the change in the wordBankChoices list
if (scoringDataMods.scoringData.choiceId && props.interactionData.wordBankChoices) {
var wordBankChoiceIndex = indexForWordBankChoice(scoringDataMods.scoringData.choiceId);
if (wordBankChoiceIndex > -1) {
interactionData = update(interactionData, {
wordBankChoices: _define_property({}, wordBankChoiceIndex, {
itemBody: {
$set: scoringDataMods.scoringData.blankText
}
})
});
}
}
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)
var updateBlank = function(blankId) {
return function(modifications) {
var indexForBlankValue = indexForBlank(blankId);
var blankData = props.interactionData.blanks[indexForBlankValue];
var mods = modifications;
if (modifications.choices === null) {
var _ = modifications.choices, modsWithoutChoices = _object_without_properties(modifications, [
"choices"
]);
mods = modsWithoutChoices;
var _props_interactionData_blanks_indexForBlankValue = props.interactionData.blanks[indexForBlankValue], __ = _props_interactionData_blanks_indexForBlankValue.choices, blankDataWithoutChoices = _object_without_properties(_props_interactionData_blanks_indexForBlankValue, [
"choices"
]);
blankData = blankDataWithoutChoices;
}
// if there's a new wordbank choice, add it to the wordBankChoice list
var wordBankChoicesMods;
if (modifications.choice) {
wordBankChoicesMods = update(props.interactionData.wordBankChoices || [
{
id: uuid(),
itemBody: ''
}
], {
$push: [
modifications.choice
]
});
}
// omit "choice" because "choice" is added to wordBankChoices, not the blank itself
var ___ = modifications.choice, modsWithoutChoice = _object_without_properties(modifications, [
"choice"
]);
mods = modsWithoutChoice;
var finalMods = update(blankData, {
$merge: mods
});
var interactionData = update(props.interactionData, _object_spread({
blanks: _define_property({}, indexForBlankValue, {
$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 = props.scoringData.value[indexForBlankValue];
var wordBankChoiceIndex = indexForWordBankChoice(scoringDataForBlank.scoringData.choiceId);
interactionData = update(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 = update(interactionData, {
$unset: [
'wordBankChoices'
]
});
}
changeItemState({
interactionData: interactionData
}, blankId);
};
};
var htmlDecode = function(input) {
var doc = new DOMParser().parseFromString(input, 'text/html');
return doc.documentElement.textContent;
};
var handleDescriptionChange = function(itemBody) {
var blankMatches = (itemBody.match(validBlankRegex) || []).map(function(match) {
return htmlDecode(match.slice(1, -1));
});
var knownBlanks = blankValues();
var newScoringDataValue = props.scoringData.value || [];
var newInteractionDataBlanks = props.interactionData.blanks || [];
var newWordBankChoices = props.interactionData.wordBankChoices;
var updateBlankTexts = function() {
newScoringDataValue = updateScoringDataBlankTexts(newScoringDataValue, newInteractionDataBlanks, blankMatches);
newInteractionDataBlanks = updateInteractionDataBlankTexts(newInteractionDataBlanks, newScoringDataValue, blankMatches);
newWordBankChoices = 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 = arrayDiff(knownBlanks, blankMatches);
var removedBlankIds = 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 = arrayDiff(blankMatches, knownBlanks);
newBlanks.forEach(function(newBlank) {
var id = uuid();
var index = blankMatches.indexOf(newBlank);
newScoringDataValue = insert(newScoringDataValue, index, defaultBlankScoringData(newBlank, id));
newInteractionDataBlanks = insert(newInteractionDataBlanks, index, 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 (!isEqual(blankTexts, blankMatches)) {
updateBlankTexts();
}
props.changeItemState({
interactionData: _object_spread({
blanks: newInteractionDataBlanks
}, newWordBankChoices && {
wordBankChoices: newWordBankChoices
}),
scoringData: {
workingItemBody: itemBody,
value: newScoringDataValue
}
});
};
var stemErrors = getErrors('scoringData.workingItemBody') || [];
var blankErrors = getErrors([
'interactionData',
'blanks',
'$errors'
]) || [];
return /*#__PURE__*/ jsx("div", {
ref: ref
}, /*#__PURE__*/ jsx(Flex, {
direction: "column",
padding: "0 0 small 0"
}, /*#__PURE__*/ jsx(Text, null, t('Type a statement and surround a word with backticks to indicate where a student will fill in the answer. (e.g., "Roses are `red`, violets are `blue`")'))), /*#__PURE__*/ jsx(QuestionContainer, {
disabled: props.overrideEditableForRegrading,
enableRichContentEditor: props.enableRichContentEditor,
itemBody: props.scoringData.workingItemBody,
onDescriptionChange: handleDescriptionChange,
onModalClose: props.onModalClose,
onModalOpen: props.onModalOpen,
openImportModal: props.openImportModal,
stemErrors: stemErrors.concat(blankErrors) || []
}, /*#__PURE__*/ jsx(BlanksOptions, {
blanks: props.interactionData.blanks,
scoringDataValue: props.scoringData.value,
fitbCommonWordbankEnabled: props.fitbCommonWordbankEnabled,
overrideEditableForRegrading: props.overrideEditableForRegrading,
wordBankChoices: props.interactionData.wordBankChoices,
notifyScreenreader: props.notifyScreenreader,
onModalClose: props.onModalClose,
onModalOpen: props.onModalOpen,
validationErrorsFromApi: props.validationErrorsFromApi,
getErrors: getErrors,
updateBlank: updateBlank,
updateScoringDataForBlank: updateScoringDataForBlank,
isSurvey: props.isSurvey
}), /*#__PURE__*/ jsx(WordBankDistractors, {
changeItemState: props.changeItemState,
indexForWordBankChoice: indexForWordBankChoice,
interactionData: props.interactionData,
interactionDataErrors: getErrors('interactionData.wordBankChoices') || {},
notifyScreenreader: props.notifyScreenreader,
onModalClose: props.onModalClose,
onModalOpen: props.onModalOpen,
overrideEditableForRegrading: props.overrideEditableForRegrading,
scoringData: props.scoringData,
isSurvey: props.isSurvey
})), /*#__PURE__*/ jsx(QuestionSettingsContainer, {
additionalOptions: props.additionalOptions
}, /*#__PURE__*/ jsx(QuestionSettingsPanel, {
label: t('Options'),
defaultExpanded: true
}, /*#__PURE__*/ jsx(FormFieldGroup, {
rowSpacing: "small",
description: /*#__PURE__*/ jsx(ScreenReaderContent, null, t('Fill in the blank options'))
}, props.interactionData.wordBankChoices && /*#__PURE__*/ jsx(Checkbox, {
label: t('Allow word bank choices to be reused'),
value: "reuseWordBankChoices",
onChange: handleCheckboxChange,
checked: props.interactionData.reuseWordBankChoices,
disabled: props.overrideEditableForRegrading
}), props.showCalculatorOption && /*#__PURE__*/ jsx(CalculatorOptionWithOqaatAlert, {
disabled: props.overrideEditableForRegrading,
calculatorValue: props.calculatorType,
onCalculatorTypeChange: handleCalculatorTypeChange,
oqaatChecked: props.oneQuestionAtATime,
onOqaatChange: props.setOneQuestionAtATime
})))));
});
RichFillBlankEdit.displayName = 'RichFillBlankEdit';
RichFillBlankEdit.interactionType = RichFillBlankInteractionType;
RichFillBlankEdit.propTypes = {
additionalOptions: PropTypes.array,
calculatorType: PropTypes.string,
changeItemState: PropTypes.func.isRequired,
enableRichContentEditor: PropTypes.bool,
errors: PropTypes.object,
errorsAreShowing: PropTypes.bool,
fitbCommonWordbankEnabled: PropTypes.bool,
interactionData: PropTypes.object.isRequired,
interactionType: PropTypes.shape({
validBlankRegex: PropTypes.string
}).isRequired,
notifyScreenreader: PropTypes.func.isRequired,
onModalClose: PropTypes.func,
onModalOpen: PropTypes.func,
oneQuestionAtATime: PropTypes.bool,
openImportModal: PropTypes.func,
overrideEditableForRegrading: PropTypes.bool,
properties: PropTypes.shape({
shuffleRules: PropTypes.shape({
blanks: PropTypes.shape({
children: PropTypes.object
})
})
}),
scoringData: PropTypes.object.isRequired,
setOneQuestionAtATime: PropTypes.func,
validationErrorsFromApi: PropTypes.object,
styles: PropTypes.object,
showCalculatorOption: PropTypes.bool,
isSurvey: PropTypes.bool
};
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
};
var RichFillBlankEditWithTools = withEditTools(RichFillBlankEdit);
var RichFillBlankEditWithStyles = withStyleOverrides(generateStyle, generateComponentTheme)(RichFillBlankEditWithTools);
RichFillBlankEditWithStyles.componentId = "Quizzes".concat(RichFillBlankEdit.displayName);
export default RichFillBlankEditWithStyles;