@instructure/quiz-core 21.0.2 → 21.1.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.
Files changed (45) hide show
  1. package/es/building/components/layout/header/BuildingButtons/theme.js +1 -1
  2. package/es/common/actions/taking.js +3 -2
  3. package/es/common/components/layout/navbar/theme.js +1 -1
  4. package/es/common/components/resources/stimulus/StimulusEditInfo/index.js +5 -1
  5. package/es/common/components/resources/stimulus/StimulusEditInfo/presenter.js +15 -2
  6. package/es/common/components/resources/stimulus/StimulusShow/index.js +1 -1
  7. package/es/common/components/shared/Card/CardWrapper/theme.js +1 -1
  8. package/es/common/reducers/taking.js +5 -1
  9. package/es/common/selectors/taking.js +3 -0
  10. package/es/common/util/getClientIpAddress.js +35 -0
  11. package/es/common/util/serializeEvent.js +4 -2
  12. package/es/index.js +2 -3
  13. package/es/moderating/components/events/Event.js +27 -10
  14. package/es/moderating/components/events/ResponseEvent.js +24 -7
  15. package/es/moderating/components/events/SessionStartEvent.js +16 -15
  16. package/es/moderating/components/events/SessionSubmitEvent.js +42 -0
  17. package/es/moderating/components/resources/EventDetails.js +43 -0
  18. package/es/moderating/components/resources/SessionBreachAlert.js +10 -0
  19. package/es/moderating/components/resources/util/checkIsBreach.js +28 -0
  20. package/es/moderating/components/resources/util/extractSessionData.js +20 -0
  21. package/es/reporting/components/resources/common/propTypes.js +14 -0
  22. package/es/taking/api/taking.js +26 -3
  23. package/lib/building/components/layout/header/BuildingButtons/theme.js +1 -1
  24. package/lib/common/actions/taking.js +3 -2
  25. package/lib/common/components/layout/navbar/theme.js +1 -1
  26. package/lib/common/components/resources/stimulus/StimulusEditInfo/index.js +5 -1
  27. package/lib/common/components/resources/stimulus/StimulusEditInfo/presenter.js +15 -2
  28. package/lib/common/components/resources/stimulus/StimulusShow/index.js +1 -1
  29. package/lib/common/components/shared/Card/CardWrapper/theme.js +1 -1
  30. package/lib/common/reducers/taking.js +5 -1
  31. package/lib/common/selectors/taking.js +5 -1
  32. package/lib/common/util/getClientIpAddress.js +43 -0
  33. package/lib/common/util/serializeEvent.js +3 -1
  34. package/lib/index.js +15 -0
  35. package/lib/moderating/components/events/Event.js +26 -9
  36. package/lib/moderating/components/events/ResponseEvent.js +25 -7
  37. package/lib/moderating/components/events/SessionStartEvent.js +16 -15
  38. package/lib/moderating/components/events/SessionSubmitEvent.js +52 -0
  39. package/lib/moderating/components/resources/EventDetails.js +51 -0
  40. package/lib/moderating/components/resources/SessionBreachAlert.js +18 -0
  41. package/lib/moderating/components/resources/util/checkIsBreach.js +36 -0
  42. package/lib/moderating/components/resources/util/extractSessionData.js +28 -0
  43. package/lib/reporting/components/resources/common/propTypes.js +18 -2
  44. package/lib/taking/api/taking.js +26 -3
  45. package/package.json +8 -8
@@ -1,3 +1,5 @@
1
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
1
3
  // =============================================
2
4
  // =============================================
3
5
 
@@ -25,6 +27,7 @@ import { getSessionItems, handleQuizSessionFetch } from "../../common/actions/qu
25
27
  import { handleSessionItemsResponse, handleResumeDataResponse, handleQuizSessionResponse } from "../../common/api/callHandlers.js";
26
28
  import * as modalActions from "../../common/actions/modal.js";
27
29
  import { backtrackingNextQuestion, sessionStartOrResumeEvent, setCurrentSessionItemPosition, submitQuizSessionEvent, updateQuizSubmitFlag, updateQuizSessionStatusOnPageLoad, updateTimerInfo } from "../../common/actions/taking.js";
30
+ import { getClientIpAddress } from "../../common/util/getClientIpAddress.js";
28
31
  var getQuizSessionConfig = function getQuizSessionConfig(quizSession) {
29
32
  // these should be handled by existing functions
30
33
  var oneQuestionAtATime = quizSession.isOneQuestionAtATime();
@@ -144,9 +147,29 @@ export function newQuizTakingSession(quizSessionId) {
144
147
  };
145
148
  }
