@instructure/quiz-core 17.46.2-rc.7 → 17.47.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 +16 -0
- package/es/banks/components/AddToBankModal/index.js +6 -0
- package/es/banks/components/AddToBankModal/presenter.js +128 -6
- package/es/banks/components/BankEntry/presenter.js +4 -3
- package/es/building/api/items.js +21 -5
- package/es/building/api/stimuli.js +21 -5
- package/es/building/components/resources/quizEntry/QuizEntryEdit/presenter.js +1 -0
- package/es/common/actions/config.js +7 -1
- package/es/common/components/ConfirmationModal/presenter.js +1 -1
- package/es/common/components/SDKApp/index.js +10 -2
- package/es/common/components/resources/entry/EntrySave/index.js +11 -5
- package/es/common/components/resources/entry/EntrySave/presenter.js +95 -21
- package/es/common/components/resources/stimulus/StimulusEdit/presenter.js +1 -0
- package/es/common/reducers/config.js +4 -1
- package/es/common/util/RceConfigProvider.js +42 -26
- package/es/common/util/rceChecker.js +1 -1
- package/es/common/util/windowChecks.js +4 -1
- package/lib/banks/components/AddToBankModal/index.js +9 -0
- package/lib/banks/components/AddToBankModal/presenter.js +135 -6
- package/lib/banks/components/BankEntry/presenter.js +4 -3
- package/lib/building/api/items.js +23 -5
- package/lib/building/api/stimuli.js +23 -5
- package/lib/building/components/resources/quizEntry/QuizEntryEdit/presenter.js +1 -0
- package/lib/common/actions/config.js +8 -0
- package/lib/common/components/ConfirmationModal/presenter.js +1 -1
- package/lib/common/components/SDKApp/index.js +9 -1
- package/lib/common/components/resources/entry/EntrySave/index.js +15 -2
- package/lib/common/components/resources/entry/EntrySave/presenter.js +96 -21
- package/lib/common/components/resources/stimulus/StimulusEdit/presenter.js +1 -0
- package/lib/common/reducers/config.js +3 -0
- package/lib/common/util/RceConfigProvider.js +41 -25
- package/lib/common/util/rceChecker.js +1 -1
- package/lib/common/util/windowChecks.js +8 -2
- package/package.json +10 -10
|
@@ -6,6 +6,7 @@ import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
|
6
6
|
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
7
7
|
import React, { Component } from 'react';
|
|
8
8
|
import PropTypes from 'prop-types';
|
|
9
|
+
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
9
10
|
import { Button } from '@instructure/ui-buttons';
|
|
10
11
|
import { View } from '@instructure/ui-view';
|
|
11
12
|
import { API_INPUT_VALIDATION_ERROR } from '@instructure/quiz-common';
|
|
@@ -39,11 +40,75 @@ export var EntrySave = /*#__PURE__*/function (_Component) {
|
|
|
39
40
|
_this.props.screenreaderNotification(msg);
|
|
40
41
|
};
|
|
41
42
|
|
|
43
|
+
_this.confirmShareableContent = function () {
|
|
44
|
+
var _this$props = _this.props,
|
|
45
|
+
canvasOrigin = _this$props.canvasOrigin,
|
|
46
|
+
checkContentShareability = _this$props.checkContentShareability,
|
|
47
|
+
entry = _this$props.entry,
|
|
48
|
+
withConfirm = _this$props.withConfirm;
|
|
49
|
+
|
|
50
|
+
_this.setState({
|
|
51
|
+
canSubmit: false
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
checkContentShareability(entry.getWorkingInstance(), canvasOrigin).then(function () {
|
|
55
|
+
_this.successfulSubmit();
|
|
56
|
+
}).catch( /*#__PURE__*/function () {
|
|
57
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(err) {
|
|
58
|
+
var _err$response, _err$response2;
|
|
59
|
+
|
|
60
|
+
var body, text;
|
|
61
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
62
|
+
while (1) {
|
|
63
|
+
switch (_context.prev = _context.next) {
|
|
64
|
+
case 0:
|
|
65
|
+
_context.next = 2;
|
|
66
|
+
return (_err$response = err.response) === null || _err$response === void 0 ? void 0 : _err$response.json();
|
|
67
|
+
|
|
68
|
+
case 2:
|
|
69
|
+
body = _context.sent;
|
|
70
|
+
text = t('There was an error attempting to validate shareability.');
|
|
71
|
+
|
|
72
|
+
if (((_err$response2 = err.response) === null || _err$response2 === void 0 ? void 0 : _err$response2.status) === 400 && body.shareable === false) {
|
|
73
|
+
text = t('You are attempting to save content containing course links which may not work when used in other courses.');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
withConfirm(function () {
|
|
77
|
+
_this.successfulSubmit();
|
|
78
|
+
}, {
|
|
79
|
+
title: t('Are you sure?'),
|
|
80
|
+
text: text,
|
|
81
|
+
continueText: t('Save anyway'),
|
|
82
|
+
onCancel: function onCancel() {
|
|
83
|
+
_this.setState({
|
|
84
|
+
canSubmit: true
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
case 6:
|
|
90
|
+
case "end":
|
|
91
|
+
return _context.stop();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}, _callee);
|
|
95
|
+
}));
|
|
96
|
+
|
|
97
|
+
return function (_x) {
|
|
98
|
+
return _ref.apply(this, arguments);
|
|
99
|
+
};
|
|
100
|
+
}());
|
|
101
|
+
};
|
|
102
|
+
|
|
42
103
|
_this.onSubmit = function (e) {
|
|
43
104
|
e.preventDefault();
|
|
44
105
|
|
|
45
106
|
if (_this.props.isValid) {
|
|
46
|
-
_this.
|
|
107
|
+
if (_this.props.checkBankedContentShareabilityEnabled && _this.props.shouldValidateShareableContent) {
|
|
108
|
+
_this.confirmShareableContent();
|
|
109
|
+
} else {
|
|
110
|
+
_this.successfulSubmit();
|
|
111
|
+
}
|
|
47
112
|
} else {
|
|
48
113
|
_this.createScreenReaderNotification();
|
|
49
114
|
|
|
@@ -87,24 +152,24 @@ export var EntrySave = /*#__PURE__*/function (_Component) {
|
|
|
87
152
|
}, {
|
|
88
153
|
key: "successfulSubmit",
|
|
89
154
|
value: function () {
|
|
90
|
-
var _successfulSubmit = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function
|
|
155
|
+
var _successfulSubmit = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
91
156
|
var validationResult;
|
|
92
|
-
return _regeneratorRuntime.wrap(function
|
|
157
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
93
158
|
while (1) {
|
|
94
|
-
switch (
|
|
159
|
+
switch (_context2.prev = _context2.next) {
|
|
95
160
|
case 0:
|
|
96
161
|
this.setState({
|
|
97
162
|
canSubmit: false
|
|
98
163
|
});
|
|
99
|
-
|
|
100
|
-
|
|
164
|
+
_context2.prev = 1;
|
|
165
|
+
_context2.next = 4;
|
|
101
166
|
return this.props.submitHandler();
|
|
102
167
|
|
|
103
168
|
case 4:
|
|
104
|
-
validationResult =
|
|
169
|
+
validationResult = _context2.sent;
|
|
105
170
|
|
|
106
171
|
if (!(validationResult === API_INPUT_VALIDATION_ERROR)) {
|
|
107
|
-
|
|
172
|
+
_context2.next = 8;
|
|
108
173
|
break;
|
|
109
174
|
}
|
|
110
175
|
|
|
@@ -112,16 +177,16 @@ export var EntrySave = /*#__PURE__*/function (_Component) {
|
|
|
112
177
|
throw new Error('User input validation error received from API.');
|
|
113
178
|
|
|
114
179
|
case 8:
|
|
115
|
-
|
|
180
|
+
_context2.next = 14;
|
|
116
181
|
break;
|
|
117
182
|
|
|
118
183
|
case 10:
|
|
119
|
-
|
|
120
|
-
|
|
184
|
+
_context2.prev = 10;
|
|
185
|
+
_context2.t0 = _context2["catch"](1);
|
|
121
186
|
this.setState({
|
|
122
187
|
canSubmit: true
|
|
123
188
|
});
|
|
124
|
-
return
|
|
189
|
+
return _context2.abrupt("return");
|
|
125
190
|
|
|
126
191
|
case 14:
|
|
127
192
|
this.props.switchOffEditing();
|
|
@@ -130,10 +195,10 @@ export var EntrySave = /*#__PURE__*/function (_Component) {
|
|
|
130
195
|
|
|
131
196
|
case 17:
|
|
132
197
|
case "end":
|
|
133
|
-
return
|
|
198
|
+
return _context2.stop();
|
|
134
199
|
}
|
|
135
200
|
}
|
|
136
|
-
},
|
|
201
|
+
}, _callee2, this, [[1, 10]]);
|
|
137
202
|
}));
|
|
138
203
|
|
|
139
204
|
function successfulSubmit() {
|
|
@@ -168,28 +233,37 @@ export var EntrySave = /*#__PURE__*/function (_Component) {
|
|
|
168
233
|
return EntrySave;
|
|
169
234
|
}(Component);
|
|
170
235
|
EntrySave.propTypes = {
|
|
171
|
-
displayPosition: PropTypes.number,
|
|
172
|
-
disableSubmit: PropTypes.bool,
|
|
173
|
-
guid: PropTypes.string,
|
|
174
|
-
submitHandler: PropTypes.func.isRequired,
|
|
175
236
|
cancelHandler: PropTypes.func,
|
|
237
|
+
canvasOrigin: PropTypes.string,
|
|
238
|
+
checkBankedContentShareabilityEnabled: PropTypes.bool,
|
|
239
|
+
checkContentShareability: PropTypes.func.isRequired,
|
|
176
240
|
clearChanges: PropTypes.func.isRequired,
|
|
177
241
|
// From connected component
|
|
178
242
|
clearNextQuizEntry: PropTypes.func.isRequired,
|
|
243
|
+
disableSubmit: PropTypes.bool,
|
|
244
|
+
displayPosition: PropTypes.number,
|
|
245
|
+
entry: ImmutablePropTypes.record.isRequired,
|
|
246
|
+
guid: PropTypes.string,
|
|
179
247
|
hideError: PropTypes.func.isRequired,
|
|
248
|
+
initialFocusId: PropTypes.string,
|
|
180
249
|
isValid: PropTypes.bool.isRequired,
|
|
181
250
|
showError: PropTypes.func.isRequired,
|
|
182
251
|
screenreaderNotification: PropTypes.func.isRequired,
|
|
252
|
+
shouldValidateShareableContent: PropTypes.bool,
|
|
253
|
+
submitHandler: PropTypes.func.isRequired,
|
|
183
254
|
// from makescrollable / from props being passed in occasionally
|
|
184
255
|
switchOnEditing: PropTypes.func.isRequired,
|
|
185
256
|
switchOffEditing: PropTypes.func.isRequired,
|
|
186
|
-
|
|
257
|
+
withConfirm: PropTypes.func.isRequired
|
|
187
258
|
};
|
|
188
259
|
EntrySave.defaultProps = {
|
|
189
|
-
displayPosition: null,
|
|
190
260
|
cancelHandler: noop,
|
|
261
|
+
canvasOrigin: '',
|
|
262
|
+
checkBankedContentShareabilityEnabled: false,
|
|
263
|
+
displayPosition: null,
|
|
191
264
|
disableSubmit: false,
|
|
192
265
|
guid: null,
|
|
193
|
-
initialFocusId: null
|
|
266
|
+
initialFocusId: null,
|
|
267
|
+
shouldValidateShareableContent: false
|
|
194
268
|
};
|
|
195
269
|
export default EntrySave;
|
|
@@ -376,6 +376,7 @@ export var StimulusEdit = (_dec = themeable(theme, styles), _dec(_class = (_temp
|
|
|
376
376
|
onAdd: this.handleAddToBank,
|
|
377
377
|
onContinue: this.handleAddToBankContinue,
|
|
378
378
|
getEntry: this.getEntryForBank,
|
|
379
|
+
workingEntry: this.props.workingStimulus,
|
|
379
380
|
entryId: this.props.guid,
|
|
380
381
|
entryType: this.props.quizEntry.entryType
|
|
381
382
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { fromJS } from 'immutable';
|
|
2
|
-
import { SET_API_ENDPOINT, SET_USER_TOKEN } from '@instructure/quiz-common';
|
|
2
|
+
import { SET_API_ENDPOINT, SET_CANVAS_ORIGIN, SET_USER_TOKEN } from '@instructure/quiz-common';
|
|
3
3
|
var defaultState = fromJS({
|
|
4
4
|
apiEndpoint: ''
|
|
5
5
|
});
|
|
@@ -11,6 +11,9 @@ export default (function () {
|
|
|
11
11
|
case SET_API_ENDPOINT:
|
|
12
12
|
return state.set('apiEndpoint', action.payload);
|
|
13
13
|
|
|
14
|
+
case SET_CANVAS_ORIGIN:
|
|
15
|
+
return state.set('canvasOrigin', action.payload);
|
|
16
|
+
|
|
14
17
|
case SET_USER_TOKEN:
|
|
15
18
|
return state.set('userToken', action.payload);
|
|
16
19
|
|
|
@@ -14,7 +14,7 @@ import { RceConfigContext, RceConfigKeys } from '@instructure/quiz-common';
|
|
|
14
14
|
import { addError } from "../actions/alerts.js";
|
|
15
15
|
import t from '@instructure/quiz-i18n/es/format-message';
|
|
16
16
|
import { extractTextFromHtml } from '@instructure/quiz-interactions';
|
|
17
|
-
import { isQuizTaking } from "./windowChecks.js";
|
|
17
|
+
import { isQuizTaking, isQuizBuilding } from "./windowChecks.js";
|
|
18
18
|
|
|
19
19
|
var _ref4 = /*#__PURE__*/React.createElement(Card, {
|
|
20
20
|
wrapped: true
|
|
@@ -50,39 +50,37 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
50
50
|
switch (_context.prev = _context.next) {
|
|
51
51
|
case 0:
|
|
52
52
|
if (hasAllPropsForRcs()) {
|
|
53
|
-
_context.next =
|
|
53
|
+
_context.next = 2;
|
|
54
54
|
break;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
handleErrorFunc('Invalid RCS configuration');
|
|
58
57
|
return _context.abrupt("return");
|
|
59
58
|
|
|
60
|
-
case
|
|
61
|
-
_context.next =
|
|
59
|
+
case 2:
|
|
60
|
+
_context.next = 4;
|
|
62
61
|
return props.rcsJwtRefreshFn(jwt);
|
|
63
62
|
|
|
64
|
-
case
|
|
63
|
+
case 4:
|
|
65
64
|
response = _context.sent;
|
|
66
65
|
refreshedToken = response === null || response === void 0 ? void 0 : (_response$json = response.json) === null || _response$json === void 0 ? void 0 : _response$json.token; // inst-redux-service-middleware response structure
|
|
67
66
|
|
|
68
67
|
if (refreshedToken) {
|
|
69
|
-
_context.next =
|
|
68
|
+
_context.next = 11;
|
|
70
69
|
break;
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
handleErrorFunc('Unable to refresh RCS token');
|
|
74
72
|
normalizedStem = questionStem !== null && questionStem !== void 0 ? questionStem : 'Unknown stem';
|
|
75
73
|
extractedText = extractTextFromHtml(normalizedStem);
|
|
76
|
-
|
|
74
|
+
handleError(t('Error while answering "{stem}": Full functionality of the Rich Content Editor may not have been available to the user.', {
|
|
77
75
|
stem: extractedText
|
|
78
76
|
}));
|
|
79
77
|
return _context.abrupt("return");
|
|
80
78
|
|
|
81
|
-
case
|
|
79
|
+
case 11:
|
|
82
80
|
setJwt(refreshedToken);
|
|
83
81
|
setTokenFn(refreshedToken);
|
|
84
82
|
|
|
85
|
-
case
|
|
83
|
+
case 13:
|
|
86
84
|
case "end":
|
|
87
85
|
return _context.stop();
|
|
88
86
|
}
|
|
@@ -95,8 +93,34 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
95
93
|
};
|
|
96
94
|
}();
|
|
97
95
|
|
|
98
|
-
var
|
|
99
|
-
|
|
96
|
+
var handleError = function handleError(quizLogMessage) {
|
|
97
|
+
if (shouldAlertUser()) {
|
|
98
|
+
alertTheUser(alertMessage());
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (shouldsetEventToQuizLog()) {
|
|
102
|
+
setEventToQuizLog(quizLogMessage);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
var alertTheUser = function alertTheUser(message) {
|
|
107
|
+
store.dispatch(addError(message));
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
var setEventToQuizLog = function setEventToQuizLog(message) {
|
|
111
|
+
props.setEventToQuizLog(message);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
var alertMessage = function alertMessage() {
|
|
115
|
+
return isQuizTaking() ? t('The Rich Content Editor has encountered an issue. ' + 'It has been logged for your instructor to review. Please refresh and try again.') : t('The Rich Content Editor has encountered an issue. Please refresh and try again.');
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
var shouldAlertUser = function shouldAlertUser() {
|
|
119
|
+
return isQuizTaking() || isQuizBuilding();
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
var shouldsetEventToQuizLog = function shouldsetEventToQuizLog() {
|
|
123
|
+
return isQuizTaking();
|
|
100
124
|
};
|
|
101
125
|
|
|
102
126
|
var getConfig = function getConfig() {
|
|
@@ -109,14 +133,6 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
109
133
|
};
|
|
110
134
|
};
|
|
111
135
|
|
|
112
|
-
var setErrorIfDuringTaking = function setErrorIfDuringTaking(errorMessage) {
|
|
113
|
-
if (!isQuizTaking()) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
props.setRCEError(errorMessage);
|
|
118
|
-
};
|
|
119
|
-
|
|
120
136
|
useEffect(function () {
|
|
121
137
|
_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
122
138
|
var host, base, url, response, json;
|
|
@@ -139,7 +155,7 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
139
155
|
break;
|
|
140
156
|
}
|
|
141
157
|
|
|
142
|
-
|
|
158
|
+
handleError(t('Error: Full functionality of the Rich Content Editor may not have been available to the user.'));
|
|
143
159
|
return _context2.abrupt("return");
|
|
144
160
|
|
|
145
161
|
case 6:
|
|
@@ -163,7 +179,7 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
163
179
|
case 16:
|
|
164
180
|
json = _context2.sent;
|
|
165
181
|
setCanvasConfig(json);
|
|
166
|
-
|
|
182
|
+
setEventToQuizLog(null);
|
|
167
183
|
_context2.next = 25;
|
|
168
184
|
break;
|
|
169
185
|
|
|
@@ -171,7 +187,7 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
171
187
|
_context2.prev = 21;
|
|
172
188
|
_context2.t0 = _context2["catch"](2);
|
|
173
189
|
setCanvasConfig(null);
|
|
174
|
-
|
|
190
|
+
handleError(t('Error: Full functionality of the Rich Content Editor including accessibility features may not have been available to the user.'));
|
|
175
191
|
|
|
176
192
|
case 25:
|
|
177
193
|
_context2.prev = 25;
|
|
@@ -206,7 +222,7 @@ RceConfigProviderComponent.propTypes = {
|
|
|
206
222
|
isNewRCEEnabled: PropTypes.bool.isRequired,
|
|
207
223
|
rce5Renderer: PropTypes.bool.isRequired,
|
|
208
224
|
isNewRCEAppsEnabled: PropTypes.bool,
|
|
209
|
-
|
|
225
|
+
setEventToQuizLog: PropTypes.func.isRequired,
|
|
210
226
|
contextId: PropTypes.string,
|
|
211
227
|
contextType: PropTypes.string,
|
|
212
228
|
canvasUserId: PropTypes.string,
|
|
@@ -238,7 +254,7 @@ var mapStateToProps = function mapStateToProps(state, ownProps) {
|
|
|
238
254
|
};
|
|
239
255
|
|
|
240
256
|
var mapDispatchToProps = {
|
|
241
|
-
|
|
257
|
+
setEventToQuizLog: setRCEError
|
|
242
258
|
};
|
|
243
259
|
var RceConfigProvider = connect(mapStateToProps, mapDispatchToProps)(RceConfigProviderComponent);
|
|
244
260
|
export { RceConfigProvider };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { featureOn } from "./featureCheck.js";
|
|
2
2
|
var newRCEFeatureName = 'use_new_rce';
|
|
3
|
-
var newRCEAppsFeatureName = '
|
|
3
|
+
var newRCEAppsFeatureName = 'rce5_apps';
|
|
4
4
|
var rce5RendererFeatureName = 'rce5_renderer';
|
|
5
5
|
export function isNewRCEEnabled() {
|
|
6
6
|
return featureOn(newRCEFeatureName);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isDuringQuizTake } from '@instructure/quiz-common';
|
|
1
|
+
import { isDuringQuizTake, isDuringQuizBuild } from '@instructure/quiz-common';
|
|
2
2
|
export var media = {
|
|
3
3
|
'phone-break-point': 'only screen and (max-width: 48rem)',
|
|
4
4
|
'tablet-break-point': 'only screen and (max-width: 64rem)'
|
|
@@ -15,4 +15,7 @@ export var onTablet = function onTablet() {
|
|
|
15
15
|
};
|
|
16
16
|
export var isQuizTaking = function isQuizTaking() {
|
|
17
17
|
return isDuringQuizTake();
|
|
18
|
+
};
|
|
19
|
+
export var isQuizBuilding = function isQuizBuilding() {
|
|
20
|
+
return isDuringQuizBuild();
|
|
18
21
|
};
|
|
@@ -16,6 +16,10 @@ var _banks = require("../../api/banks.js");
|
|
|
16
16
|
|
|
17
17
|
var _bankEntries = require("../../api/bankEntries.js");
|
|
18
18
|
|
|
19
|
+
var _items = require("../../../building/api/items.js");
|
|
20
|
+
|
|
21
|
+
var _stimuli = require("../../../building/api/stimuli.js");
|
|
22
|
+
|
|
19
23
|
var _presenter = _interopRequireDefault(require("./presenter.js"));
|
|
20
24
|
|
|
21
25
|
var modalActions = _interopRequireWildcard(require("../../../common/actions/modal.js"));
|
|
@@ -30,10 +34,15 @@ var _quizCommon = require("@instructure/quiz-common");
|
|
|
30
34
|
|
|
31
35
|
var _modalHelpers = require("../../../common/util/modalHelpers.js");
|
|
32
36
|
|
|
37
|
+
var _featureCheck = require("../../../common/util/featureCheck.js");
|
|
38
|
+
|
|
33
39
|
function mapStateToProps(state, props) {
|
|
34
40
|
var selectedBankOption = state.getIn(['ui', _quizCommon.ADD_TO_BANK_MODAL_BANK_SELECTION]);
|
|
35
41
|
var selectedBank = selectedBankOption && new _Bank.default(state.getIn(['banks', selectedBankOption]));
|
|
36
42
|
return {
|
|
43
|
+
canvasOrigin: state.getIn(['config', 'canvasOrigin']),
|
|
44
|
+
checkBankedContentShareabilityEnabled: (0, _featureCheck.featureOn)('check_banked_content_shareability'),
|
|
45
|
+
checkContentShareability: props.entryType === 'Item' ? _items.checkItemShareability : _stimuli.checkStimulusShareability,
|
|
37
46
|
selectedBank: selectedBank,
|
|
38
47
|
modalTrigger: (0, _modalHelpers.getModalTrigger)(state),
|
|
39
48
|
modalOpen: state.getIn(['modal', 'isOpen']) === [_quizCommon.ADD_TO_BANK_MODAL, props.entryType, props.entryId].join(':')
|
|
@@ -9,6 +9,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
9
9
|
});
|
|
10
10
|
exports.default = exports.AddToBankModal = void 0;
|
|
11
11
|
|
|
12
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
13
|
+
|
|
14
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
15
|
+
|
|
12
16
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
13
17
|
|
|
14
18
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
@@ -37,11 +41,36 @@ var _Bank = _interopRequireDefault(require("../../../common/records/Bank.js"));
|
|
|
37
41
|
|
|
38
42
|
var _index = _interopRequireDefault(require("../../../common/components/resources/BankSelection/index.js"));
|
|
39
43
|
|
|
44
|
+
var _uiSpinner = require("@instructure/ui-spinner");
|
|
45
|
+
|
|
46
|
+
var _uiText = require("@instructure/ui-text");
|
|
47
|
+
|
|
48
|
+
var _uiIcons = require("@instructure/ui-icons");
|
|
49
|
+
|
|
50
|
+
var _uiView = require("@instructure/ui-view");
|
|
51
|
+
|
|
52
|
+
var _uiFlex = require("@instructure/ui-flex");
|
|
53
|
+
|
|
40
54
|
var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message"));
|
|
41
55
|
|
|
42
56
|
var _quizCommon = require("@instructure/quiz-common");
|
|
43
57
|
|
|
44
|
-
var
|
|
58
|
+
var _ref2 = /*#__PURE__*/_react.default.createElement(_uiIcons.IconCheckLine, {
|
|
59
|
+
color: "success"
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
var _ref3 = /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
|
|
63
|
+
padding: "0 small 0 0"
|
|
64
|
+
}, /*#__PURE__*/_react.default.createElement(_uiIcons.IconNoLine, {
|
|
65
|
+
color: "error",
|
|
66
|
+
size: "small"
|
|
67
|
+
}));
|
|
68
|
+
|
|
69
|
+
var _ref4 = /*#__PURE__*/_react.default.createElement(_uiIcons.IconWarningLine, {
|
|
70
|
+
color: "warning"
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
var _ref5 = /*#__PURE__*/_react.default.createElement("br", null);
|
|
45
74
|
|
|
46
75
|
var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
47
76
|
(0, _inherits2.default)(AddToBankModal, _Component);
|
|
@@ -60,6 +89,7 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
60
89
|
_this = _super.call.apply(_super, [this].concat(args));
|
|
61
90
|
_this.state = {
|
|
62
91
|
bankType: 'existing',
|
|
92
|
+
contentShareable: 'loading',
|
|
63
93
|
newBankTitle: ''
|
|
64
94
|
};
|
|
65
95
|
|
|
@@ -124,6 +154,65 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
124
154
|
}
|
|
125
155
|
|
|
126
156
|
(0, _createClass2.default)(AddToBankModal, [{
|
|
157
|
+
key: "componentDidUpdate",
|
|
158
|
+
value: function componentDidUpdate(prevProps) {
|
|
159
|
+
var _this2 = this;
|
|
160
|
+
|
|
161
|
+
var _this$props = this.props,
|
|
162
|
+
canvasOrigin = _this$props.canvasOrigin,
|
|
163
|
+
checkBankedContentShareabilityEnabled = _this$props.checkBankedContentShareabilityEnabled,
|
|
164
|
+
modalOpen = _this$props.modalOpen,
|
|
165
|
+
checkContentShareability = _this$props.checkContentShareability,
|
|
166
|
+
workingEntry = _this$props.workingEntry;
|
|
167
|
+
|
|
168
|
+
if (checkBankedContentShareabilityEnabled && modalOpen && !prevProps.modalOpen) {
|
|
169
|
+
this.setState({
|
|
170
|
+
contentShareable: 'loading'
|
|
171
|
+
});
|
|
172
|
+
checkContentShareability(workingEntry, canvasOrigin).then(function () {
|
|
173
|
+
_this2.setState({
|
|
174
|
+
contentShareable: 'true'
|
|
175
|
+
});
|
|
176
|
+
}).catch( /*#__PURE__*/function () {
|
|
177
|
+
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(err) {
|
|
178
|
+
var _err$response, _err$response2;
|
|
179
|
+
|
|
180
|
+
var body;
|
|
181
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
182
|
+
while (1) {
|
|
183
|
+
switch (_context.prev = _context.next) {
|
|
184
|
+
case 0:
|
|
185
|
+
_context.next = 2;
|
|
186
|
+
return (_err$response = err.response) === null || _err$response === void 0 ? void 0 : _err$response.json();
|
|
187
|
+
|
|
188
|
+
case 2:
|
|
189
|
+
body = _context.sent;
|
|
190
|
+
|
|
191
|
+
if (((_err$response2 = err.response) === null || _err$response2 === void 0 ? void 0 : _err$response2.status) === 400 && body.shareable === false) {
|
|
192
|
+
_this2.setState({
|
|
193
|
+
contentShareable: 'false'
|
|
194
|
+
});
|
|
195
|
+
} else {
|
|
196
|
+
_this2.setState({
|
|
197
|
+
contentShareable: 'unknown'
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
case 4:
|
|
202
|
+
case "end":
|
|
203
|
+
return _context.stop();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}, _callee);
|
|
207
|
+
}));
|
|
208
|
+
|
|
209
|
+
return function (_x) {
|
|
210
|
+
return _ref.apply(this, arguments);
|
|
211
|
+
};
|
|
212
|
+
}());
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}, {
|
|
127
216
|
key: "cancelButton",
|
|
128
217
|
value: function cancelButton() {
|
|
129
218
|
return /*#__PURE__*/_react.default.createElement(_uiButtons.Button, {
|
|
@@ -136,8 +225,11 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
136
225
|
value: function addToBankButton() {
|
|
137
226
|
var _this$state = this.state,
|
|
138
227
|
bankType = _this$state.bankType,
|
|
139
|
-
newBankTitle = _this$state.newBankTitle
|
|
140
|
-
|
|
228
|
+
newBankTitle = _this$state.newBankTitle,
|
|
229
|
+
contentShareable = _this$state.contentShareable;
|
|
230
|
+
var checkBankedContentShareabilityEnabled = this.props.checkBankedContentShareabilityEnabled;
|
|
231
|
+
var contentShareableLoading = contentShareable === 'loading';
|
|
232
|
+
var disabled = bankType === 'existing' && !this.props.selectedBank || bankType === 'new' && (!newBankTitle || !newBankTitle.trim()) || checkBankedContentShareabilityEnabled && contentShareableLoading;
|
|
141
233
|
return /*#__PURE__*/_react.default.createElement(_uiButtons.Button, {
|
|
142
234
|
type: "button",
|
|
143
235
|
variant: "primary",
|
|
@@ -145,7 +237,7 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
145
237
|
disabled: disabled,
|
|
146
238
|
margin: _quizCommon.XSMALL_SIDE_MARGIN,
|
|
147
239
|
"data-automation": "sdk-add-to-bank-button"
|
|
148
|
-
}, (0, _formatMessage.default)('Add'));
|
|
240
|
+
}, checkBankedContentShareabilityEnabled && !contentShareableLoading && contentShareable !== 'true' ? (0, _formatMessage.default)('Add anyway') : (0, _formatMessage.default)('Add'));
|
|
149
241
|
}
|
|
150
242
|
}, {
|
|
151
243
|
key: "renderBankTypeContent",
|
|
@@ -165,6 +257,37 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
165
257
|
type: "text"
|
|
166
258
|
});
|
|
167
259
|
}
|
|
260
|
+
}, {
|
|
261
|
+
key: "renderContentShareabilityMessage",
|
|
262
|
+
value: function renderContentShareabilityMessage() {
|
|
263
|
+
if (this.props.checkBankedContentShareabilityEnabled) {
|
|
264
|
+
var content = null;
|
|
265
|
+
|
|
266
|
+
if (this.state.contentShareable === 'loading') {
|
|
267
|
+
content = /*#__PURE__*/_react.default.createElement(_uiText.Text, null, /*#__PURE__*/_react.default.createElement(_uiSpinner.Spinner, {
|
|
268
|
+
size: "x-small",
|
|
269
|
+
renderTitle: (0, _formatMessage.default)('Checking content shareability...')
|
|
270
|
+
}), "\xA0", (0, _formatMessage.default)('Validating content...'));
|
|
271
|
+
} else if (this.state.contentShareable === 'true') {
|
|
272
|
+
content = /*#__PURE__*/_react.default.createElement(_uiText.Text, null, _ref2, "\xA0", (0, _formatMessage.default)('Good to go!'));
|
|
273
|
+
} else if (this.state.contentShareable === 'false') {
|
|
274
|
+
content = /*#__PURE__*/_react.default.createElement(_uiFlex.Flex, null, _ref3, /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
|
|
275
|
+
shouldShrink: true
|
|
276
|
+
}, /*#__PURE__*/_react.default.createElement(_uiText.Text, {
|
|
277
|
+
color: "error"
|
|
278
|
+
}, (0, _formatMessage.default)('You are attempting to add content containing course links which may not work when used in other courses.'))));
|
|
279
|
+
} else {
|
|
280
|
+
content = /*#__PURE__*/_react.default.createElement(_uiText.Text, {
|
|
281
|
+
color: "warning"
|
|
282
|
+
}, _ref4, "\xA0", (0, _formatMessage.default)('There was an error attempting to validate shareability.'));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return /*#__PURE__*/_react.default.createElement(_uiView.View, {
|
|
286
|
+
as: "div",
|
|
287
|
+
margin: "small 0 0 0"
|
|
288
|
+
}, content);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
168
291
|
}, {
|
|
169
292
|
key: "renderContent",
|
|
170
293
|
value: function renderContent() {
|
|
@@ -179,7 +302,7 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
179
302
|
}), /*#__PURE__*/_react.default.createElement(_uiRadioInput.RadioInput, {
|
|
180
303
|
value: "new",
|
|
181
304
|
label: (0, _formatMessage.default)('New item bank')
|
|
182
|
-
})),
|
|
305
|
+
})), _ref5, this.renderBankTypeContent(), this.renderContentShareabilityMessage());
|
|
183
306
|
}
|
|
184
307
|
}, {
|
|
185
308
|
key: "render",
|
|
@@ -207,6 +330,9 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
207
330
|
|
|
208
331
|
exports.AddToBankModal = AddToBankModal;
|
|
209
332
|
AddToBankModal.propTypes = {
|
|
333
|
+
canvasOrigin: _propTypes.default.string,
|
|
334
|
+
checkBankedContentShareabilityEnabled: _propTypes.default.bool,
|
|
335
|
+
checkContentShareability: _propTypes.default.func.isRequired,
|
|
210
336
|
closeModal: _propTypes.default.func.isRequired,
|
|
211
337
|
createBank: _propTypes.default.func.isRequired,
|
|
212
338
|
createBankEntry: _propTypes.default.func.isRequired,
|
|
@@ -218,15 +344,18 @@ AddToBankModal.propTypes = {
|
|
|
218
344
|
entryType: _propTypes.default.string.isRequired,
|
|
219
345
|
// Resolve to the bank entry's entry, or create it if it does not yet exist.
|
|
220
346
|
getEntry: _propTypes.default.func.isRequired,
|
|
347
|
+
handleValidationErrorsFromApi: _propTypes.default.func.isRequired,
|
|
221
348
|
label: _propTypes.default.string.isRequired,
|
|
222
349
|
modalOpen: _propTypes.default.bool.isRequired,
|
|
223
350
|
onAdd: _propTypes.default.func,
|
|
224
351
|
onContinue: _propTypes.default.func,
|
|
225
352
|
selectedBank: _reactImmutableProptypes.default.record,
|
|
226
353
|
uiSet: _propTypes.default.func.isRequired,
|
|
227
|
-
|
|
354
|
+
workingEntry: _reactImmutableProptypes.default.record.isRequired
|
|
228
355
|
};
|
|
229
356
|
AddToBankModal.defaultProps = {
|
|
357
|
+
canvasOrigin: '',
|
|
358
|
+
checkBankedContentShareabilityEnabled: false,
|
|
230
359
|
onAdd: function onAdd() {},
|
|
231
360
|
onContinue: function onContinue() {},
|
|
232
361
|
selectedBank: null
|
|
@@ -245,17 +245,18 @@ var BankEntry = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles), _de
|
|
|
245
245
|
return {
|
|
246
246
|
cancelHandler: _this.navigateToBank,
|
|
247
247
|
clearChanges: _this.clearChanges,
|
|
248
|
+
clearValidationErrorsFromApi: _this.clearValidationErrorsFromApi,
|
|
248
249
|
contextUuid: null,
|
|
250
|
+
disableSubmit: Boolean(_this.state.validationErrorsFromApi && Object.values(_this.state.validationErrorsFromApi).length),
|
|
249
251
|
entry: entry,
|
|
250
252
|
guid: "".concat(_this.props.bankEntry.id, "_bank_entry_edit"),
|
|
251
253
|
handleQuizEntryPointsChange: _this.handlePointsChange,
|
|
252
254
|
parentId: _this.props.bankId,
|
|
253
255
|
parentType: _quizCommon.PARENT_TYPE_BANK,
|
|
256
|
+
shouldValidateShareableContent: true,
|
|
254
257
|
stimulus: entry,
|
|
255
258
|
submitHandler: _this.submitHandler,
|
|
256
|
-
validationErrorsFromApi: _this.state.validationErrorsFromApi
|
|
257
|
-
clearValidationErrorsFromApi: _this.clearValidationErrorsFromApi,
|
|
258
|
-
disableSubmit: Boolean(_this.state.validationErrorsFromApi && Object.values(_this.state.validationErrorsFromApi).length)
|
|
259
|
+
validationErrorsFromApi: _this.state.validationErrorsFromApi
|
|
259
260
|
};
|
|
260
261
|
};
|
|
261
262
|
|