@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
231 lines (225 loc) • 9.76 kB
JavaScript
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
var _dec, _class, _FillBlankTake;
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 = _getPrototypeOf(derived);
return _possibleConstructorReturn(_this, isNativeReflectConstruct() ? Reflect.construct(derived, args || [], _getPrototypeOf(_this).constructor) : derived.apply(_this, args));
}
/** @jsx jsx */
import { Component } from 'react';
import PropTypes from 'prop-types';
import map from 'lodash/map';
import find from 'lodash/find';
import indexOf from 'lodash/indexOf';
import update from 'immutability-helper';
import { Alert } from '@instructure/ui-alerts';
import { Text } from '@instructure/ui-text';
import { jsx } from '@instructure/emotion';
import { ItemBodyWrapper } from '@instructure/quiz-rce';
import t from '@instructure/quiz-i18n/es/format-message';
import Wordbank from '../drag_components/Wordbank';
import TakeStem from './take_components/TakeStem';
import generateStyle from './styles';
import generateComponentTheme from './theme';
import { withStyleOverrides } from '@instructure/quiz-common';
/**
---
category: FillInTheBlank
---
Fill in the Blank Take component
```jsx_example
const WrappedExample = DragDropContext(HTML5Backend)(FillBlankTake)
function Example (props) {
const exampleProps = {
interactionData: {
prompt: '<p><strong>Please</strong> fill in all the blanks</p>',
stemItems: [
{ id: 'stem_uuid-1', position: 1, type: 'text', value: ' ... ' },
{ id: 'stem_uuid0', position: 2, type: 'blank', blankId: 'fitb_uuid1' },
{ id: 'stem_uuid1', position: 3, type: 'text', value: ' Columbus sailed in ' },
{ id: 'stem_uuid2', position: 4, type: 'blank', blankId: 'fitb_uuid2' },
{ id: 'stem_uuid3', position: 5, type: 'text', value: ' , from the country of ' },
{ id: 'stem_uuid4', position: 6, type: 'blank', blankId: 'fitb_uuid3' },
{ id: 'stem_uuid5', position: 7, type: 'text', value: ' , on the continent of ' },
{ id: 'stem_uuid6', position: 8, type: 'blank', blankId: 'fitb_uuid4' },
{ id: 'stem_uuid7', position: 9, type: 'text', value: ' , across the ' },
{ id: 'stem_uuid8', position: 10, type: 'blank', blankId: 'fitb_uuid5' },
{ id: 'stem_uuid9', position: 11, type: 'text', value: ' , and found... ' },
{ id: 'stem_uuid10', position: 12, type: 'blank', blankId: 'fitb_uuid6' },
{ id: 'stem_uuid11', position: 13, type: 'text', value: ' !!! ' },
{ id: 'stem_uuid12', position: 14, type: 'text', value: ' Where the people were " ' },
{ id: 'stem_uuid13', position: 15, type: 'blank', blankId: 'fitb_uuid7' },
{ id: 'stem_uuid14', position: 16, type: 'text', value: ' " ' }
],
blanks: [{
id: 'fitb_uuid1',
answerType: 'openEntry'
}, {
id: 'fitb_uuid2',
answerType: 'openEntry'
}, {
id: 'fitb_uuid3',
answerType: 'openEntry'
}, {
id: 'fitb_uuid4',
answerType: 'openEntry'
}, {
id: 'fitb_uuid5',
answerType: 'openEntry'
}, {
id: 'fitb_uuid6',
choices: [
{ id: 'choice_uuid11_brazil', position: 1, itemBody: 'Brazil' },
{ id: 'choice_uuid12_austria', position: 2, itemBody: 'Austria' },
{ id: 'choice_uuid13_america', position: 3, itemBody: 'America' }
],
answerType: 'wordbank'
}, {
id: 'fitb_uuid7',
choices: [
{ id: 'choice_uuid11_peaceful', position: 1, itemBody: 'peaceful' },
{ id: 'choice_uuid12_war-torn', position: 2, itemBody: 'war-torn' },
{ id: 'choice_uuid13_confused', position: 3, itemBody: 'confused' }
],
answerType: 'dropdown'
}]
},
userResponse: {
value: [
{ id: 'fitb_uuid1', value: 'Christopher', type: 'Text'},
{ id: 'fitb_uuid2', value: '1493', type: 'Text'},
{ id: 'fitb_uuid3', value: 'Span', type: 'Text'},
{ id: 'fitb_uuid4', value: 'Europe', type: 'Text'},
{ id: 'fitb_uuid5', value: 'Atlantic', type: 'Text'},
{ id: 'fitb_uuid6', value: 'choice_uuid12_austria', type: 'Text'},
{ id: 'fitb_uuid7', value: 'choice_uuid13_confused', type: 'Text'}
]
}
}
return (
<WrappedExample {...exampleProps} {...props} />
)
}
<SettingsSwitcher locales={LOCALES}>
<TakeStateProvider>
<Example />
</TakeStateProvider>
</SettingsSwitcher>
```
**/
var FillBlankTake = (_dec = withStyleOverrides(generateStyle, generateComponentTheme), _dec(_class = (_FillBlankTake = /*#__PURE__*/function (_Component) {
function FillBlankTake() {
var _this2;
_classCallCheck(this, FillBlankTake);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this2 = _callSuper(this, FillBlankTake, [].concat(args));
_defineProperty(_this2, "moveChoiceToWordbank", function (blankId, choiceId) {
var responses = _this2.props.userResponse.value;
var blank = find(responses, {
id: blankId
});
// Removes the answer for blank only if choice is selected response for blank
if (blank && blank.value === choiceId) {
var blankIndex = indexOf(map(_this2.props.userResponse.value, 'id'), blankId);
var newResponses = update(responses, _defineProperty({}, blankIndex, {
$merge: {
value: null
}
}));
_this2.props.handleResponseUpdate(newResponses);
}
});
return _this2;
}
_inherits(FillBlankTake, _Component);
return _createClass(FillBlankTake, [{
key: "remainingWordBankChoices",
value: function remainingWordBankChoices() {
var wordbankBlanks = this.props.interactionData.blanks.filter(function (blank) {
return blank.answerType === 'wordbank';
});
var choices = _toConsumableArray(wordbankBlanks.map(function (blank) {
return blank.choices;
}).flat());
// filter the choices which are already used
this.props.userResponse.value.forEach(function (response) {
var choiceIndex = choices.findIndex(function (choice) {
return choice.id === response.value;
});
if (choiceIndex > -1) {
choices.splice(choiceIndex, 1);
}
});
return choices;
}
}, {
key: "renderWordbank",
value: function renderWordbank() {
var blanks = this.props.interactionData.blanks || [];
if (blanks.find(function (blank) {
return ['wordbank', 'dropdown'].includes(blank.answerType);
})) {
return jsx(Wordbank, {
blanks: blanks,
response: this.props.userResponse.value,
returnChoiceToWordbank: this.moveChoiceToWordbank,
wordBankChoices: this.remainingWordBankChoices()
});
}
}
}, {
key: "renderDeprecationWarning",
value: function renderDeprecationWarning() {
return jsx(Alert, {
variant: "error"
}, jsx(Text, {
color: "primary"
}, jsx("b", null, t('This question type is deprecated'))), jsx("ul", null, jsx("li", null, t('Quizzes containing deprecated question types will fail to copy.')), jsx("li", null, t('This question was unable to be automatically upgraded due to malformed data.')), jsx("li", null, t('Please delete this question and recreate it using the current Fill in the Blank question type.'))));
}
}, {
key: "render",
value: function render() {
return jsx(ItemBodyWrapper, {
itemBody: this.props.interactionData.prompt
}, this.props.readOnly && this.renderDeprecationWarning(), jsx("div", {
css: this.props.styles.question
}, jsx("div", {
css: this.props.styles.headerSection
}, jsx(TakeStem, {
onUpdate: this.props.handleResponseUpdate,
interactionData: this.props.interactionData,
returnChoiceToWordbank: this.moveChoiceToWordbank,
userResponses: this.props.userResponse.value,
readOnly: this.props.readOnly,
wordBankChoices: this.remainingWordBankChoices()
})), this.renderWordbank()));
}
}]);
}(Component), _defineProperty(_FillBlankTake, "displayName", 'FillBlankTake'), _defineProperty(_FillBlankTake, "componentId", "Quizzes".concat(_FillBlankTake.displayName)), _defineProperty(_FillBlankTake, "propTypes", {
handleResponseUpdate: PropTypes.func,
interactionData: PropTypes.object.isRequired,
userResponse: PropTypes.object.isRequired,
readOnly: PropTypes.bool,
styles: PropTypes.object
}), _defineProperty(_FillBlankTake, "defaultProps", {
handleResponseUpdate: void 0,
readOnly: false
}), _FillBlankTake)) || _class);
export { FillBlankTake as default };