@instructure/quiz-core 17.26.1-rc.0 → 17.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [17.27.0](https://gerrit.instructure.com/quizzes-ui/compare/v17.26.0...v17.27.0) (2022-03-08)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **itembanks:** Fixes default filter when launching from course ([966b51d](https://gerrit.instructure.com/quizzes-ui/commits/966b51d7eefdf2f966da94c7a97a98db2dcfd508))
12
+
13
+
14
+ ### Features
15
+
16
+ * **fitb:** support question copy to rich_fitb ([d79040c](https://gerrit.instructure.com/quizzes-ui/commits/d79040c52784e570123138f420acf792e9a5213c))
17
+
18
+
19
+
20
+
21
+
6
22
  # [17.26.0](https://gerrit.instructure.com/quizzes-ui/compare/v17.25.1...v17.26.0) (2022-02-23)
7
23
 
8
24
 
@@ -14,8 +14,10 @@ import partial from 'lodash/partial';
14
14
  import { ScreenReaderContent } from '@instructure/ui-a11y-content';
15
15
  import { TextInput } from '@instructure/ui-text-input';
16
16
  import { themeable } from '@instructure/ui-themeable';
17
+ import { FillBlankInteractionType } from '@instructure/quiz-interactions';
17
18
  import { IconBankLine } from '@instructure/ui-icons';
18
19
  import t from '@instructure/quiz-i18n/es/format-message';
20
+ import { convertFITBtoRich } from "../../../../../../common/util/fitbCopyHelper.js";
19
21
  import PositionBox from "../../../../../../common/components/resources/positionBox/PositionBox.js";
20
22
  import Item from "../../../../../../common/records/Item.js";
21
23
  import ActionButtons from "../../../ActionButtons/index.js";
@@ -103,19 +105,19 @@ var QuizEntryHeader = (_dec = themeable(theme, styles), _dec(_class = (_temp = _
103
105
 
104
106
  _this.copyItem = /*#__PURE__*/function () {
105
107
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(e) {
106
- var _this$props, quizId, workingQuizEntry, workingEntry, msg, validationResult, interactionTypeData;
108
+ var _this$props, quizId, workingQuizEntry, workingEntry, richFITBEnabled, richFITBInteractionID, msg, validationResult, interactionTypeData;
107
109
 
108
110
  return _regeneratorRuntime.wrap(function _callee$(_context) {
109
111
  while (1) {
110
112
  switch (_context.prev = _context.next) {
111
113
  case 0:
112
- _this$props = _this.props, quizId = _this$props.quizId, workingQuizEntry = _this$props.workingQuizEntry, workingEntry = _this$props.workingEntry;
114
+ _this$props = _this.props, quizId = _this$props.quizId, workingQuizEntry = _this$props.workingQuizEntry, workingEntry = _this$props.workingEntry, richFITBEnabled = _this$props.richFITBEnabled, richFITBInteractionID = _this$props.richFITBInteractionID;
113
115
  msg = t('Item {displayPosition} cannot be saved due to invalid input data.', {
114
116
  displayPosition: _this.props.displayPosition
115
117
  });
116
118
 
117
119
  if (!_this.props.isValid) {
118
- _context.next = 13;
120
+ _context.next = 14;
119
121
  break;
120
122
  }
121
123
 
@@ -149,17 +151,21 @@ var QuizEntryHeader = (_dec = themeable(theme, styles), _dec(_class = (_temp = _
149
151
  title: workingEntry.title
150
152
  };
151
153
 
154
+ if (richFITBEnabled && workingEntry.getInteractionType() instanceof FillBlankInteractionType) {
155
+ interactionTypeData = convertFITBtoRich(interactionTypeData, richFITBInteractionID);
156
+ }
157
+
152
158
  _this.props.createTempItem(quizId, Math.round(workingQuizEntry.position + 1), interactionTypeData, workingQuizEntry.stimulusQuizEntryId, workingEntry.stimulusId, workingQuizEntry.pointsPossible);
153
159
 
154
- _context.next = 15;
160
+ _context.next = 16;
155
161
  break;
156
162
 
157
- case 13:
163
+ case 14:
158
164
  _this.props.screenreaderNotification(msg);
159
165
 
160
166
  _this.props.showError(_this.props.guid);
161
167
 
162
- case 15:
168
+ case 16:
163
169
  case "end":
164
170
  return _context.stop();
165
171
  }
@@ -319,6 +325,8 @@ var QuizEntryHeader = (_dec = themeable(theme, styles), _dec(_class = (_temp = _
319
325
  quizId: PropTypes.string.isRequired,
320
326
  removeQuizEntry: PropTypes.func.isRequired,
321
327
  // from connected component
328
+ richFITBEnabled: PropTypes.bool,
329
+ richFITBInteractionID: PropTypes.string,
322
330
  screenreaderNotification: PropTypes.func.isRequired,
323
331
  setUi: PropTypes.func.isRequired,
324
332
  shouldClone: PropTypes.bool,
@@ -331,6 +339,8 @@ var QuizEntryHeader = (_dec = themeable(theme, styles), _dec(_class = (_temp = _
331
339
  disabledForRegrade: false,
332
340
  initialFocusId: null,
333
341
  name: null,
342
+ richFITBEnabled: false,
343
+ richFITBInteractionID: '',
334
344
  shouldClone: false
335
345
  }, _temp)) || _class);
336
346
  export default QuizEntryHeader;
@@ -9,6 +9,7 @@ import * as modalActions from "../../../../../common/actions/modal.js";
9
9
  import { set as setUI } from "../../../../../common/actions/ui.js";
10
10
  import * as modificationActions from "../../../../../common/actions/modifications.js";
11
11
  import * as quizEntryApiActions from "../../../../api/quizEntries.js";
12
+ import { featureOn } from "../../../../../common/util/featureCheck.js";
12
13
  import { ADD_CONTENT_POPOVER_KEY } from '@instructure/quiz-common';
13
14
  import QuizEntryEdit from "./presenter.js";
14
15
 
@@ -23,8 +24,12 @@ function mapStateToProps(state, props) {
23
24
  var dndPosition = state.getIn(['dragAndDrop', 'position']);
24
25
  var draggingAboveHalf = state.getIn(['dragAndDrop', 'aboveHalf'], false);
25
26
  var draggingOver = props.draggingOnBuild && dndPosition === props.quizEntry.position;
27
+ var richFITBInteraction = state.getIn(['interactionTypes'], Map()).find(function (interactionType) {
28
+ return interactionType.get('slug') === 'rich-fill-blank';
29
+ });
26
30
  return {
27
31
  addContentPopoverOpen: Boolean(addContentPopoverOpen),
32
+ appContainer: state.getIn(['ui', 'appContainer']),
28
33
  draggingAboveHalf: draggingOver && draggingAboveHalf,
29
34
  draggingOver: draggingOver,
30
35
  editable: true,
@@ -34,10 +39,11 @@ function mapStateToProps(state, props) {
34
39
  isOccluded: state.getIn(['ui', 'quizEntriesOccluded'], false),
35
40
  nextQuizEntry: state.getIn(['modifications', 'nextQuizEntry'], null),
36
41
  notifyScreenReader: true,
42
+ richFITBEnabled: featureOn('interaction_type_rich_fill_blank'),
43
+ richFITBInteractionID: (richFITBInteraction || Map()).get('id'),
37
44
  stemErrors: workingEntry.errorsFor('itemBody').toJS(),
38
45
  workingEntry: workingEntry,
39
- workingQuizEntry: props.quizEntry.getWorkingInstance(),
40
- appContainer: state.getIn(['ui', 'appContainer'])
46
+ workingQuizEntry: props.quizEntry.getWorkingInstance()
41
47
  };
42
48
  }
43
49
 
@@ -398,7 +398,7 @@ var QuizEntryEdit = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
398
398
  }, {
399
399
  key: "renderHeader",
400
400
  value: function renderHeader() {
401
- var headerProps = pick(this.props, ['changeItemTitle', 'clearModifications', 'clearTemporaryItem', 'connectDragSource', 'createTempItem', 'disabledForRegrade', 'displayPosition', 'entry', 'guid', 'hideError', 'initialFocusId', 'name', 'quizEntries', 'quizEntry', 'quizId', 'removeQuizEntry', 'screenreaderNotification', 'setUi', 'shouldClone', 'showError', 'withConfirm', 'workingEntry', 'workingQuizEntry']);
401
+ var headerProps = pick(this.props, ['changeItemTitle', 'clearModifications', 'clearTemporaryItem', 'connectDragSource', 'createTempItem', 'disabledForRegrade', 'displayPosition', 'entry', 'guid', 'hideError', 'initialFocusId', 'name', 'quizEntries', 'quizEntry', 'quizId', 'removeQuizEntry', 'richFITBEnabled', 'richFITBInteractionID', 'screenreaderNotification', 'setUi', 'shouldClone', 'showError', 'withConfirm', 'workingEntry', 'workingQuizEntry']);
402
402
  return /*#__PURE__*/React.createElement(QuizEntryEditHeader, Object.assign({
403
403
  isValid: this.isValid(),
404
404
  successfulSubmit: this.successfulSubmit,
@@ -425,6 +425,13 @@ var QuizEntryEdit = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
425
425
  QuizEntryEdit.displayName = "QuizEntryEdit";
426
426
  return QuizEntryEdit;
427
427
  }(Component), _class2.propTypes = {
428
+ addContentPopoverOpen: PropTypes.bool.isRequired,
429
+ alternativeRightFooter: PropTypes.func,
430
+ appContainer: CustomPropTypes.selectors.isRequired,
431
+ changeItemTitle: PropTypes.func.isRequired,
432
+ // from connected component
433
+ changeQuizEntryPoints: PropTypes.func.isRequired,
434
+ // from connected component
428
435
  children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
429
436
  clearModifications: PropTypes.func.isRequired,
430
437
  // from connected component
@@ -434,6 +441,7 @@ var QuizEntryEdit = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
434
441
  // from connected component
435
442
  cloneQuizEntry: PropTypes.func.isRequired,
436
443
  // from connected component
444
+ clearValidationErrorsFromApi: PropTypes.func.isRequired,
437
445
  connectDragPreview: PropTypes.func.isRequired,
438
446
  // inserted from React DnD
439
447
  connectDragSource: PropTypes.func.isRequired,
@@ -447,17 +455,29 @@ var QuizEntryEdit = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
447
455
  createQuizEntry: PropTypes.func.isRequired,
448
456
  // from connected component
449
457
  disabledForRegrade: PropTypes.bool,
458
+ displayPosition: PropTypes.number.isRequired,
450
459
  draggingAboveHalf: PropTypes.bool.isRequired,
451
460
  draggingOver: PropTypes.bool.isRequired,
452
461
  entry: ImmutablePropTypes.record.isRequired,
453
462
  guid: PropTypes.string.isRequired,
454
- addContentPopoverOpen: PropTypes.bool.isRequired,
463
+ handleValidationErrorsFromApi: PropTypes.func.isRequired,
464
+ haveValidationErrorsFromApi: PropTypes.bool,
465
+ hideError: PropTypes.func.isRequired,
466
+ // from connected component
467
+ initialFocusId: PropTypes.string,
455
468
  isOccluded: PropTypes.bool,
469
+ name: PropTypes.string,
456
470
  nextQuizEntry: ImmutablePropTypes.map,
457
471
  openRegradeModal: PropTypes.func.isRequired,
458
472
  quizEntries: ImmutablePropTypes.listOf(ImmutablePropTypes.record).isRequired,
473
+ onEditQuizEntryToggle: PropTypes.func,
474
+ openModal: PropTypes.func.isRequired,
459
475
  quizEntry: ImmutablePropTypes.record.isRequired,
460
476
  quizId: PropTypes.string.isRequired,
477
+ removeQuizEntry: PropTypes.func.isRequired,
478
+ // from connected component
479
+ richFITBEnabled: PropTypes.bool,
480
+ richFITBInteractionID: PropTypes.string,
461
481
  screenreaderNotification: PropTypes.func.isRequired,
462
482
  // from connected component
463
483
  setUi: PropTypes.func.isRequired,
@@ -469,38 +489,22 @@ var QuizEntryEdit = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
469
489
  // from connected component
470
490
  updateItem: PropTypes.func.isRequired,
471
491
  // from connected component
472
- workingEntry: ImmutablePropTypes.record.isRequired,
473
- workingQuizEntry: ImmutablePropTypes.record.isRequired,
474
- appContainer: CustomPropTypes.selectors.isRequired,
475
- alternativeRightFooter: PropTypes.func,
476
- changeItemTitle: PropTypes.func.isRequired,
477
- // from connected component
478
- changeQuizEntryPoints: PropTypes.func.isRequired,
479
- // from connected component
480
- displayPosition: PropTypes.number.isRequired,
481
- hideError: PropTypes.func.isRequired,
482
- // from connected component
483
- name: PropTypes.string,
484
- openModal: PropTypes.func.isRequired,
485
- removeQuizEntry: PropTypes.func.isRequired,
486
- // from connected component
487
492
  withConfirm: PropTypes.func.isRequired,
488
- initialFocusId: PropTypes.string,
489
- onEditQuizEntryToggle: PropTypes.func,
490
- clearValidationErrorsFromApi: PropTypes.func.isRequired,
491
- handleValidationErrorsFromApi: PropTypes.func.isRequired,
492
- haveValidationErrorsFromApi: PropTypes.bool
493
+ workingEntry: ImmutablePropTypes.record.isRequired,
494
+ workingQuizEntry: ImmutablePropTypes.record.isRequired
493
495
  }, _class2.defaultProps = {
494
496
  alternativeRightFooter: null,
495
497
  children: null,
496
498
  disabledForRegrade: false,
499
+ haveValidationErrorsFromApi: false,
497
500
  initialFocusId: null,
498
501
  isOccluded: false,
499
502
  name: null,
500
503
  nextQuizEntry: null,
501
504
  onEditQuizEntryToggle: Function.prototype,
502
- shouldClone: false,
503
- haveValidationErrorsFromApi: false
505
+ richFITBEnabled: false,
506
+ richFITBInteractionID: '',
507
+ shouldClone: false
504
508
  }, _temp)) || _class);
505
509
  export var UndecoratedQuizEntryEdit = QuizEntryEdit;
506
510
  export var QuizEntryEditRaw = wrapWithOutsideClick(QuizEntryEdit);
@@ -7,6 +7,7 @@ import { withConfirm } from "../../../../../common/actions/modal.js";
7
7
  import { QuizEntryShowPresenter } from "./presenter.js";
8
8
  import { getQuizEntryWithErrorsShowing } from "../../../../../common/selectors/quizzes.js";
9
9
  import { CREATE_ITEM_CALL, UPDATE_ITEM_CALL } from '@instructure/quiz-common';
10
+ import { featureOn } from "../../../../../common/util/featureCheck.js";
10
11
 
11
12
  function mapStateToProps(state, props) {
12
13
  var dndPosition = state.getIn(['dragAndDrop', 'position']);
@@ -14,13 +15,18 @@ function mapStateToProps(state, props) {
14
15
  var draggingOver = props.draggingOnBuild && dndPosition === props.quizEntry.position;
15
16
  var itemModsClear = state.getIn(['modifications', 'items'], Map()).isEmpty();
16
17
  var quizEntryModsClear = state.getIn(['modifications', 'quizEntries'], Map()).isEmpty();
18
+ var richFITBInteraction = state.getIn(['interactionTypes'], Map()).find(function (interactionType) {
19
+ return interactionType.get('slug') === 'rich-fill-blank';
20
+ });
17
21
  return {
18
22
  createItemCallStatus: state.getIn(['calls', CREATE_ITEM_CALL, 'requestStatus'], ''),
19
- updateItemCallStatus: state.getIn(['calls', UPDATE_ITEM_CALL, 'requestStatus'], ''),
20
23
  draggingAboveHalf: draggingOver && draggingAboveHalf,
21
24
  draggingOver: draggingOver,
22
25
  modificationsClear: itemModsClear && quizEntryModsClear,
23
- quizEntryWithErrorsShowing: getQuizEntryWithErrorsShowing(state) || props.haveValidationErrorsFromApi
26
+ quizEntryWithErrorsShowing: getQuizEntryWithErrorsShowing(state) || props.haveValidationErrorsFromApi,
27
+ richFITBEnabled: featureOn('interaction_type_rich_fill_blank'),
28
+ richFITBInteractionID: (richFITBInteraction || Map()).get('id'),
29
+ updateItemCallStatus: state.getIn(['calls', UPDATE_ITEM_CALL, 'requestStatus'], '')
24
30
  };
25
31
  }
26
32
 
@@ -13,8 +13,10 @@ import { DragSource } from 'react-dnd';
13
13
  import { IconBankLine } from '@instructure/ui-icons';
14
14
  import { ScreenReaderContent } from '@instructure/ui-a11y-content';
15
15
  import { themeable } from '@instructure/ui-themeable';
16
+ import { FillBlankInteractionType } from '@instructure/quiz-interactions';
16
17
  import { TOP } from '@instructure/quiz-common';
17
18
  import t from '@instructure/quiz-i18n/es/format-message';
19
+ import { convertFITBtoRich } from "../../../../../common/util/fitbCopyHelper.js";
18
20
  import Item from "../../../../../common/records/Item.js";
19
21
  import Overlay from "../../../../../common/components/shared/overlay/Overlay.js";
20
22
  import ActionButtons from "../../ActionButtons/index.js";
@@ -106,7 +108,9 @@ var QuizEntryShow = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
106
108
  var _this$props = _this.props,
107
109
  quizId = _this$props.quizId,
108
110
  quizEntry = _this$props.quizEntry,
109
- entry = _this$props.entry;
111
+ entry = _this$props.entry,
112
+ richFITBEnabled = _this$props.richFITBEnabled,
113
+ richFITBInteractionID = _this$props.richFITBInteractionID;
110
114
  var interactionTypeData = {
111
115
  answerFeedback: entry.answerFeedback,
112
116
  calculatorType: entry.calculatorType,
@@ -121,6 +125,10 @@ var QuizEntryShow = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
121
125
  title: entry.title
122
126
  };
123
127
 
128
+ if (richFITBEnabled && entry.getInteractionType() instanceof FillBlankInteractionType) {
129
+ interactionTypeData = convertFITBtoRich(interactionTypeData, richFITBInteractionID);
130
+ }
131
+
124
132
  _this.props.createItem(quizId, Math.round(quizEntry.position + 1), interactionTypeData, quizEntry.stimulusQuizEntryId, entry.stimulusId, quizEntry.pointsPossible);
125
133
  };
126
134
 
@@ -316,7 +324,11 @@ var QuizEntryShow = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
316
324
  displayPosition: PropTypes.number.isRequired,
317
325
  draggingOver: PropTypes.bool.isRequired,
318
326
  draggingAboveHalf: PropTypes.bool.isRequired,
327
+ editQuizEntryToggle: PropTypes.bool.isRequired,
319
328
  entry: ImmutablePropTypes.record.isRequired,
329
+ haveValidationErrorsFromApi: PropTypes.bool,
330
+ // only used in index.js
331
+ interactionTypeName: PropTypes.string,
320
332
  modificationsClear: PropTypes.bool.isRequired,
321
333
  quizEntryWithErrorsShowing: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
322
334
  quizEntries: ImmutablePropTypes.listOf(ImmutablePropTypes.record).isRequired,
@@ -324,18 +336,16 @@ var QuizEntryShow = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
324
336
  quizId: PropTypes.string.isRequired,
325
337
  removeQuizEntry: PropTypes.func.isRequired,
326
338
  // from connected component
339
+ richFITBEnabled: PropTypes.bool,
340
+ richFITBInteractionID: PropTypes.string,
327
341
  screenreaderNotification: PropTypes.func.isRequired,
328
342
  // from connected component
329
343
  scrollKey: PropTypes.string,
344
+ stimulusOrientation: PropTypes.string,
330
345
  switchOnEditing: PropTypes.func.isRequired,
331
346
  // from QuizEntry
332
347
  updateItemCallStatus: PropTypes.string.isRequired,
333
- withConfirm: PropTypes.func.isRequired,
334
- editQuizEntryToggle: PropTypes.bool.isRequired,
335
- haveValidationErrorsFromApi: PropTypes.bool,
336
- // only used in index.js
337
- interactionTypeName: PropTypes.string,
338
- stimulusOrientation: PropTypes.string
348
+ withConfirm: PropTypes.func.isRequired
339
349
  }, _class2.defaultProps = {
340
350
  children: null,
341
351
  draggingOver: false,
@@ -345,6 +355,8 @@ var QuizEntryShow = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
345
355
  editQuizEntryToggle: false,
346
356
  haveValidationErrorsFromApi: false,
347
357
  interactionTypeName: null,
358
+ richFITBEnabled: false,
359
+ richFITBInteractionID: '',
348
360
  stimulusOrientation: null
349
361
  }, _temp)) || _class);
350
362
  export var QuizEntryShowRaw = QuizEntryShow;
@@ -0,0 +1,29 @@
1
+ import { List, Map } from 'immutable';
2
+ export function convertFITBtoRich(interactionTypeData, richFITBInteractionID) {
3
+ var interactionData = interactionTypeData.interactionData,
4
+ scoringData = interactionTypeData.scoringData;
5
+ var sortedStemItems = interactionData.get('stemItems').sort(function (a, b) {
6
+ return a.get('position') - b.get('position');
7
+ });
8
+ var workingItemBody = sortedStemItems.reduce(function (itemBody, stemItem) {
9
+ if (stemItem.get('type') === 'text') {
10
+ return itemBody + stemItem.get('value', '');
11
+ } else {
12
+ var blankScoringData = scoringData.get('value', List()).find(function (blank) {
13
+ return blank.get('id') === stemItem.get('blankId');
14
+ }) || Map();
15
+ return itemBody + "`".concat(blankScoringData.getIn(['scoringData', 'blankText']), "`");
16
+ }
17
+ }, '');
18
+ return Object.assign({}, interactionTypeData, {
19
+ id: richFITBInteractionID,
20
+ itemBody: '',
21
+ interactionData: {
22
+ blanks: interactionData.get('blanks', [])
23
+ },
24
+ scoringData: {
25
+ workingItemBody: "".concat(interactionData.get('prompt', ''), "<p>").concat(workingItemBody, "</p>"),
26
+ value: scoringData.get('value', [])
27
+ }
28
+ });
29
+ }
@@ -35,10 +35,14 @@ var _uiTextInput = require("@instructure/ui-text-input");
35
35
 
36
36
  var _uiThemeable = require("@instructure/ui-themeable");
37
37
 
38
+ var _quizInteractions = require("@instructure/quiz-interactions");
39
+
38
40
  var _uiIcons = require("@instructure/ui-icons");
39
41
 
40
42
  var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message"));
41
43
 
44
+ var _fitbCopyHelper = require("../../../../../../common/util/fitbCopyHelper.js");
45
+
42
46
  var _PositionBox = _interopRequireDefault(require("../../../../../../common/components/resources/positionBox/PositionBox.js"));
43
47
 
44
48
  var _Item = _interopRequireDefault(require("../../../../../../common/records/Item.js"));
@@ -133,19 +137,19 @@ var QuizEntryHeader = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles
133
137
 
134
138
  _this.copyItem = /*#__PURE__*/function () {
135
139
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(e) {
136
- var _this$props, quizId, workingQuizEntry, workingEntry, msg, validationResult, interactionTypeData;
140
+ var _this$props, quizId, workingQuizEntry, workingEntry, richFITBEnabled, richFITBInteractionID, msg, validationResult, interactionTypeData;
137
141
 
138
142
  return _regenerator.default.wrap(function _callee$(_context) {
139
143
  while (1) {
140
144
  switch (_context.prev = _context.next) {
141
145
  case 0:
142
- _this$props = _this.props, quizId = _this$props.quizId, workingQuizEntry = _this$props.workingQuizEntry, workingEntry = _this$props.workingEntry;
146
+ _this$props = _this.props, quizId = _this$props.quizId, workingQuizEntry = _this$props.workingQuizEntry, workingEntry = _this$props.workingEntry, richFITBEnabled = _this$props.richFITBEnabled, richFITBInteractionID = _this$props.richFITBInteractionID;
143
147
  msg = (0, _formatMessage.default)('Item {displayPosition} cannot be saved due to invalid input data.', {
144
148
  displayPosition: _this.props.displayPosition
145
149
  });
146
150
 
147
151
  if (!_this.props.isValid) {
148
- _context.next = 13;
152
+ _context.next = 14;
149
153
  break;
150
154
  }
151
155
 
@@ -179,17 +183,21 @@ var QuizEntryHeader = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles
179
183
  title: workingEntry.title
180
184
  };
181
185
 
186
+ if (richFITBEnabled && workingEntry.getInteractionType() instanceof _quizInteractions.FillBlankInteractionType) {
187
+ interactionTypeData = (0, _fitbCopyHelper.convertFITBtoRich)(interactionTypeData, richFITBInteractionID);
188
+ }
189
+
182
190
  _this.props.createTempItem(quizId, Math.round(workingQuizEntry.position + 1), interactionTypeData, workingQuizEntry.stimulusQuizEntryId, workingEntry.stimulusId, workingQuizEntry.pointsPossible);
183
191
 
184
- _context.next = 15;
192
+ _context.next = 16;
185
193
  break;
186
194
 
187
- case 13:
195
+ case 14:
188
196
  _this.props.screenreaderNotification(msg);
189
197
 
190
198
  _this.props.showError(_this.props.guid);
191
199
 
192
- case 15:
200
+ case 16:
193
201
  case "end":
194
202
  return _context.stop();
195
203
  }
@@ -348,6 +356,8 @@ var QuizEntryHeader = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles
348
356
  quizId: _propTypes.default.string.isRequired,
349
357
  removeQuizEntry: _propTypes.default.func.isRequired,
350
358
  // from connected component
359
+ richFITBEnabled: _propTypes.default.bool,
360
+ richFITBInteractionID: _propTypes.default.string,
351
361
  screenreaderNotification: _propTypes.default.func.isRequired,
352
362
  setUi: _propTypes.default.func.isRequired,
353
363
  shouldClone: _propTypes.default.bool,
@@ -360,6 +370,8 @@ var QuizEntryHeader = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles
360
370
  disabledForRegrade: false,
361
371
  initialFocusId: null,
362
372
  name: null,
373
+ richFITBEnabled: false,
374
+ richFITBInteractionID: '',
363
375
  shouldClone: false
364
376
  }, _temp)) || _class);
365
377
  var _default = QuizEntryHeader;
@@ -31,6 +31,8 @@ var modificationActions = _interopRequireWildcard(require("../../../../../common
31
31
 
32
32
  var quizEntryApiActions = _interopRequireWildcard(require("../../../../api/quizEntries.js"));
33
33
 
34
+ var _featureCheck = require("../../../../../common/util/featureCheck.js");
35
+
34
36
  var _quizCommon = require("@instructure/quiz-common");
35
37
 
36
38
  var _presenter = _interopRequireDefault(require("./presenter.js"));
@@ -46,8 +48,12 @@ function mapStateToProps(state, props) {
46
48
  var dndPosition = state.getIn(['dragAndDrop', 'position']);
47
49
  var draggingAboveHalf = state.getIn(['dragAndDrop', 'aboveHalf'], false);
48
50
  var draggingOver = props.draggingOnBuild && dndPosition === props.quizEntry.position;
51
+ var richFITBInteraction = state.getIn(['interactionTypes'], (0, _immutable.Map)()).find(function (interactionType) {
52
+ return interactionType.get('slug') === 'rich-fill-blank';
53
+ });
49
54
  return {
50
55
  addContentPopoverOpen: Boolean(addContentPopoverOpen),
56
+ appContainer: state.getIn(['ui', 'appContainer']),
51
57
  draggingAboveHalf: draggingOver && draggingAboveHalf,
52
58
  draggingOver: draggingOver,
53
59
  editable: true,
@@ -57,10 +63,11 @@ function mapStateToProps(state, props) {
57
63
  isOccluded: state.getIn(['ui', 'quizEntriesOccluded'], false),
58
64
  nextQuizEntry: state.getIn(['modifications', 'nextQuizEntry'], null),
59
65
  notifyScreenReader: true,
66
+ richFITBEnabled: (0, _featureCheck.featureOn)('interaction_type_rich_fill_blank'),
67
+ richFITBInteractionID: (richFITBInteraction || (0, _immutable.Map)()).get('id'),
60
68
  stemErrors: workingEntry.errorsFor('itemBody').toJS(),
61
69
  workingEntry: workingEntry,
62
- workingQuizEntry: props.quizEntry.getWorkingInstance(),
63
- appContainer: state.getIn(['ui', 'appContainer'])
70
+ workingQuizEntry: props.quizEntry.getWorkingInstance()
64
71
  };
65
72
  }
66
73
 
@@ -432,7 +432,7 @@ var QuizEntryEdit = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
432
432
  }, {
433
433
  key: "renderHeader",
434
434
  value: function renderHeader() {
435
- var headerProps = (0, _pick.default)(this.props, ['changeItemTitle', 'clearModifications', 'clearTemporaryItem', 'connectDragSource', 'createTempItem', 'disabledForRegrade', 'displayPosition', 'entry', 'guid', 'hideError', 'initialFocusId', 'name', 'quizEntries', 'quizEntry', 'quizId', 'removeQuizEntry', 'screenreaderNotification', 'setUi', 'shouldClone', 'showError', 'withConfirm', 'workingEntry', 'workingQuizEntry']);
435
+ var headerProps = (0, _pick.default)(this.props, ['changeItemTitle', 'clearModifications', 'clearTemporaryItem', 'connectDragSource', 'createTempItem', 'disabledForRegrade', 'displayPosition', 'entry', 'guid', 'hideError', 'initialFocusId', 'name', 'quizEntries', 'quizEntry', 'quizId', 'removeQuizEntry', 'richFITBEnabled', 'richFITBInteractionID', 'screenreaderNotification', 'setUi', 'shouldClone', 'showError', 'withConfirm', 'workingEntry', 'workingQuizEntry']);
436
436
  return /*#__PURE__*/_react.default.createElement(_index3.default, Object.assign({
437
437
  isValid: this.isValid(),
438
438
  successfulSubmit: this.successfulSubmit,
@@ -458,6 +458,13 @@ var QuizEntryEdit = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
458
458
  QuizEntryEdit.displayName = "QuizEntryEdit";
459
459
  return QuizEntryEdit;
460
460
  }(_react.Component), _class2.propTypes = {
461
+ addContentPopoverOpen: _propTypes.default.bool.isRequired,
462
+ alternativeRightFooter: _propTypes.default.func,
463
+ appContainer: _CustomPropTypes.default.selectors.isRequired,
464
+ changeItemTitle: _propTypes.default.func.isRequired,
465
+ // from connected component
466
+ changeQuizEntryPoints: _propTypes.default.func.isRequired,
467
+ // from connected component
461
468
  children: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.node), _propTypes.default.node]),
462
469
  clearModifications: _propTypes.default.func.isRequired,
463
470
  // from connected component
@@ -467,6 +474,7 @@ var QuizEntryEdit = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
467
474
  // from connected component
468
475
  cloneQuizEntry: _propTypes.default.func.isRequired,
469
476
  // from connected component
477
+ clearValidationErrorsFromApi: _propTypes.default.func.isRequired,
470
478
  connectDragPreview: _propTypes.default.func.isRequired,
471
479
  // inserted from React DnD
472
480
  connectDragSource: _propTypes.default.func.isRequired,
@@ -480,17 +488,29 @@ var QuizEntryEdit = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
480
488
  createQuizEntry: _propTypes.default.func.isRequired,
481
489
  // from connected component
482
490
  disabledForRegrade: _propTypes.default.bool,
491
+ displayPosition: _propTypes.default.number.isRequired,
483
492
  draggingAboveHalf: _propTypes.default.bool.isRequired,
484
493
  draggingOver: _propTypes.default.bool.isRequired,
485
494
  entry: _reactImmutableProptypes.default.record.isRequired,
486
495
  guid: _propTypes.default.string.isRequired,
487
- addContentPopoverOpen: _propTypes.default.bool.isRequired,
496
+ handleValidationErrorsFromApi: _propTypes.default.func.isRequired,
497
+ haveValidationErrorsFromApi: _propTypes.default.bool,
498
+ hideError: _propTypes.default.func.isRequired,
499
+ // from connected component
500
+ initialFocusId: _propTypes.default.string,
488
501
  isOccluded: _propTypes.default.bool,
502
+ name: _propTypes.default.string,
489
503
  nextQuizEntry: _reactImmutableProptypes.default.map,
490
504
  openRegradeModal: _propTypes.default.func.isRequired,
491
505
  quizEntries: _reactImmutableProptypes.default.listOf(_reactImmutableProptypes.default.record).isRequired,
506
+ onEditQuizEntryToggle: _propTypes.default.func,
507
+ openModal: _propTypes.default.func.isRequired,
492
508
  quizEntry: _reactImmutableProptypes.default.record.isRequired,
493
509
  quizId: _propTypes.default.string.isRequired,
510
+ removeQuizEntry: _propTypes.default.func.isRequired,
511
+ // from connected component
512
+ richFITBEnabled: _propTypes.default.bool,
513
+ richFITBInteractionID: _propTypes.default.string,
494
514
  screenreaderNotification: _propTypes.default.func.isRequired,
495
515
  // from connected component
496
516
  setUi: _propTypes.default.func.isRequired,
@@ -502,38 +522,22 @@ var QuizEntryEdit = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
502
522
  // from connected component
503
523
  updateItem: _propTypes.default.func.isRequired,
504
524
  // from connected component
505
- workingEntry: _reactImmutableProptypes.default.record.isRequired,
506
- workingQuizEntry: _reactImmutableProptypes.default.record.isRequired,
507
- appContainer: _CustomPropTypes.default.selectors.isRequired,
508
- alternativeRightFooter: _propTypes.default.func,
509
- changeItemTitle: _propTypes.default.func.isRequired,
510
- // from connected component
511
- changeQuizEntryPoints: _propTypes.default.func.isRequired,
512
- // from connected component
513
- displayPosition: _propTypes.default.number.isRequired,
514
- hideError: _propTypes.default.func.isRequired,
515
- // from connected component
516
- name: _propTypes.default.string,
517
- openModal: _propTypes.default.func.isRequired,
518
- removeQuizEntry: _propTypes.default.func.isRequired,
519
- // from connected component
520
525
  withConfirm: _propTypes.default.func.isRequired,
521
- initialFocusId: _propTypes.default.string,
522
- onEditQuizEntryToggle: _propTypes.default.func,
523
- clearValidationErrorsFromApi: _propTypes.default.func.isRequired,
524
- handleValidationErrorsFromApi: _propTypes.default.func.isRequired,
525
- haveValidationErrorsFromApi: _propTypes.default.bool
526
+ workingEntry: _reactImmutableProptypes.default.record.isRequired,
527
+ workingQuizEntry: _reactImmutableProptypes.default.record.isRequired
526
528
  }, _class2.defaultProps = {
527
529
  alternativeRightFooter: null,
528
530
  children: null,
529
531
  disabledForRegrade: false,
532
+ haveValidationErrorsFromApi: false,
530
533
  initialFocusId: null,
531
534
  isOccluded: false,
532
535
  name: null,
533
536
  nextQuizEntry: null,
534
537
  onEditQuizEntryToggle: Function.prototype,
535
- shouldClone: false,
536
- haveValidationErrorsFromApi: false
538
+ richFITBEnabled: false,
539
+ richFITBInteractionID: '',
540
+ shouldClone: false
537
541
  }, _temp)) || _class);
538
542
  var UndecoratedQuizEntryEdit = QuizEntryEdit;
539
543
  exports.UndecoratedQuizEntryEdit = UndecoratedQuizEntryEdit;
@@ -23,19 +23,26 @@ var _quizzes = require("../../../../../common/selectors/quizzes.js");
23
23
 
24
24
  var _quizCommon = require("@instructure/quiz-common");
25
25
 
26
+ var _featureCheck = require("../../../../../common/util/featureCheck.js");
27
+
26
28
  function mapStateToProps(state, props) {
27
29
  var dndPosition = state.getIn(['dragAndDrop', 'position']);
28
30
  var draggingAboveHalf = state.getIn(['dragAndDrop', 'aboveHalf'], false);
29
31
  var draggingOver = props.draggingOnBuild && dndPosition === props.quizEntry.position;
30
32
  var itemModsClear = state.getIn(['modifications', 'items'], (0, _immutable.Map)()).isEmpty();
31
33
  var quizEntryModsClear = state.getIn(['modifications', 'quizEntries'], (0, _immutable.Map)()).isEmpty();
34
+ var richFITBInteraction = state.getIn(['interactionTypes'], (0, _immutable.Map)()).find(function (interactionType) {
35
+ return interactionType.get('slug') === 'rich-fill-blank';
36
+ });
32
37
  return {
33
38
  createItemCallStatus: state.getIn(['calls', _quizCommon.CREATE_ITEM_CALL, 'requestStatus'], ''),
34
- updateItemCallStatus: state.getIn(['calls', _quizCommon.UPDATE_ITEM_CALL, 'requestStatus'], ''),
35
39
  draggingAboveHalf: draggingOver && draggingAboveHalf,
36
40
  draggingOver: draggingOver,
37
41
  modificationsClear: itemModsClear && quizEntryModsClear,
38
- quizEntryWithErrorsShowing: (0, _quizzes.getQuizEntryWithErrorsShowing)(state) || props.haveValidationErrorsFromApi
42
+ quizEntryWithErrorsShowing: (0, _quizzes.getQuizEntryWithErrorsShowing)(state) || props.haveValidationErrorsFromApi,
43
+ richFITBEnabled: (0, _featureCheck.featureOn)('interaction_type_rich_fill_blank'),
44
+ richFITBInteractionID: (richFITBInteraction || (0, _immutable.Map)()).get('id'),
45
+ updateItemCallStatus: state.getIn(['calls', _quizCommon.UPDATE_ITEM_CALL, 'requestStatus'], '')
39
46
  };
40
47
  }
41
48
 
@@ -33,10 +33,14 @@ var _uiA11yContent = require("@instructure/ui-a11y-content");
33
33
 
34
34
  var _uiThemeable = require("@instructure/ui-themeable");
35
35
 
36
+ var _quizInteractions = require("@instructure/quiz-interactions");
37
+
36
38
  var _quizCommon = require("@instructure/quiz-common");
37
39
 
38
40
  var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message"));
39
41
 
42
+ var _fitbCopyHelper = require("../../../../../common/util/fitbCopyHelper.js");
43
+
40
44
  var _Item = _interopRequireDefault(require("../../../../../common/records/Item.js"));
41
45
 
42
46
  var _Overlay = _interopRequireDefault(require("../../../../../common/components/shared/overlay/Overlay.js"));
@@ -137,7 +141,9 @@ var QuizEntryShow = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
137
141
  var _this$props = _this.props,
138
142
  quizId = _this$props.quizId,
139
143
  quizEntry = _this$props.quizEntry,
140
- entry = _this$props.entry;
144
+ entry = _this$props.entry,
145
+ richFITBEnabled = _this$props.richFITBEnabled,
146
+ richFITBInteractionID = _this$props.richFITBInteractionID;
141
147
  var interactionTypeData = {
142
148
  answerFeedback: entry.answerFeedback,
143
149
  calculatorType: entry.calculatorType,
@@ -152,6 +158,10 @@ var QuizEntryShow = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
152
158
  title: entry.title
153
159
  };
154
160
 
161
+ if (richFITBEnabled && entry.getInteractionType() instanceof _quizInteractions.FillBlankInteractionType) {
162
+ interactionTypeData = (0, _fitbCopyHelper.convertFITBtoRich)(interactionTypeData, richFITBInteractionID);
163
+ }
164
+
155
165
  _this.props.createItem(quizId, Math.round(quizEntry.position + 1), interactionTypeData, quizEntry.stimulusQuizEntryId, entry.stimulusId, quizEntry.pointsPossible);
156
166
  };
157
167
 
@@ -346,7 +356,11 @@ var QuizEntryShow = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
346
356
  displayPosition: _propTypes.default.number.isRequired,
347
357
  draggingOver: _propTypes.default.bool.isRequired,
348
358
  draggingAboveHalf: _propTypes.default.bool.isRequired,
359
+ editQuizEntryToggle: _propTypes.default.bool.isRequired,
349
360
  entry: _reactImmutableProptypes.default.record.isRequired,
361
+ haveValidationErrorsFromApi: _propTypes.default.bool,
362
+ // only used in index.js
363
+ interactionTypeName: _propTypes.default.string,
350
364
  modificationsClear: _propTypes.default.bool.isRequired,
351
365
  quizEntryWithErrorsShowing: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.object]),
352
366
  quizEntries: _reactImmutableProptypes.default.listOf(_reactImmutableProptypes.default.record).isRequired,
@@ -354,18 +368,16 @@ var QuizEntryShow = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
354
368
  quizId: _propTypes.default.string.isRequired,
355
369
  removeQuizEntry: _propTypes.default.func.isRequired,
356
370
  // from connected component
371
+ richFITBEnabled: _propTypes.default.bool,
372
+ richFITBInteractionID: _propTypes.default.string,
357
373
  screenreaderNotification: _propTypes.default.func.isRequired,
358
374
  // from connected component
359
375
  scrollKey: _propTypes.default.string,
376
+ stimulusOrientation: _propTypes.default.string,
360
377
  switchOnEditing: _propTypes.default.func.isRequired,
361
378
  // from QuizEntry
362
379
  updateItemCallStatus: _propTypes.default.string.isRequired,
363
- withConfirm: _propTypes.default.func.isRequired,
364
- editQuizEntryToggle: _propTypes.default.bool.isRequired,
365
- haveValidationErrorsFromApi: _propTypes.default.bool,
366
- // only used in index.js
367
- interactionTypeName: _propTypes.default.string,
368
- stimulusOrientation: _propTypes.default.string
380
+ withConfirm: _propTypes.default.func.isRequired
369
381
  }, _class2.defaultProps = {
370
382
  children: null,
371
383
  draggingOver: false,
@@ -375,6 +387,8 @@ var QuizEntryShow = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
375
387
  editQuizEntryToggle: false,
376
388
  haveValidationErrorsFromApi: false,
377
389
  interactionTypeName: null,
390
+ richFITBEnabled: false,
391
+ richFITBInteractionID: '',
378
392
  stimulusOrientation: null
379
393
  }, _temp)) || _class);
380
394
  var QuizEntryShowRaw = QuizEntryShow;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.convertFITBtoRich = convertFITBtoRich;
7
+
8
+ var _immutable = require("immutable");
9
+
10
+ function convertFITBtoRich(interactionTypeData, richFITBInteractionID) {
11
+ var interactionData = interactionTypeData.interactionData,
12
+ scoringData = interactionTypeData.scoringData;
13
+ var sortedStemItems = interactionData.get('stemItems').sort(function (a, b) {
14
+ return a.get('position') - b.get('position');
15
+ });
16
+ var workingItemBody = sortedStemItems.reduce(function (itemBody, stemItem) {
17
+ if (stemItem.get('type') === 'text') {
18
+ return itemBody + stemItem.get('value', '');
19
+ } else {
20
+ var blankScoringData = scoringData.get('value', (0, _immutable.List)()).find(function (blank) {
21
+ return blank.get('id') === stemItem.get('blankId');
22
+ }) || (0, _immutable.Map)();
23
+ return itemBody + "`".concat(blankScoringData.getIn(['scoringData', 'blankText']), "`");
24
+ }
25
+ }, '');
26
+ return Object.assign({}, interactionTypeData, {
27
+ id: richFITBInteractionID,
28
+ itemBody: '',
29
+ interactionData: {
30
+ blanks: interactionData.get('blanks', [])
31
+ },
32
+ scoringData: {
33
+ workingItemBody: "".concat(interactionData.get('prompt', ''), "<p>").concat(workingItemBody, "</p>"),
34
+ value: scoringData.get('value', [])
35
+ }
36
+ });
37
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/quiz-core",
3
- "version": "17.26.1-rc.0+966b51d7e",
3
+ "version": "17.27.0",
4
4
  "license": "MIT",
5
5
  "description": "The Quiz React SDK by Instructure Inc.",
6
6
  "author": "Instructure, Inc. Engineering and Product Design",
@@ -41,11 +41,11 @@
41
41
  ],
42
42
  "dependencies": {
43
43
  "@instructure/outcomes-ui": "^2.1.2",
44
- "@instructure/quiz-common": "17.26.1-rc.0+966b51d7e",
45
- "@instructure/quiz-i18n": "17.26.1-rc.0+966b51d7e",
46
- "@instructure/quiz-interactions": "17.26.1-rc.0+966b51d7e",
47
- "@instructure/quiz-number-input": "17.26.1-rc.0+966b51d7e",
48
- "@instructure/quiz-rce": "17.26.1-rc.0+966b51d7e",
44
+ "@instructure/quiz-common": "^17.27.0",
45
+ "@instructure/quiz-i18n": "^17.27.0",
46
+ "@instructure/quiz-interactions": "^17.27.0",
47
+ "@instructure/quiz-number-input": "^17.27.0",
48
+ "@instructure/quiz-rce": "^17.27.0",
49
49
  "@instructure/ui-a11y-content": "^7.11.0",
50
50
  "@instructure/ui-alerts": "^7.11.0",
51
51
  "@instructure/ui-avatar": "^7.11.0",
@@ -106,7 +106,7 @@
106
106
  "eventemitter3": "^3.1.0",
107
107
  "humps": "^2.0.0",
108
108
  "immutable": "^3.8.1",
109
- "instructure-validations": "17.26.1-rc.0+966b51d7e",
109
+ "instructure-validations": "^17.27.0",
110
110
  "ipaddr.js": "^1.5.4",
111
111
  "isomorphic-fetch": "^2.2.0",
112
112
  "isuuid": "^0.1.0",
@@ -137,7 +137,7 @@
137
137
  "uuid": "^3.2.1"
138
138
  },
139
139
  "devDependencies": {
140
- "@instructure/quiz-scripts": "17.26.1-rc.0+966b51d7e",
140
+ "@instructure/quiz-scripts": "^17.27.0",
141
141
  "@instructure/ui-axe-check": "^7.11.0",
142
142
  "@instructure/ui-babel-preset": "^7.11.0",
143
143
  "@instructure/ui-karma-config": "^7.11.0",
@@ -156,7 +156,7 @@
156
156
  "intl": "^1.2.4",
157
157
  "jquery": "^2.2.3",
158
158
  "most-subject": "^5.3.0",
159
- "quiz-presets": "17.26.1-rc.0+966b51d7e",
159
+ "quiz-presets": "^17.27.0",
160
160
  "react": "^16.8.6",
161
161
  "react-addons-test-utils": "^15.6.2",
162
162
  "react-dom": "^16.8.6",
@@ -172,5 +172,5 @@
172
172
  "publishConfig": {
173
173
  "access": "public"
174
174
  },
175
- "gitHead": "966b51d7eefdf2f966da94c7a97a98db2dcfd508"
175
+ "gitHead": "b1455dfd44cf4094964ff5a2e4c5843d4b3c2cc0"
176
176
  }