146
149
  export function onQuizSessionReadyForTaking(quizSession) {
147
- return function (dispatch) {
148
- dispatch([makeSessionItemCall(quizSession), getResumeData(quizSession.id), sessionStartOrResumeEvent(navigator.userAgent), updateQuizSessionStatusOnPageLoad(quizSession.status)]);
149
- };
150
+ return /*#__PURE__*/function () {
151
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(dispatch) {
152
+ var ipAddress;
153
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
154
+ while (1) {
155
+ switch (_context.prev = _context.next) {
156
+ case 0:
157
+ _context.next = 2;
158
+ return getClientIpAddress(quizSession.id);
159
+ case 2:
160
+ ipAddress = _context.sent;
161
+ dispatch([makeSessionItemCall(quizSession), getResumeData(quizSession.id), sessionStartOrResumeEvent(navigator.userAgent, ipAddress), updateQuizSessionStatusOnPageLoad(quizSession.status)]);
162
+ case 4:
163
+ case "end":
164
+ return _context.stop();
165
+ }
166
+ }
167
+ }, _callee);
168
+ }));
169
+ return function (_x) {
170
+ return _ref.apply(this, arguments);
171
+ };
172
+ }();
150
173
  }
151
174
 
152
175
  // ====================================
@@ -11,7 +11,7 @@ var generateComponentTheme = function generateComponentTheme(_ref) {
11
11
  return {
12
12
  quizSavingColor: colors.lightGray,
13
13
  quizSavingMargin: spacing.large,
14
- buttonsHolderMargin: spacing.xLarge,
14
+ buttonsHolderMargin: spacing.mediumSmall,
15
15
  menuIconMargin: spacing.xSmall,
16
16
  menuIconFontSize: typography.fontSizeLarge
17
17
  };
@@ -122,12 +122,13 @@ var loadResumeData = function loadResumeData(resumeData) {
122
122
  };
123
123
  };
124
124
  exports.loadResumeData = loadResumeData;
