@instructure/quiz-core 17.46.2-rc.7 → 17.47.1-rc.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/ApiFeatureFlagInitializer/index.js +36 -0
- package/es/common/components/ConfirmationModal/presenter.js +1 -1
- package/es/common/{util → components/RceConfigProvider}/RceConfigProvider.js +66 -51
- package/es/common/components/SDKApp/index.js +14 -7
- 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/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/ApiFeatureFlagInitializer/index.js +53 -0
- package/lib/common/components/ConfirmationModal/presenter.js +1 -1
- package/lib/common/{util → components/RceConfigProvider}/RceConfigProvider.js +66 -51
- package/lib/common/components/SDKApp/index.js +17 -10
- 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/rceChecker.js +1 -1
- package/lib/common/util/windowChecks.js +8 -2
- package/package.json +10 -10
|
@@ -4,17 +4,17 @@ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
|
4
4
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
5
5
|
import React, { useEffect, useState } from 'react';
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
7
|
-
import { connect } from "../../
|
|
8
|
-
import store from "
|
|
9
|
-
import { setRCEError } from "
|
|
10
|
-
import { isNewRCEEnabled, isNewRCEAppsEnabled, isRCE5RendererEnabled } from "
|
|
11
|
-
import { QuizzesSpinner as Spinner } from "../
|
|
12
|
-
import { Card } from "../
|
|
7
|
+
import { connect } from "../../react-redux.js";
|
|
8
|
+
import store from "../../../reduxStore.js";
|
|
9
|
+
import { setRCEError } from "../../actions/rce.js";
|
|
10
|
+
import { isNewRCEEnabled, isNewRCEAppsEnabled, isRCE5RendererEnabled } from "../../util/rceChecker.js";
|
|
11
|
+
import { QuizzesSpinner as Spinner } from "../shared/spinner/Spinner.js";
|
|
12
|
+
import { Card } from "../shared/Card/index.js";
|
|
13
13
|
import { RceConfigContext, RceConfigKeys } from '@instructure/quiz-common';
|
|
14
|
-
import { addError } from "
|
|
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 "
|
|
17
|
+
import { isQuizTaking, isQuizBuilding } from "../../util/windowChecks.js";
|
|
18
18
|
|
|
19
19
|
var _ref4 = /*#__PURE__*/React.createElement(Card, {
|
|
20
20
|
wrapped: true
|
|
@@ -40,6 +40,10 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
40
40
|
return !!(props.contextId && props.contextType && props.canvasUserId && props.rcsHost && props.rcsJwtRefreshFn && props.rcsJwt);
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
var isRce5Disabled = function isRce5Disabled() {
|
|
44
|
+
return !props.isNewRCEEnabled && !props.rce5Renderer;
|
|
45
|
+
};
|
|
46
|
+
|
|
43
47
|
var refreshToken = /*#__PURE__*/function () {
|
|
44
48
|
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(setTokenFn, questionStem) {
|
|
45
49
|
var _response$json;
|
|
@@ -50,39 +54,37 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
50
54
|
switch (_context.prev = _context.next) {
|
|
51
55
|
case 0:
|
|
52
56
|
if (hasAllPropsForRcs()) {
|
|
53
|
-
_context.next =
|
|
57
|
+
_context.next = 2;
|
|
54
58
|
break;
|
|
55
59
|
}
|
|
56
60
|
|
|
57
|
-
handleErrorFunc('Invalid RCS configuration');
|
|
58
61
|
return _context.abrupt("return");
|
|
59
62
|
|
|
60
|
-
case
|
|
61
|
-
_context.next =
|
|
63
|
+
case 2:
|
|
64
|
+
_context.next = 4;
|
|
62
65
|
return props.rcsJwtRefreshFn(jwt);
|
|
63
66
|
|
|
64
|
-
case
|
|
67
|
+
case 4:
|
|
65
68
|
response = _context.sent;
|
|
66
69
|
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
70
|
|
|
68
71
|
if (refreshedToken) {
|
|
69
|
-
_context.next =
|
|
72
|
+
_context.next = 11;
|
|
70
73
|
break;
|
|
71
74
|
}
|
|
72
75
|
|
|
73
|
-
handleErrorFunc('Unable to refresh RCS token');
|
|
74
76
|
normalizedStem = questionStem !== null && questionStem !== void 0 ? questionStem : 'Unknown stem';
|
|
75
77
|
extractedText = extractTextFromHtml(normalizedStem);
|
|
76
|
-
|
|
78
|
+
handleError(t('Error while answering "{stem}": Full functionality of the Rich Content Editor may not have been available to the user.', {
|
|
77
79
|
stem: extractedText
|
|
78
80
|
}));
|
|
79
81
|
return _context.abrupt("return");
|
|
80
82
|
|
|
81
|
-
case
|
|
83
|
+
case 11:
|
|
82
84
|
setJwt(refreshedToken);
|
|
83
85
|
setTokenFn(refreshedToken);
|
|
84
86
|
|
|
85
|
-
case
|
|
87
|
+
case 13:
|
|
86
88
|
case "end":
|
|
87
89
|
return _context.stop();
|
|
88
90
|
}
|
|
@@ -95,8 +97,34 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
95
97
|
};
|
|
96
98
|
}();
|
|
97
99
|
|
|
98
|
-
var
|
|
99
|
-
|
|
100
|
+
var handleError = function handleError(quizLogMessage) {
|
|
101
|
+
if (shouldAlertUser()) {
|
|
102
|
+
alertTheUser(alertMessage());
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (shouldsetEventToQuizLog()) {
|
|
106
|
+
setEventToQuizLog(quizLogMessage);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
var alertTheUser = function alertTheUser(message) {
|
|
111
|
+
store.dispatch(addError(message));
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
var setEventToQuizLog = function setEventToQuizLog(message) {
|
|
115
|
+
props.setEventToQuizLog(message);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
var alertMessage = function alertMessage() {
|
|
119
|
+
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.');
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
var shouldAlertUser = function shouldAlertUser() {
|
|
123
|
+
return isQuizTaking() || isQuizBuilding();
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
var shouldsetEventToQuizLog = function shouldsetEventToQuizLog() {
|
|
127
|
+
return isQuizTaking();
|
|
100
128
|
};
|
|
101
129
|
|
|
102
130
|
var getConfig = function getConfig() {
|
|
@@ -109,14 +137,6 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
109
137
|
};
|
|
110
138
|
};
|
|
111
139
|
|
|
112
|
-
var setErrorIfDuringTaking = function setErrorIfDuringTaking(errorMessage) {
|
|
113
|
-
if (!isQuizTaking()) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
props.setRCEError(errorMessage);
|
|
118
|
-
};
|
|
119
|
-
|
|
120
140
|
useEffect(function () {
|
|
121
141
|
_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
122
142
|
var host, base, url, response, json;
|
|
@@ -124,7 +144,7 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
124
144
|
while (1) {
|
|
125
145
|
switch (_context2.prev = _context2.next) {
|
|
126
146
|
case 0:
|
|
127
|
-
if (!(
|
|
147
|
+
if (!isRce5Disabled()) {
|
|
128
148
|
_context2.next = 2;
|
|
129
149
|
break;
|
|
130
150
|
}
|
|
@@ -139,7 +159,7 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
139
159
|
break;
|
|
140
160
|
}
|
|
141
161
|
|
|
142
|
-
|
|
162
|
+
handleError(t('Error: Full functionality of the Rich Content Editor may not have been available to the user.'));
|
|
143
163
|
return _context2.abrupt("return");
|
|
144
164
|
|
|
145
165
|
case 6:
|
|
@@ -163,7 +183,7 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
163
183
|
case 16:
|
|
164
184
|
json = _context2.sent;
|
|
165
185
|
setCanvasConfig(json);
|
|
166
|
-
|
|
186
|
+
setEventToQuizLog(null);
|
|
167
187
|
_context2.next = 25;
|
|
168
188
|
break;
|
|
169
189
|
|
|
@@ -171,7 +191,7 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
171
191
|
_context2.prev = 21;
|
|
172
192
|
_context2.t0 = _context2["catch"](2);
|
|
173
193
|
setCanvasConfig(null);
|
|
174
|
-
|
|
194
|
+
handleError(t('Error: Full functionality of the Rich Content Editor including accessibility features may not have been available to the user.'));
|
|
175
195
|
|
|
176
196
|
case 25:
|
|
177
197
|
_context2.prev = 25;
|
|
@@ -187,34 +207,31 @@ export var RceConfigProviderComponent = function RceConfigProviderComponent(prop
|
|
|
187
207
|
}))();
|
|
188
208
|
}, [props.isNewRCEEnabled, props.rce5Renderer]);
|
|
189
209
|
|
|
190
|
-
if (
|
|
191
|
-
|
|
192
|
-
if (!canvasConfigLoading) {
|
|
193
|
-
return /*#__PURE__*/React.createElement(RceConfigContext.Provider, {
|
|
194
|
-
value: getConfig()
|
|
195
|
-
}, props.children);
|
|
196
|
-
}
|
|
197
|
-
} else {
|
|
198
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
|
|
199
|
-
}
|
|
210
|
+
if (isRce5Disabled()) {
|
|
211
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
|
|
200
212
|
}
|
|
201
213
|
|
|
202
|
-
|
|
214
|
+
if (!canvasConfigLoading) {
|
|
215
|
+
return /*#__PURE__*/React.createElement(RceConfigContext.Provider, {
|
|
216
|
+
value: getConfig()
|
|
217
|
+
}, props.children);
|
|
218
|
+
} else {
|
|
219
|
+
return _ref4;
|
|
220
|
+
}
|
|
203
221
|
};
|
|
204
222
|
RceConfigProviderComponent.propTypes = {
|
|
205
223
|
children: PropTypes.node.isRequired,
|
|
206
224
|
isNewRCEEnabled: PropTypes.bool.isRequired,
|
|
207
225
|
rce5Renderer: PropTypes.bool.isRequired,
|
|
208
226
|
isNewRCEAppsEnabled: PropTypes.bool,
|
|
209
|
-
|
|
227
|
+
setEventToQuizLog: PropTypes.func.isRequired,
|
|
210
228
|
contextId: PropTypes.string,
|
|
211
229
|
contextType: PropTypes.string,
|
|
212
230
|
canvasUserId: PropTypes.string,
|
|
213
231
|
rcsHost: PropTypes.string,
|
|
214
232
|
rcsJwt: PropTypes.string,
|
|
215
233
|
rcsJwtRefreshFn: PropTypes.func,
|
|
216
|
-
canvasOrigin: PropTypes.string
|
|
217
|
-
loadedApiFeatures: PropTypes.bool
|
|
234
|
+
canvasOrigin: PropTypes.string
|
|
218
235
|
};
|
|
219
236
|
RceConfigProviderComponent.defaultProps = {
|
|
220
237
|
contextId: null,
|
|
@@ -224,21 +241,19 @@ RceConfigProviderComponent.defaultProps = {
|
|
|
224
241
|
rcsJwt: null,
|
|
225
242
|
rcsJwtRefreshFn: null,
|
|
226
243
|
canvasOrigin: null,
|
|
227
|
-
loadedApiFeatures: false,
|
|
228
244
|
isNewRCEAppsEnabled: false
|
|
229
245
|
};
|
|
230
246
|
|
|
231
|
-
var mapStateToProps = function mapStateToProps(
|
|
247
|
+
var mapStateToProps = function mapStateToProps() {
|
|
232
248
|
return {
|
|
233
249
|
isNewRCEEnabled: isNewRCEEnabled(),
|
|
234
250
|
rce5Renderer: isRCE5RendererEnabled(),
|
|
235
|
-
isNewRCEAppsEnabled: isNewRCEAppsEnabled()
|
|
236
|
-
loadedApiFeatures: state.getIn(['ui', 'loadedApiFeatures']) || ownProps.loadedApiFeatures
|
|
251
|
+
isNewRCEAppsEnabled: isNewRCEAppsEnabled()
|
|
237
252
|
};
|
|
238
253
|
};
|
|
239
254
|
|
|
240
255
|
var mapDispatchToProps = {
|
|
241
|
-
|
|
256
|
+
setEventToQuizLog: setRCEError
|
|
242
257
|
};
|
|
243
258
|
var RceConfigProvider = connect(mapStateToProps, mapDispatchToProps)(RceConfigProviderComponent);
|
|
244
259
|
export { RceConfigProvider };
|
|
@@ -17,9 +17,8 @@ import { ApplyLocale } from '@instructure/ui-i18n';
|
|
|
17
17
|
import { Provider } from "../../react-redux.js";
|
|
18
18
|
import store from "../../../reduxStore.js";
|
|
19
19
|
import { getLocale } from '@instructure/quiz-common';
|
|
20
|
-
import { getFeatures } from "../../api/features.js";
|
|
21
20
|
import { set } from "../../actions/ui.js";
|
|
22
|
-
import { setAPIEndpoint, setUserToken } from "../../actions/config.js";
|
|
21
|
+
import { setAPIEndpoint, setCanvasOrigin, setUserToken } from "../../actions/config.js";
|
|
23
22
|
import { setContextUuid, setOutcomesEndpoint, setOutcomesToken } from "../../actions/outcomes.js";
|
|
24
23
|
import { addFeatures, removeFeatures } from "../../actions/features.js";
|
|
25
24
|
import renderAlerts from "../../util/renderAlerts.js";
|
|
@@ -34,7 +33,8 @@ import theme from "./theme.js";
|
|
|
34
33
|
import CustomPropTypes from "../../../common/util/CustomPropTypes.js";
|
|
35
34
|
import ConfirmationModal from "../ConfirmationModal/index.js";
|
|
36
35
|
import setupFormatMessage from '@instructure/quiz-i18n/es/util/setupFormatMessage';
|
|
37
|
-
import { RceConfigProvider } from "
|
|
36
|
+
import { RceConfigProvider } from "../RceConfigProvider/RceConfigProvider.js";
|
|
37
|
+
import { ApiFeatureFlagInitializer } from "../ApiFeatureFlagInitializer/index.js";
|
|
38
38
|
|
|
39
39
|
var _ref = /*#__PURE__*/React.createElement(ConfirmationModal, null);
|
|
40
40
|
|
|
@@ -78,8 +78,9 @@ export var SDKApp = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
|
|
|
78
78
|
}, {
|
|
79
79
|
key: "componentWillMount",
|
|
80
80
|
value: function componentWillMount() {
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
var _this$props$rceConfig;
|
|
82
|
+
|
|
83
|
+
this.store.dispatch([setAPIEndpoint(this.props.apiEndpoint), setCanvasOrigin((_this$props$rceConfig = this.props.rceConfig) === null || _this$props$rceConfig === void 0 ? void 0 : _this$props$rceConfig.canvasOrigin), this.setAppContainer(this.props.appContainer), setUserToken(this.props.userToken), setOutcomesEndpoint(this.props.outcomesEndpoint), setOutcomesToken(this.props.outcomesToken), setContextUuid(this.props.contextUuid)]);
|
|
83
84
|
|
|
84
85
|
if (this.props.itemBankSharingEnabled) {
|
|
85
86
|
this.store.dispatch(addFeatures('item_bank_sharing'));
|
|
@@ -95,10 +96,16 @@ export var SDKApp = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
|
|
|
95
96
|
}, {
|
|
96
97
|
key: "componentWillReceiveProps",
|
|
97
98
|
value: function componentWillReceiveProps(newProps) {
|
|
99
|
+
var _newProps$rceConfig, _this$props$rceConfig2;
|
|
100
|
+
|
|
98
101
|
if (newProps.apiEndpoint !== this.props.apiEndpoint) {
|
|
99
102
|
this.store.dispatch(setAPIEndpoint(newProps.apiEndpoint));
|
|
100
103
|
}
|
|
101
104
|
|
|
105
|
+
if (((_newProps$rceConfig = newProps.rceConfig) === null || _newProps$rceConfig === void 0 ? void 0 : _newProps$rceConfig.canvasOrigin) !== ((_this$props$rceConfig2 = this.props.rceConfig) === null || _this$props$rceConfig2 === void 0 ? void 0 : _this$props$rceConfig2.canvasOrigin)) {
|
|
106
|
+
this.store.dispatch(setCanvasOrigin(newProps.rceConfig.canvasOrigin));
|
|
107
|
+
}
|
|
108
|
+
|
|
102
109
|
if (newProps.appContainer !== this.props.appContainer) {
|
|
103
110
|
this.store.dispatch(this.setAppContainer(newProps.appContainer));
|
|
104
111
|
}
|
|
@@ -132,13 +139,13 @@ export var SDKApp = (_dec = themeable(theme, styles), _dec(_class = (_temp = _cl
|
|
|
132
139
|
context = this.context;
|
|
133
140
|
return /*#__PURE__*/React.createElement(Provider, {
|
|
134
141
|
store: store
|
|
135
|
-
}, /*#__PURE__*/React.createElement(RceConfigProvider, this.props.rceConfig, /*#__PURE__*/React.createElement(ApplyLocale, {
|
|
142
|
+
}, /*#__PURE__*/React.createElement(ApiFeatureFlagInitializer, null, /*#__PURE__*/React.createElement(RceConfigProvider, this.props.rceConfig, /*#__PURE__*/React.createElement(ApplyLocale, {
|
|
136
143
|
locale: getLocale(props, context),
|
|
137
144
|
timezone: props.timeZone
|
|
138
145
|
}, /*#__PURE__*/React.createElement("div", {
|
|
139
146
|
className: styles.sdk,
|
|
140
147
|
"data-automation": "sdk-app"
|
|
141
|
-
}, _ref, props.children))));
|
|
148
|
+
}, _ref, props.children)))));
|
|
142
149
|
}
|
|
143
150
|
}]);
|
|
144
151
|
|
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
import { connect } from "../../../../react-redux.js";
|
|
2
|
+
import { checkItemShareability } from "../../../../../building/api/items.js";
|
|
3
|
+
import { checkStimulusShareability } from "../../../../../building/api/stimuli.js";
|
|
2
4
|
import makeEditable from "../../../shared/functionality/makeEditable.js";
|
|
3
5
|
import { showError, hideError } from "../../../../actions/errorsShowing.js";
|
|
4
6
|
import { screenreaderNotification } from "../../../../actions/alerts.js";
|
|
5
7
|
import { clearNextQuizEntry } from "../../../../actions/modifications.js";
|
|
8
|
+
import { withConfirm } from "../../../../actions/modal.js";
|
|
9
|
+
import { featureOn } from "../../../../util/featureCheck.js";
|
|
6
10
|
import EntrySave from "./presenter.js";
|
|
7
|
-
|
|
8
|
-
function mapStateToProps(state, props) {
|
|
11
|
+
export function mapStateToProps(state, props) {
|
|
9
12
|
// Error Related:
|
|
10
13
|
var workingEntry = props.entry.getWorkingInstance();
|
|
11
14
|
var isValid = props.isValid !== void 0 ? props.isValid : workingEntry.isValid();
|
|
12
15
|
return {
|
|
16
|
+
canvasOrigin: state.getIn(['config', 'canvasOrigin']),
|
|
17
|
+
checkBankedContentShareabilityEnabled: featureOn('check_banked_content_shareability'),
|
|
18
|
+
checkContentShareability: props.entry.isStimulus ? checkStimulusShareability : checkItemShareability,
|
|
13
19
|
isValid: isValid
|
|
14
20
|
};
|
|
15
21
|
}
|
|
16
|
-
|
|
17
22
|
var mapDispatchToProps = {
|
|
18
23
|
clearNextQuizEntry: clearNextQuizEntry,
|
|
19
|
-
showError: showError,
|
|
20
24
|
hideError: hideError,
|
|
21
|
-
screenreaderNotification: screenreaderNotification
|
|
25
|
+
screenreaderNotification: screenreaderNotification,
|
|
26
|
+
showError: showError,
|
|
27
|
+
withConfirm: withConfirm
|
|
22
28
|
};
|
|
23
29
|
export default makeEditable(connect(mapStateToProps, mapDispatchToProps)(EntrySave));
|
|
@@ -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
|
|
|
@@ -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(':')
|