@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
213 lines (211 loc) • 8.84 kB
JavaScript
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";
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));
}
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { v4 as uuid } from 'uuid';
import update from 'immutability-helper';
import { Flex, FormFieldGroup } from '@instructure/quiz-common';
import RichFillBlankInteractionType from '../../../../records/interactions/rich_fill_blank';
import ChoiceInput from '../../../common/edit/components/ChoiceInput';
import Footer from '../../../common/edit/components/Footer';
import { getNextItemIdFromArray } from '../../../../util/focusHelpers';
import { toErrors } from '../../../../util/instUIMessages';
import t from '@instructure/quiz-i18n/es/format-message';
import { normalizeErrors } from '../../../../util/normalizeErrors';
var WordBankDistractors = /*#__PURE__*/function (_Component) {
function WordBankDistractors() {
var _this2;
_classCallCheck(this, WordBankDistractors);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this2 = _callSuper(this, WordBankDistractors, [].concat(args));
_defineProperty(_this2, "distractorRefs", {});
_defineProperty(_this2, "getErrorsForChoice", function (id) {
var wordBankChoiceIndex = _this2.props.indexForWordBankChoice(id);
var errors = _this2.props.interactionDataErrors[wordBankChoiceIndex] || {};
return toErrors(errors.itemBody || []);
});
_defineProperty(_this2, "onWordBankDistractorInputChange", function (id, e) {
var wordBankChoiceIndex = _this2.props.indexForWordBankChoice(id);
var interactionData = update(_this2.props.interactionData, {
wordBankChoices: _defineProperty({}, wordBankChoiceIndex, {
itemBody: {
$set: e.target.value
}
})
});
_this2.props.changeItemState({
interactionData: interactionData
});
});
_defineProperty(_this2, "handleCreateWordBankDistractor", function () {
var id = uuid();
var newWordBankDistractor = {
id: id,
itemBody: ''
};
var interactionData = update(_this2.props.interactionData, {
wordBankChoices: {
$push: [newWordBankDistractor]
}
});
_this2.props.changeItemState({
interactionData: interactionData
});
});
_defineProperty(_this2, "handleRemoveWordBankDistractor", function (distractorId) {
var newWordBankChoices = _this2.props.interactionData.wordBankChoices.filter(function (wordBankChoice) {
return wordBankChoice.id !== distractorId;
});
var interactionData = update(_this2.props.interactionData, {
wordBankChoices: {
$set: newWordBankChoices
}
});
_this2.props.changeItemState({
interactionData: interactionData
});
// focus handling:
var nextDistractorId = getNextItemIdFromArray(distractorId, _this2.getWordBankDistractors());
var nextDistractorRef = _this2.distractorRefs[nextDistractorId];
if (nextDistractorRef) {
nextDistractorRef.removeChoicebutton.focus();
} else {
_this2.addDistractorRef.focus();
}
});
_defineProperty(_this2, "handleRemoveChoice", function (distractorId) {
return function () {
_this2.handleRemoveWordBankDistractor(distractorId);
};
});
_defineProperty(_this2, "handleDistractorRef", function (distractorId) {
return function (node) {
_this2.distractorRefs[distractorId] = node;
};
});
_defineProperty(_this2, "handleAddDistractorRef", function (node) {
_this2.addDistractorRef = node;
});
return _this2;
}
_inherits(WordBankDistractors, _Component);
return _createClass(WordBankDistractors, [{
key: "getWordBankDistractors",
value: function getWordBankDistractors() {
var correctChoiceIds = this.props.scoringData.value.map(function (scoringData) {
return scoringData.scoringData.choiceId;
}).filter(function (c) {
return c;
});
return this.props.interactionData.wordBankChoices.filter(function (wordBankChoice) {
return !correctChoiceIds.includes(wordBankChoice.id);
});
}
}, {
key: "renderWordBankDistractor",
value:
// =============
// RENDERING
// =============
function renderWordBankDistractor(distractor, focusOnMount) {
return /*#__PURE__*/React.createElement(ChoiceInput, {
key: distractor.id,
id: distractor.id,
renderLabel: t('Distractor'),
isRequired: true,
disabledFields: this.props.overrideEditableForRegrading ? ['answerInput'] : [],
itemBody: distractor.itemBody,
errors: this.getErrorsForChoice(distractor.id),
onInputChange: this.onWordBankDistractorInputChange,
onModalClose: this.props.onModalClose,
onModalOpen: this.props.onModalOpen,
onRemoveChoice: this.handleRemoveChoice(distractor.id),
ref: this.handleDistractorRef(distractor.id),
focusOnMount: focusOnMount,
shouldRenderRemoveChoice: !this.props.overrideEditableForRegrading,
noRCE: true,
notifyScreenreader: this.props.notifyScreenreader
});
}
}, {
key: "render",
value: function render() {
var _this3 = this;
var noFocusOnFirstTime = true;
if (!this.props.interactionData.wordBankChoices) return null;
return /*#__PURE__*/React.createElement(FormFieldGroup, {
description: t('Word Bank Distractors'),
messages: normalizeErrors(this.props.interactionDataErrors.$errors)
}, /*#__PURE__*/React.createElement(Flex, {
direction: "column",
gap: "small"
}, /*#__PURE__*/React.createElement(Flex.Item, null, /*#__PURE__*/React.createElement(Flex, {
direction: "column",
gap: "small"
}, this.getWordBankDistractors().map(function (distractor, i, source) {
var focusOnMount = noFocusOnFirstTime ? noFocusOnFirstTime = !noFocusOnFirstTime : i + 1 === source.length && !distractor.itemBody;
return _this3.renderWordBankDistractor(distractor, focusOnMount);
}))), !this.props.overrideEditableForRegrading && /*#__PURE__*/React.createElement(Flex.Item, null, /*#__PURE__*/React.createElement(Footer, {
ref: this.handleAddDistractorRef,
onCreateChoice: this.handleCreateWordBankDistractor,
buttonText: t('Distractor'),
screenReaderText: t('Add Distractor'),
notifyScreenreader: this.props.notifyScreenreader
}))));
}
}]);
}(Component);
_defineProperty(WordBankDistractors, "interactionType", RichFillBlankInteractionType);
_defineProperty(WordBankDistractors, "propTypes", {
changeItemState: PropTypes.func.isRequired,
indexForWordBankChoice: PropTypes.func.isRequired,
interactionData: PropTypes.shape({
wordBankChoices: PropTypes.arrayOf(PropTypes.shape({
itemBody: PropTypes.string,
id: PropTypes.string
}))
}).isRequired,
interactionDataErrors: PropTypes.oneOfType([PropTypes.shape({
$errors: PropTypes.arrayOf(PropTypes.string)
}), PropTypes.objectOf(PropTypes.shape({
itemBody: PropTypes.arrayOf(PropTypes.string)
}))]).isRequired,
notifyScreenreader: PropTypes.func.isRequired,
onModalClose: PropTypes.func,
onModalOpen: PropTypes.func,
overrideEditableForRegrading: PropTypes.bool,
scoringData: PropTypes.shape({
value: PropTypes.arrayOf(PropTypes.shape({
scoringData: PropTypes.shape({
choiceId: PropTypes.string
})
}))
}).isRequired
});
_defineProperty(WordBankDistractors, "defaultProps", {
overrideEditableForRegrading: false,
onModalClose: void 0,
onModalOpen: void 0,
scoringData: void 0
});
export { WordBankDistractors as default };