125
- var sessionStartOrResumeEvent = function sessionStartOrResumeEvent(userAgent) {
125
+ var sessionStartOrResumeEvent = function sessionStartOrResumeEvent(userAgent, ipAddress) {
126
126
  return {
127
127
  type: _quizCommon.SESSION_STARTED_OR_RESUMED_EVENT,
128
128
  payload: {
129
129
  userAgent: userAgent,
130
- browserSessionId: (0, _uuid.v4)()
130
+ browserSessionId: (0, _uuid.v4)(),
131
+ ipAddress: ipAddress
131
132
  }
132
133
  };
133
134
  };
@@ -8,7 +8,7 @@ var generateComponentTheme = function generateComponentTheme(_ref) {
8
8
  var breakpoints = _ref.breakpoints,
9
9
  colors = _ref.colors;
10
10
  return {
11
- backgroundColor: colors.porcelain,
11
+ backgroundColor: colors.white,
12
12
  phoneBreakPoint: breakpoints.medium
13
13
  };
14
14
  };
@@ -10,12 +10,16 @@ var _redux = require("redux");
10
10
  var _reactRedux = require("../../../../react-redux.js");
11
11
  var modificationActions = _interopRequireWildcard(require("../../../../actions/modifications.js"));
12
12
  var _featureCheck = require("../../../../../common/util/featureCheck.js");
13
+ var _quizzes = require("../../../../../common/selectors/quizzes.js");
13
14
  var _presenter = _interopRequireDefault(require("./presenter.js"));
14
15
  function mapStateToProps(state, props) {
16
+ var quizId = (0, _quizzes.getActiveQuizId)(state);
17
+ var quiz = (0, _quizzes.getQuizById)(state, quizId);
15
18
  return {
16
19
  workingStimulus: props.stimulus.getWorkingInstance(),
17
20
  errorsShowing: state.getIn(['errorsShowing', props.guid], props.errorsShowing || false),
18
- stimulusOrientationEnabled: (0, _featureCheck.featureOn)('customizable_stimulus_orientation')
21
+ stimulusOrientationEnabled: (0, _featureCheck.featureOn)('customizable_stimulus_orientation'),
22
+ shuffleQuestionsEnabled: quiz.shuffleQuestions
19
23
  };
20
24
  }
21
25
  function mapDispatchToProps(dispatch) {
@@ -23,6 +23,7 @@ var _quizCommon = require("@instructure/quiz-common");
23
23
  var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message"));
24
24
  var _styles = _interopRequireDefault(require("./styles.js"));
25
25
  var _theme = _interopRequireDefault(require("./theme.js"));
26
+ var _uiAlerts = require("@instructure/ui-alerts");
26
27
  var _dec, _class, _StimulusEditInfo;
27
28
  /** @jsx jsx */
28
29
  var _ref3 = (0, _emotion.jsx)(_uiIcons.IconUpdownLine, {
@@ -103,6 +104,16 @@ var StimulusEditInfo = (_dec = (0, _quizCommon.withStyleOverrides)(_styles.defau
103
104
  value: "top"
104
105
  }, (0, _formatMessage.default)('Questions below'))));
105
106
  }
107
+ }, {
108
+ key: "renderPassageAlert",
109
+ value: function renderPassageAlert(stimulus) {
110
+ if (!stimulus.passage || !this.props.shuffleQuestionsEnabled) {
111
+ return null;
112
+ }
113
+ return (0, _emotion.jsx)(_uiAlerts.Alert, {
114
+ variant: "warning"
115
+ }, (0, _formatMessage.default)('The passage sections may not appear in their original order due to the shuffle setting.'));
116
+ }
106
117
  }, {
107
118
  key: "renderInstructions",
108
119
  value: function renderInstructions(stimulus) {
@@ -153,7 +164,7 @@ var StimulusEditInfo = (_dec = (0, _quizCommon.withStyleOverrides)(_styles.defau
153
164
  }, (0, _emotion.jsx)(_uiHeading.Heading, {
154
165
  level: "h3",
155
166
  as: "h2"
156
- }, this.headerText(stimulus)), (0, _emotion.jsx)("div", {
167
+ }, this.headerText(stimulus)), this.renderPassageAlert(stimulus), (0, _emotion.jsx)("div", {
157
168
  css: this.props.styles.section
158
169
  }, (0, _emotion.jsx)(_quizCommon.TextInput, {
159
170
  messages: this.inputErrors('title'),
@@ -191,9 +202,11 @@ var StimulusEditInfo = (_dec = (0, _quizCommon.withStyleOverrides)(_styles.defau
191
202
  modifyStimulus: _propTypes.default.func.isRequired,
192
203
  setTitleRef: _propTypes.default.func,
193
204
  stimulusOrientationEnabled: _propTypes.default.bool.isRequired,
194
- styles: _propTypes.default.object
205
+ styles: _propTypes.default.object,
206
+ shuffleQuestionsEnabled: _propTypes.default.bool
195
207
  }, _StimulusEditInfo.defaultProps = {
196
208
  isBankedContent: false,
209
+ shuffleQuestionsEnabled: false,
197
210
  setTitleRef: function setTitleRef() {}
198
211
  }, _StimulusEditInfo)) || _class);
199
212
  exports.StimulusEditInfo = StimulusEditInfo;
@@ -15,13 +15,13 @@ var _reactImmutableProptypes = _interopRequireDefault(require("react-immutable-p
15
15
  var _uiIcons = require("@instructure/ui-icons");
16
16
  var _emotion = require("@instructure/emotion");
17
17
  var _uiText = require("@instructure/ui-text");
18
+ var _quizCommon = require("@instructure/quiz-common");
18
19
  var _index = _interopRequireDefault(require("../StimulusShowInfo/index.js"));
19
20
  var _index2 = _interopRequireDefault(require("../../../../../building/components/resources/ActionButtons/index.js"));
20
21
  var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message"));
21
22
  var _styles = _interopRequireDefault(require("./styles.js"));
22
23
  var _theme = _interopRequireDefault(require("./theme.js"));
23
24
  var _index3 = _interopRequireDefault(require("../../../shared/overlay/index.js"));
24
- var _quizCommon = require("@instructure/quiz-common");
25
25
  var _dec, _class, _StimulusShow;
26
26
  /** @jsx jsx */
27
27
  /* eslint "jsx-a11y/click-events-have-key-events": "warn" */
@@ -9,7 +9,7 @@ var generateComponentTheme = function generateComponentTheme(_ref) {
9
9
  breakpoints = _ref.breakpoints,
10
10
  transitions = _ref.transitions;
11
11
  return {
12
- wrapperPadding: spacing.medium,
12
+ wrapperPadding: spacing.mediumSmall,
13
13
  wrapperTransitionDuration: transitions.duration,
14
14
  phoneBreakPoint: "max-width: ".concat(breakpoints.medium),
15
15
  phoneWrapperPadding: spacing.medium
@@ -73,7 +73,11 @@ var loadResponses = function loadResponses(state, payload) {
73
73
  return payload.reduce(modifyResponse, state);
74
74
  };
75
75
  var markSessionStartedIdentifier = function markSessionStartedIdentifier(state, payload) {
76
- return state.get('browserSessionId') === payload.browserSessionId ? state : state.set('browserSessionId', payload.browserSessionId);
76
+ var needsUpdate = state.get('browserSessionId') !== payload.browserSessionId || state.get('ipAddress') !== payload.ipAddress;
77
+ return needsUpdate ? state.merge({
78
+ browserSessionId: payload.browserSessionId,
79
+ ipAddress: payload.ipAddress
80
+ }) : state;
77
81
  };
78
82
  var updateQuizSubmitFlag = function updateQuizSubmitFlag(state, payload) {
79
83
  return state.set('submitFlag', payload.value);
@@ -8,7 +8,7 @@ exports.isTimeUp = isTimeUp;
8
8
  exports.getResponsesByIds = getResponsesByIds;
9
9
  exports.getResponseById = getResponseById;
10
10
  exports.getResponseDataByPosition = getResponseDataByPosition;
11
- exports.getIsTaking = exports.getTimerData = exports.getBrowserSessionId = exports.getCurrentSessionItemPosition = void 0;
11
+ exports.getIsTaking = exports.getTimerData = exports.getIpAddress = exports.getBrowserSessionId = exports.getCurrentSessionItemPosition = void 0;
12
12
  var _immutable = require("immutable");
13
13
  var _Response = _interopRequireDefault(require("../records/Response.js"));
14
14
  var path = 'taking';
@@ -20,6 +20,10 @@ var getBrowserSessionId = function getBrowserSessionId(state) {
20
20
  return state.getIn([path, 'browserSessionId']);
21
21
  };
22
22
  exports.getBrowserSessionId = getBrowserSessionId;
23
+ var getIpAddress = function getIpAddress(state) {
24
+ return state.getIn([path, 'ipAddress']);
25
+ };
26
+ exports.getIpAddress = getIpAddress;
23
27
  var getTimerData = function getTimerData(state) {
24
28
  return state.getIn([path, 'timerData'], (0, _immutable.Map)());
25
29
  };
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getClientIpAddress = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
+ var _Fetcher = _interopRequireDefault(require("./Fetcher.js"));
11
+ var getClientIpAddress = /*#__PURE__*/function () {
12
+ var _ref = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(quizSessionId) {
13
+ var url, fetcher, _yield$fetcher$get, ip;
14
+ return _regenerator.default.wrap(function _callee$(_context) {
15
+ while (1) {
16
+ switch (_context.prev = _context.next) {
17
+ case 0:
18
+ _context.prev = 0;
19
+ url = "/api/quiz_sessions/".concat(quizSessionId, "/get_ip_address");
20
+ fetcher = new _Fetcher.default();
21
+ _context.next = 5;
22
+ return fetcher.get(url);
23
+ case 5:
24
+ _yield$fetcher$get = _context.sent;
25
+ ip = _yield$fetcher$get.ip;
26
+ return _context.abrupt("return", ip);
27
+ case 10:
28
+ _context.prev = 10;
29
+ _context.t0 = _context["catch"](0);
30
+ console.error(_context.t0);
31
+ return _context.abrupt("return", null);
32
+ case 14:
33
+ case "end":
34
+ return _context.stop();
35
+ }
36
+ }
37
+ }, _callee, null, [[0, 10]]);
38
+ }));
39
+ return function getClientIpAddress(_x) {
40
+ return _ref.apply(this, arguments);
41
+ };
42
+ }();
43
+ exports.getClientIpAddress = getClientIpAddress;
@@ -17,8 +17,10 @@ function serializeEvent(action, store) {
17
17
  var state = store.getState();
18
18
  var quizSession = (0, _quizSessions.getActiveQuizSession)(state);
19
19
  var defaultEventData = {
20
+ userAgent: navigator.userAgent,
20
21
  browserSessionId: (0, _taking.getBrowserSessionId)(state),
21
- clientTimestamp: new Date()
22
+ clientTimestamp: new Date(),
23
+ ipAddress: (0, _taking.getIpAddress)(state)
22
24
  };
23
25
  var authoritativeData = {
24
26
  accountUuid: quizSession.accountUuid,
package/lib/index.js CHANGED
@@ -118,6 +118,7 @@ var _exportNames = {
118
118
  setThemeByKey: true,
119
119
  getActiveTheme: true,
120
120
  setActiveTheme: true,
121
+ getClientIpAddress: true,
121
122
  createQuizEntryRegrade: true,
122
123
  getQuizEntry: true,
123
124
  moveQuizEntry: true,
@@ -203,6 +204,7 @@ var _exportNames = {
203
204
  getQuizById: true,
204
205
  getActiveQuizId: true,
205
206
  getQuizEntryById: true,
207
+ getQuizEntriesByQuizId: true,
206
208
  isActiveQuizWorkingInstanceOneQuestionAtATime: true,
207
209
  getActiveQuiz: true,
208
210
  getItemById: true,
@@ -891,6 +893,12 @@ Object.defineProperty(exports, "setActiveTheme", {
891
893
  return _quizCommon.setActiveTheme;
892
894
  }
893
895
  });
896
+ Object.defineProperty(exports, "getClientIpAddress", {
897
+ enumerable: true,
898
+ get: function get() {
899
+ return _getClientIpAddress.getClientIpAddress;
900
+ }
901
+ });
894
902
  Object.defineProperty(exports, "createQuizEntryRegrade", {
895
903
  enumerable: true,
896
904
  get: function get() {
@@ -1383,6 +1391,12 @@ Object.defineProperty(exports, "getQuizEntryById", {
1383
1391
  return _quizzes3.getQuizEntryById;
1384
1392
  }
1385
1393
  });
1394
+ Object.defineProperty(exports, "getQuizEntriesByQuizId", {
1395
+ enumerable: true,
1396
+ get: function get() {
1397
+ return _quizzes3.getQuizEntriesByQuizId;
1398
+ }
1399
+ });
1386
1400
  Object.defineProperty(exports, "isActiveQuizWorkingInstanceOneQuestionAtATime", {
1387
1401
  enumerable: true,
1388
1402
  get: function get() {
@@ -1571,6 +1585,7 @@ var _sessionStore = require("./common/util/sessionStore.js");
1571
1585
  var _printUtils = require("./common/util/printUtils.js");
1572
1586
  var _rceChecker = require("./common/util/rceChecker.js");
1573
1587
  var _quizCommon = require("@instructure/quiz-common");
1588
+ var _getClientIpAddress = require("./common/util/getClientIpAddress.js");
1574
1589
  var _quizEntryRegrades = require("./grading/api/quizEntryRegrades.js");
1575
1590
  var _quizEntries = require("./building/api/quizEntries.js");
1576
1591
  var _items = require("./building/api/items.js");
@@ -18,9 +18,12 @@ var _uiTable = require("@instructure/ui-table");
18
18
  var _ElapsedTime = _interopRequireDefault(require("../resources/ElapsedTime.js"));
19
19
  var _ResponseEvent = _interopRequireDefault(require("./ResponseEvent.js"));
20
20
  var _SessionStartEvent = _interopRequireDefault(require("./SessionStartEvent.js"));
21
+ var _SessionSubmitEvent = require("./SessionSubmitEvent.js");
21
22
  var _RCEEvent = _interopRequireDefault(require("./RCEEvent.js"));
22
23
  var _PageBlurredEvent = _interopRequireDefault(require("./PageBlurredEvent.js"));
23
24
  var _PageFocusedEvent = _interopRequireDefault(require("./PageFocusedEvent.js"));
25
+ var _extractSessionData = require("../resources/util/extractSessionData.js");
26
+ var _checkIsBreach = require("../resources/util/checkIsBreach.js");
24
27
  var _Event;
25
28
  var _ref = /*#__PURE__*/_react.default.createElement(_PageBlurredEvent.default, null);
26
29
  var _ref2 = /*#__PURE__*/_react.default.createElement(_PageFocusedEvent.default, null);
@@ -33,26 +36,34 @@ var Event = /*#__PURE__*/function (_Component) {
33
36
  }
34
37
  (0, _createClass2.default)(Event, [{
35
38
  key: "renderResponseEvent",
36
- value: function renderResponseEvent(event) {
39
+ value: function renderResponseEvent(event, validationErrors, currentEventData) {
37
40
  var item = event.getItem();
38
41
  if (!item) {
39
42
  return null;
40
43
  } else {
41
44
  return /*#__PURE__*/_react.default.createElement(_ResponseEvent.default, {
42
45
  event: event,
43
- item: item
46
+ item: item,
47
+ validationErrors: validationErrors,
48
+ currentEventData: currentEventData
44
49
  });
45
50
  }
46
51
  }
47
52
  }, {
48
53
  key: "renderPayload",
49
- value: function renderPayload(event) {
54
+ value: function renderPayload(event, validationErrors, currentEventData) {
50
55
  switch (event.eventType) {
51
56
  case _quizCommon.RESPONSE:
52
- return this.renderResponseEvent(event);
57
+ return this.renderResponseEvent(event, validationErrors, currentEventData);
53
58
  case _quizCommon.SESSION_STARTED_OR_RESUMED_EVENT:
54
59
  return /*#__PURE__*/_react.default.createElement(_SessionStartEvent.default, {
55
- event: event
60
+ validationErrors: validationErrors,
61
+ currentEventData: currentEventData
62
+ });
63
+ case _quizCommon.QUIZ_SUBMISSION_EVENT:
64
+ return /*#__PURE__*/_react.default.createElement(_SessionSubmitEvent.SessionSubmitEvent, {
65
+ validationErrors: validationErrors,
66
+ currentEventData: currentEventData
56
67
  });
57
68
  case _quizCommon.RCE_EVENT:
58
69
  return /*#__PURE__*/_react.default.createElement(_RCEEvent.default, {
@@ -72,8 +83,12 @@ var Event = /*#__PURE__*/function (_Component) {
72
83
  value: function render() {
73
84
  var _this$props = this.props,
74
85
  event = _this$props.event,
75
- startTime = _this$props.startTime;
76
- var payloadNode = this.renderPayload(event);
86
+ startTime = _this$props.startTime,
87
+ firstEvent = _this$props.firstEvent;
88
+ var currentEventData = (0, _extractSessionData.extractSessionData)(event);
89
+ var firstEventData = (0, _extractSessionData.extractSessionData)(firstEvent);
90
+ var validationErrors = (0, _checkIsBreach.checkIsBreach)(firstEventData, currentEventData);
91
+ var payloadNode = this.renderPayload(event, validationErrors, currentEventData);
77
92
  if (!payloadNode) return null;
78
93
  return /*#__PURE__*/_react.default.createElement(_uiTable.Table.Row, null, /*#__PURE__*/_react.default.createElement(_uiTable.Table.Cell, null, /*#__PURE__*/_react.default.createElement(_ElapsedTime.default, {
79
94
  eventTime: event.createdDate(),
@@ -91,11 +106,13 @@ Event.displayName = 'Row';
91
106
  Event.componentId = "Quizzes".concat(_Event.displayName);
92
107
  Event.propTypes = {
93
108
  event: _reactImmutableProptypes.default.record,
94
- startTime: _propTypes.default.instanceOf(Date)
109
+ startTime: _propTypes.default.instanceOf(Date),
110
+ firstEvent: _reactImmutableProptypes.default.record
95
111
  };
96
112
  Event.defaultProps = {
97
113
  event: void 0,
98
- startTime: void 0
114
+ startTime: void 0,
115
+ firstEvent: void 0
99
116
  };
100
117
  var _default = Event;
101
118
  exports.default = _default;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
4
5
  Object.defineProperty(exports, "__esModule", {
5
6
  value: true
6
7
  });
@@ -9,7 +10,7 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/cl
9
10
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
11
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
11
12
  var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper"));
12
- var _react = require("react");
13
+ var _react = _interopRequireWildcard(require("react"));
13
14
  var _reactImmutableProptypes = _interopRequireDefault(require("react-immutable-proptypes"));
14
15
  var _propTypes = _interopRequireDefault(require("prop-types"));
15
16
  var _uiIcons = require("@instructure/ui-icons");
@@ -19,9 +20,11 @@ var _uiToggleDetails = require("@instructure/ui-toggle-details");
19
20
  var _emotion = require("@instructure/emotion");
20
21
  var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message"));
21
22
  var _quizInteractions = require("@instructure/quiz-interactions");
23
+ var _EventDetails = require("../resources/EventDetails.js");
22
24
  var _styles = _interopRequireDefault(require("./styles.js"));
23
25
  var _theme = _interopRequireDefault(require("./theme.js"));
24
26
  var _quizCommon = require("@instructure/quiz-common");
27
+ var _propTypes2 = require("../../../reporting/components/resources/common/propTypes.js");
25
28
  var _dec, _class, _ResponseEvent;
26
29
  /** @jsx jsx */
27
30
  var imgRegex = /<img.*?src=['"](.+)['"]/g;
@@ -51,13 +54,16 @@ var ResponseEvent = (_dec = (0, _quizCommon.withStyleOverrides)(_styles.default,
51
54
  }, {
52
55
  key: "renderTextSummary",
53
56
  value: function renderTextSummary() {
57
+ var isBreach = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : false;
54
58
  var strippedItemBody = (0, _quizInteractions.extractTextFromHtml)(this.itemBody);
55
59
  return (0, _emotion.jsx)("span", null, this.hasMedia() && (0, _emotion.jsx)(_uiIcons.IconImageSolid, {
56
60
  css: this.props.styles.answerMediaIcon
57
- }), (0, _formatMessage.default)('Answered question {position}: {question}', {
61
+ }), (0, _emotion.jsx)(_uiText.Text, {
62
+ color: isBreach ? 'danger' : 'primary'
63
+ }, (0, _formatMessage.default)('Answered question {position}: {question}', {
58
64
  position: this.props.event.getIn(['eventData', 'position']),
59
65
  question: strippedItemBody
60
- }));
66
+ })));
61
67
  }
62
68
  }, {
63
69
  key: "renderMedia",
@@ -85,16 +91,26 @@ var ResponseEvent = (_dec = (0, _quizCommon.withStyleOverrides)(_styles.default,
85
91
  }, {
86
92
  key: "render",
87
93
  value: function render() {
94
+ var _this$props = this.props,
95
+ validationErrors = _this$props.validationErrors,
96
+ currentEventData = _this$props.currentEventData;
88
97
  var responseText = this.getReadableResponseText();
89
98
  if (responseText) {
90
99
  // If this returns falsey, then we know to just display the stem
91
100
  return (0, _emotion.jsx)(_uiToggleDetails.ToggleDetails, {
92
- summary: this.renderTextSummary()
93
- }, this.renderMedia(), responseText);
101
+ summary: this.renderTextSummary(validationErrors.isBreach)
102
+ }, this.renderMedia(), (0, _emotion.jsx)(_EventDetails.EventDetails, {
103
+ currentEventData: currentEventData,
104
+ validationErrors: validationErrors,
105
+ answerValue: responseText
106
+ }));
94
107
  } else {
95
108
  return (0, _emotion.jsx)(_uiText.Text, {
96
109
  size: "small"
97
- }, this.renderTextSummary(), this.renderMedia());
110
+ }, this.renderTextSummary(validationErrors.isBreach), (0, _emotion.jsx)(_EventDetails.EventDetails, {
111
+ currentEventData: currentEventData,
112
+ validationErrors: validationErrors
113
+ }), this.renderMedia());
98
114
  }
99
115
  }
100
116
  }, {
@@ -108,7 +124,9 @@ var ResponseEvent = (_dec = (0, _quizCommon.withStyleOverrides)(_styles.default,
108
124
  }(_react.Component), _ResponseEvent.displayName = 'ResponseEvent', _ResponseEvent.componentId = "Quizzes".concat(_ResponseEvent.displayName), _ResponseEvent.propTypes = {
109
125
  event: _reactImmutableProptypes.default.record.isRequired,
110
126
  item: _reactImmutableProptypes.default.record.isRequired,
111
- styles: _propTypes.default.object
127
+ styles: _propTypes.default.object,
128
+ validationErrors: _propTypes2.sessionValidationErrorsPropType,
129
+ currentEventData: _propTypes2.eventDataPropType
112
130
  }, _ResponseEvent)) || _class);
113
131
  exports.ResponseEvent = ResponseEvent;
114
132
  var _default = ResponseEvent;
@@ -11,11 +11,11 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
11
11
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
12
12
  var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper"));
13
13
  var _react = _interopRequireWildcard(require("react"));
14
- var _reactImmutableProptypes = _interopRequireDefault(require("react-immutable-proptypes"));
15
- var _platform = _interopRequireDefault(require("platform"));
14
+ var _EventDetails = require("../resources/EventDetails.js");
16
15
  var _uiToggleDetails = require("@instructure/ui-toggle-details");
17
- var _uiTable = require("@instructure/ui-table");
18
16
  var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message"));
17
+ var _uiText = require("@instructure/ui-text");
18
+ var _propTypes = require("../../../reporting/components/resources/common/propTypes.js");
19
19
  var SessionStartEvent = /*#__PURE__*/function (_Component) {
20
20
  (0, _inherits2.default)(SessionStartEvent, _Component);
21
21
  var _super = (0, _createSuper2.default)(SessionStartEvent);
@@ -26,18 +26,18 @@ var SessionStartEvent = /*#__PURE__*/function (_Component) {
26
26
  (0, _createClass2.default)(SessionStartEvent, [{
27
27
  key: "render",
28
28
  value: function render() {
29
- var event = this.props.event;
30
- var userPlatform = _platform.default.parse(event.getIn(['eventData', 'userAgent']));
29
+ var _this$props = this.props,
30
+ validationErrors = _this$props.validationErrors,
31
+ currentEventData = _this$props.currentEventData;
32
+ var summary = /*#__PURE__*/_react.default.createElement(_uiText.Text, {
33
+ color: validationErrors.isBreach ? 'danger' : 'primary'
34
+ }, (0, _formatMessage.default)('Session started'));
31
35
  return /*#__PURE__*/_react.default.createElement(_uiToggleDetails.ToggleDetails, {
32
- summary: (0, _formatMessage.default)('Session started')
33
- }, /*#__PURE__*/_react.default.createElement(_uiTable.Table, {
34
- caption: (0, _formatMessage.default)('System details')
35
- }, /*#__PURE__*/_react.default.createElement(_uiTable.Table.Head, null, /*#__PURE__*/_react.default.createElement(_uiTable.Table.Row, null, /*#__PURE__*/_react.default.createElement(_uiTable.Table.ColHeader, {
36
- id: "system-details-attribute"
37
- }, (0, _formatMessage.default)('attribute')), /*#__PURE__*/_react.default.createElement(_uiTable.Table.ColHeader, {
38
- id: "system-details-value"
39
- }, (0, _formatMessage.default)('value')))), /*#__PURE__*/_react.default.createElement(_uiTable.Table.Body, null, /*#__PURE__*/_react.default.createElement(_uiTable.Table.Row, null, /*#__PURE__*/_react.default.createElement(_uiTable.Table.Cell, null, (0, _formatMessage.default)('Browser')), /*#__PURE__*/_react.default.createElement(_uiTable.Table.Cell, null, // eslint-disable-next-line react/jsx-no-literals
40
- "".concat(userPlatform.name, " ").concat(userPlatform.version))), /*#__PURE__*/_react.default.createElement(_uiTable.Table.Row, null, /*#__PURE__*/_react.default.createElement(_uiTable.Table.Cell, null, (0, _formatMessage.default)('Operating System')), /*#__PURE__*/_react.default.createElement(_uiTable.Table.Cell, null, userPlatform.os.toString())))));
36
+ summary: summary
37
+ }, /*#__PURE__*/_react.default.createElement(_EventDetails.EventDetails, {
38
+ currentEventData: currentEventData,
39
+ validationErrors: validationErrors
40
+ }));
41
41
  }
42
42
  }]);
43
43
  SessionStartEvent.displayName = "SessionStartEvent";
@@ -45,7 +45,8 @@ var SessionStartEvent = /*#__PURE__*/function (_Component) {
45
45
  }(_react.Component);
46
46
  exports.SessionStartEvent = SessionStartEvent;
47
47
  SessionStartEvent.propTypes = {
48
- event: _reactImmutableProptypes.default.record.isRequired
48
+ validationErrors: _propTypes.sessionValidationErrorsPropType,
49
+ currentEventData: _propTypes.eventDataPropType
49
50
  };
50
51
  var _default = SessionStartEvent;
51
52
  exports.default = _default;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = exports.SessionSubmitEvent = void 0;
9
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
10
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
11
+ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
12
+ var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper"));
13
+ var _react = _interopRequireWildcard(require("react"));
14
+ var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message"));
15
+ var _EventDetails = require("../resources/EventDetails.js");
16
+ var _uiToggleDetails = require("@instructure/ui-toggle-details");
17
+ var _uiText = require("@instructure/ui-text");
18
+ var _propTypes = require("../../../reporting/components/resources/common/propTypes.js");
19
+ var SessionSubmitEvent = /*#__PURE__*/function (_Component) {
20
+ (0, _inherits2.default)(SessionSubmitEvent, _Component);
21
+ var _super = (0, _createSuper2.default)(SessionSubmitEvent);
22
+ function SessionSubmitEvent() {
23
+ (0, _classCallCheck2.default)(this, SessionSubmitEvent);
24
+ return _super.apply(this, arguments);
25
+ }
26
+ (0, _createClass2.default)(SessionSubmitEvent, [{
27
+ key: "render",
28
+ value: function render() {
29
+ var _this$props = this.props,
30
+ validationErrors = _this$props.validationErrors,
31
+ currentEventData = _this$props.currentEventData;
32
+ var summary = /*#__PURE__*/_react.default.createElement(_uiText.Text, {
33
+ color: validationErrors.isBreach ? 'danger' : 'primary'
34
+ }, (0, _formatMessage.default)('Session submitted'));
35
+ return /*#__PURE__*/_react.default.createElement(_uiToggleDetails.ToggleDetails, {
36
+ summary: summary
37
+ }, /*#__PURE__*/_react.default.createElement(_EventDetails.EventDetails, {
38
+ currentEventData: currentEventData,
39
+ validationErrors: validationErrors
40
+ }));
41
+ }
42
+ }]);
43
+ SessionSubmitEvent.displayName = "SessionSubmitEvent";
44
+ return SessionSubmitEvent;
45
+ }(_react.Component);
46
+ exports.SessionSubmitEvent = SessionSubmitEvent;
47
+ SessionSubmitEvent.propTypes = {
48
+ validationErrors: _propTypes.sessionValidationErrorsPropType,
49
+ currentEventData: _propTypes.eventDataPropType
50
+ };
51
+ var _default = SessionSubmitEvent;
52
+ exports.default = _default;