UNPKG

quiz-interactions

Version:

A React UI component Library for quiz interaction types.

449 lines (376 loc) 16.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports.drawTypes = drawTypes; exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); 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 _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _immutabilityHelper = _interopRequireDefault(require("immutability-helper")); var _pick = _interopRequireDefault(require("lodash/fp/pick")); var _find2 = _interopRequireDefault(require("lodash/fp/find")); var _uiElements = require("@instructure/ui-elements"); var _uiIcons = require("@instructure/ui-icons"); var _uiThemeable = require("@instructure/ui-themeable"); var _hotspot = _interopRequireDefault(require("../../../records/interactions/hotspot")); var _QuestionSettingsContainer = _interopRequireDefault(require("../../common/edit/components/QuestionSettingsContainer")); var _QuestionContainer = _interopRequireDefault(require("../../common/edit/components/QuestionContainer")); var _RemoveChoiceButton = _interopRequireDefault(require("../../common/edit/components/RemoveChoiceButton")); var _DrawingContainer = _interopRequireDefault(require("./DrawingContainer")); var _Oval = _interopRequireDefault(require("../common/Oval")); var _Polygon = _interopRequireDefault(require("../common/Polygon")); var _Square = _interopRequireDefault(require("../common/Square")); var _theme = _interopRequireDefault(require("./theme")); var _withEditTools = _interopRequireDefault(require("../../../util/withEditTools")); var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/lib/format-message")); var _QuestionSettingsPanel = _interopRequireDefault(require("../../common/edit/components/QuestionSettingsPanel")); var _CalculatorOptionWithOqaatAlert = _interopRequireDefault(require("../../common/edit/components/CalculatorOptionWithOqaatAlert")); var _uiFormField = require("@instructure/ui-form-field"); var _uiA11y = require("@instructure/ui-a11y"); var _dec, _class, _class2, _temp; 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(source, true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var styles = { componentId: 'ckcaF', template: function template(theme) { return "\n\n.ckcaF_dTIX{align-items:flex-end;display:flex;margin-top:".concat(theme.footerContainerMargin || 'inherit', "}\n\n.ckcaF_fhUM{flex:1}\n\n.ckcaF_djjy{align-items:center;display:flex;margin:").concat(theme.accessibilityInfoMargin || 'inherit', " 0 ").concat(theme.accessibilityInfoMargin || 'inherit', " 0}\n\n.ckcaF_cMfx{margin-right:").concat(theme.iconRightMargin || 'inherit', "}"); }, 'footerContainer': 'ckcaF_dTIX', 'footerContainerText': 'ckcaF_fhUM', 'accessibilityInfo': 'ckcaF_djjy', 'accessibilityInfoIcon': 'ckcaF_cMfx' }; function drawTypes() { return [{ type: 'square', title: (0, _formatMessage.default)('Square'), icon: _uiIcons.IconBoxLine, component: _Square.default }, { type: 'oval', title: (0, _formatMessage.default)('Oval'), icon: _uiIcons.IconEmptyLine, component: _Oval.default }, { type: 'polygon', title: (0, _formatMessage.default)('Polygon'), icon: _uiIcons.IconMarkerLine, component: _Polygon.default }]; } /** --- category: HotSpot --- HotSpot Edit component ```jsx_example function Example (props) { const exampleProps = { itemBody: 'Which of these players is David Ferrer', interactionData: { imageUrl: 'https://i.ytimg.com/vi/LgkAebhJ7iE/maxresdefault.jpg' }, scoringData: { value: { type: 'oval', coordinates: [ { x: 0.6, y: 0.13 }, { x: 0.7, y: 0.2 } ] } } } return ( <HotSpotEdit {...exampleProps} {...props} /> ) } <SettingsSwitcher locales={LOCALES}> <EditStateProvider> <Example /> </EditStateProvider> </SettingsSwitcher> ``` **/ var HotSpotEdit = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles), (0, _withEditTools.default)(_class = _dec(_class = (_temp = _class2 = /*#__PURE__*/ function (_Component) { (0, _inherits2.default)(HotSpotEdit, _Component); function HotSpotEdit() { var _getPrototypeOf2; var _this; (0, _classCallCheck2.default)(this, HotSpotEdit); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2.default)(this, (_getPrototypeOf2 = (0, _getPrototypeOf3.default)(HotSpotEdit)).call.apply(_getPrototypeOf2, [this].concat(args))); _this.drawingContainer = null; _this.state = { file: null }; _this.updateProps = function (newProps) { var propsToUpdate = (0, _pick.default)(['interactionData', 'scoringData', 'properties'], _this.props); _this.props.changeItemState((0, _immutabilityHelper.default)(propsToUpdate, newProps)); }; _this.convertCoordinates = function (coordinatesArray) { var convertedCoordinates = coordinatesArray.map(function (_ref) { var x = _ref.x, y = _ref.y; return { x: x / _this.drawingContainer.currentImageWidth(), y: y / _this.drawingContainer.currentImageHeight() }; }); _this.updateProps({ scoringData: { value: { coordinates: { $set: convertedCoordinates } } } }); }; _this.handleCalculatorTypeChange = function (e, value) { _this.props.changeItemState({ calculatorType: value }); }; _this.handleTypeChange = function (newType) { _this.updateProps({ scoringData: { value: { $set: { type: newType, coordinates: [] } } } }); }; _this.handleRemoveImage = function () { _this.updateProps({ interactionData: { $set: {} }, scoringData: { value: { coordinates: { $set: [] } } } }); }; _this.handleUpload = function (url) { _this.updateProps({ interactionData: { imageUrl: { $set: url } }, scoringData: { value: { $set: { coordinates: [], type: 'square' } } } }); _this.setState({ file: null }); }; _this.handleDropAccepted = function (_ref2) { var _ref3 = (0, _slicedToArray2.default)(_ref2, 1), file = _ref3[0]; if (file instanceof Blob) { var reader = new FileReader(); reader.onload = function (e) { _this.setState({ file: { url: e.target.result } }); }; reader.readAsDataURL(file); } _this.setState({ file: {} }); _this.props.mediaUpload(file, _this.handleUpload); }; _this.handleDrawingRemove = function () { _this.drawingContainer.canvas.clearCanvas(); _this.drawingContainer.canvas.focus(); _this.handleTypeChange(_this.props.scoringData.value.type); }; _this.handleDescriptionChange = function (itemBody) { return _this.props.changeItemState({ itemBody: itemBody }); }; _this.handleDrawingContainerRef = function (node) { _this.drawingContainer = node; }; return _this; } (0, _createClass2.default)(HotSpotEdit, [{ key: "renderFooter", // =========== // RENDER // =========== value: function renderFooter() { var coordinates = this.props.scoringData.value.coordinates; var url = this.props.interactionData.imageUrl; if (url !== void 0 && coordinates !== void 0 && coordinates.length > 1) { var _find = (0, _find2.default)({ type: this.props.scoringData.value.type }, drawTypes()), title = _find.title; // FIXME: some of the translations for this don't look right (fr, it...) var mainText = (0, _formatMessage.default)('{title} Hot Spot', { title: title }); return _react.default.createElement("div", { className: styles.footerContainer }, _react.default.createElement("div", { className: styles.footerContainerText }, _react.default.createElement("div", null, _react.default.createElement(_uiElements.Text, { weight: "bold" }, mainText)), _react.default.createElement("div", null, _react.default.createElement(_uiElements.Text, { color: "primary" }, (0, _formatMessage.default)('Clicks within the hot spot will receive full points')))), _react.default.createElement(_RemoveChoiceButton.default, { buttonSize: "large", onRemoveChoice: this.handleDrawingRemove, screenReaderText: (0, _formatMessage.default)('Remove current drawing') })); } } }, { key: "renderOptionsDescription", value: function renderOptionsDescription() { return _react.default.createElement(_uiA11y.ScreenReaderContent, null, (0, _formatMessage.default)('Hotspot options')); } }, { key: "render", value: function render() { return _react.default.createElement("div", null, _react.default.createElement("div", { className: styles.accessibilityInfo }, _react.default.createElement(_uiElements.Text, { color: "secondary" }, _react.default.createElement(_uiIcons.IconInfoLine, { size: "x-small", className: styles.accessibilityInfoIcon }), (0, _formatMessage.default)('This question type is not accessible to users requiring keyboard-only access or screen readers.'))), _react.default.createElement(_QuestionContainer.default, { disabled: this.props.overrideEditableForRegrading, enableRichContentEditor: this.props.enableRichContentEditor, itemBody: this.props.itemBody, onDescriptionChange: this.handleDescriptionChange, onModalClose: this.props.onModalClose, onModalOpen: this.props.onModalOpen, openImportModal: this.props.openImportModal, renderImportModal: this.props.renderImportModal, stemErrors: this.props.getErrors('itemBody') }, _react.default.createElement(_DrawingContainer.default, { ref: this.handleDrawingContainerRef, canvasErrors: this.props.getErrors('scoringData.value.coordinates'), coordinates: this.props.scoringData.value.coordinates, currentType: this.props.scoringData.value.type, drawTypes: drawTypes(), fileDropErrors: this.props.getErrors('interactionData.imageUrl'), onModalOpen: this.props.onModalOpen, onModalClose: this.props.onModalClose, onDropAccepted: this.handleDropAccepted, onSetType: this.handleTypeChange, convertCoordinates: this.convertCoordinates, onRemoveImage: this.handleRemoveImage, typeErrors: this.props.getErrors('scoringData.value.type'), url: this.props.interactionData.imageUrl || this.state.file && this.state.file.url, isUploading: this.state.file !== null }), this.renderFooter()), _react.default.createElement(_QuestionSettingsContainer.default, { additionalOptions: this.props.additionalOptions }, !this.props.hiddenOptions.calculator && _react.default.createElement(_QuestionSettingsPanel.default, { label: (0, _formatMessage.default)('Options'), defaultExpanded: true }, _react.default.createElement(_uiFormField.FormFieldGroup, { rowSpacing: "small", description: this.renderOptionsDescription() }, _react.default.createElement(_CalculatorOptionWithOqaatAlert.default, { disabled: this.props.overrideEditableForRegrading, calculatorValue: this.props.calculatorType, onCalculatorTypeChange: this.handleCalculatorTypeChange, oqaatChecked: this.props.oneQuestionAtATime, onOqaatChange: this.props.setOneQuestionAtATime }))))); } }]); HotSpotEdit.displayName = "HotSpotEdit"; return HotSpotEdit; }(_react.Component), _class2.interactionType = _hotspot.default, _class2.propTypes = _objectSpread({ additionalOptions: _propTypes.default.array, calculatorType: _propTypes.default.string, changeItemState: _propTypes.default.func.isRequired, enableRichContentEditor: _propTypes.default.bool, errors: _propTypes.default.shape({ itemBody: _propTypes.default.arrayOf(_propTypes.default.string), interactionData: _propTypes.default.shape({ imageUrl: _propTypes.default.arrayOf(_propTypes.default.string) }), scoringData: _propTypes.default.shape({ value: _propTypes.default.shape({ type: _propTypes.default.arrayOf(_propTypes.default.string), coordinates: _propTypes.default.arrayOf(_propTypes.default.string) }) }) }), hiddenOptions: _propTypes.default.shape({ calculator: _propTypes.default.bool }), interactionData: _propTypes.default.shape({ imageUrl: _propTypes.default.string }).isRequired, itemBody: _propTypes.default.string, mediaUpload: _propTypes.default.func.isRequired, onModalClose: _propTypes.default.func, onModalOpen: _propTypes.default.func, oneQuestionAtATime: _propTypes.default.bool, openImportModal: _propTypes.default.func, overrideEditableForRegrading: _propTypes.default.bool, renderImportModal: _propTypes.default.func, scoringData: _propTypes.default.shape({ value: _propTypes.default.shape({ type: _propTypes.default.oneOf(['square', 'oval', 'polygon']), coordinates: _propTypes.default.arrayOf(_propTypes.default.shape({ x: _propTypes.default.number.isRequired, y: _propTypes.default.number.isRequired })) }).isRequired }).isRequired, setOneQuestionAtATime: _propTypes.default.func }, _withEditTools.default.injectedProps), _class2.defaultProps = { calculatorType: 'none', enableRichContentEditor: true, hiddenOptions: { calculator: true }, oneQuestionAtATime: false, overrideEditableForRegrading: false, setOneQuestionAtATime: Function.prototype, additionalOptions: void 0, errors: void 0, itemBody: void 0, onModalClose: void 0, onModalOpen: void 0, openImportModal: void 0, renderImportModal: void 0 }, _temp)) || _class) || _class); exports.default = HotSpotEdit;