@instructure/quiz-core 20.35.1-rc.8 → 20.35.1-rc10.6
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/es/banks/components/AddToBankModal/index.js +4 -0
- package/es/banks/components/AddToBankModal/presenter.js +109 -5
- package/es/banks/components/BankEntry/presenter.js +2 -0
- package/es/building/api/items.js +13 -0
- package/es/building/api/stimuli.js +13 -0
- package/es/building/components/resources/quizEntry/QuizEntryEdit/presenter.js +1 -0
- package/es/common/components/resources/entry/EntrySave/index.js +7 -1
- package/es/common/components/resources/entry/EntrySave/presenter.js +90 -27
- package/es/common/components/resources/stimulus/StimulusEdit/presenter.js +1 -0
- package/lib/banks/components/AddToBankModal/index.js +4 -0
- package/lib/banks/components/AddToBankModal/presenter.js +109 -5
- package/lib/banks/components/BankEntry/presenter.js +2 -0
- package/lib/building/api/items.js +14 -0
- package/lib/building/api/stimuli.js +14 -0
- package/lib/building/components/resources/quizEntry/QuizEntryEdit/presenter.js +1 -0
- package/lib/common/components/resources/entry/EntrySave/index.js +7 -1
- package/lib/common/components/resources/entry/EntrySave/presenter.js +90 -27
- package/lib/common/components/resources/stimulus/StimulusEdit/presenter.js +1 -0
- package/package.json +9 -9
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { connect } from "../../../common/react-redux.js";
|
|
2
2
|
import { createBank } from "../../api/banks.js";
|
|
3
3
|
import { createBankEntry, moveBankEntryFromQuizEntry } from "../../api/bankEntries.js";
|
|
4
|
+
import { checkItemShareability } from "../../../building/api/items.js";
|
|
5
|
+
import { checkStimulusShareability } from "../../../building/api/stimuli.js";
|
|
4
6
|
import AddToBankModal from "./presenter.js";
|
|
5
7
|
import * as modalActions from "../../../common/actions/modal.js";
|
|
6
8
|
import { disassociateEntry } from "../../../common/actions/banks.js";
|
|
@@ -9,6 +11,8 @@ import { ADD_TO_BANK_MODAL } from '@instructure/quiz-common';
|
|
|
9
11
|
import { getModalTrigger } from "../../../common/util/modalHelpers.js";
|
|
10
12
|
export function mapStateToProps(state, props) {
|
|
11
13
|
return {
|
|
14
|
+
canvasOrigin: state.getIn(['config', 'canvasOrigin']),
|
|
15
|
+
checkContentShareability: props.entryType === 'Item' ? checkItemShareability : checkStimulusShareability,
|
|
12
16
|
modalTrigger: getModalTrigger(state),
|
|
13
17
|
modalOpen: state.getIn(['modal', 'isOpen']) === [ADD_TO_BANK_MODAL, props.entryType, props.entryId].join(':')
|
|
14
18
|
};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
1
3
|
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
2
4
|
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
5
|
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
4
6
|
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
5
7
|
import React, { Component } from 'react';
|
|
6
8
|
import PropTypes from 'prop-types';
|
|
9
|
+
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
7
10
|
import { Button, CloseButton } from '@instructure/ui-buttons';
|
|
8
11
|
import { Heading } from '@instructure/ui-heading';
|
|
9
12
|
import { TextInput } from '@instructure/ui-text-input';
|
|
@@ -11,10 +14,24 @@ import { RadioInputGroup, RadioInput } from '@instructure/ui-radio-input';
|
|
|
11
14
|
import { ScreenReaderContent } from '@instructure/ui-a11y-content';
|
|
12
15
|
import Bank from "../../../common/records/Bank.js";
|
|
13
16
|
import BankSelection from "../../../common/components/resources/BankSelection/presenter.js";
|
|
17
|
+
import { Spinner } from '@instructure/ui-spinner';
|
|
18
|
+
import { Text } from '@instructure/ui-text';
|
|
19
|
+
import { IconNoLine, IconWarningLine } from '@instructure/ui-icons';
|
|
20
|
+
import { View } from '@instructure/ui-view';
|
|
21
|
+
import { Flex } from '@instructure/ui-flex';
|
|
14
22
|
import t from '@instructure/quiz-i18n/es/format-message';
|
|
15
23
|
import { Modal, ModalHeader, ModalBody, ModalFooter, XSMALL_SIDE_MARGIN } from '@instructure/quiz-common';
|
|
16
24
|
import { featureOn } from "../../../common/util/featureCheck.js";
|
|
17
|
-
var
|
|
25
|
+
var _ref2 = /*#__PURE__*/React.createElement(Flex.Item, {
|
|
26
|
+
padding: "0 small 0 0"
|
|
27
|
+
}, /*#__PURE__*/React.createElement(IconNoLine, {
|
|
28
|
+
color: "error",
|
|
29
|
+
size: "small"
|
|
30
|
+
}));
|
|
31
|
+
var _ref3 = /*#__PURE__*/React.createElement(IconWarningLine, {
|
|
32
|
+
color: "warning"
|
|
33
|
+
});
|
|
34
|
+
var _ref4 = /*#__PURE__*/React.createElement("br", null);
|
|
18
35
|
export var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
19
36
|
_inherits(AddToBankModal, _Component);
|
|
20
37
|
var _super = _createSuper(AddToBankModal);
|
|
@@ -27,6 +44,7 @@ export var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
27
44
|
_this = _super.call.apply(_super, [this].concat(args));
|
|
28
45
|
_this.state = {
|
|
29
46
|
bankType: 'existing',
|
|
47
|
+
contentShareable: 'loading',
|
|
30
48
|
newBankTitle: '',
|
|
31
49
|
selectedBank: null
|
|
32
50
|
};
|
|
@@ -87,6 +105,57 @@ export var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
87
105
|
return _this;
|
|
88
106
|
}
|
|
89
107
|
_createClass(AddToBankModal, [{
|
|
108
|
+
key: "componentDidUpdate",
|
|
109
|
+
value: function componentDidUpdate(prevProps) {
|
|
110
|
+
var _this2 = this;
|
|
111
|
+
var _this$props = this.props,
|
|
112
|
+
canvasOrigin = _this$props.canvasOrigin,
|
|
113
|
+
modalOpen = _this$props.modalOpen,
|
|
114
|
+
checkContentShareability = _this$props.checkContentShareability,
|
|
115
|
+
workingEntry = _this$props.workingEntry;
|
|
116
|
+
if (modalOpen && !prevProps.modalOpen) {
|
|
117
|
+
this.setState({
|
|
118
|
+
contentShareable: 'loading'
|
|
119
|
+
});
|
|
120
|
+
checkContentShareability(workingEntry, canvasOrigin).then(function () {
|
|
121
|
+
_this2.setState({
|
|
122
|
+
contentShareable: 'true'
|
|
123
|
+
});
|
|
124
|
+
}).catch(/*#__PURE__*/function () {
|
|
125
|
+
var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(err) {
|
|
126
|
+
var _err$response, _err$response2;
|
|
127
|
+
var body;
|
|
128
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
129
|
+
while (1) {
|
|
130
|
+
switch (_context.prev = _context.next) {
|
|
131
|
+
case 0:
|
|
132
|
+
_context.next = 2;
|
|
133
|
+
return (_err$response = err.response) === null || _err$response === void 0 ? void 0 : _err$response.json();
|
|
134
|
+
case 2:
|
|
135
|
+
body = _context.sent;
|
|
136
|
+
if (((_err$response2 = err.response) === null || _err$response2 === void 0 ? void 0 : _err$response2.status) === 400 && body.shareable === false) {
|
|
137
|
+
_this2.setState({
|
|
138
|
+
contentShareable: 'false'
|
|
139
|
+
});
|
|
140
|
+
} else {
|
|
141
|
+
_this2.setState({
|
|
142
|
+
contentShareable: 'unknown'
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
case 4:
|
|
146
|
+
case "end":
|
|
147
|
+
return _context.stop();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}, _callee);
|
|
151
|
+
}));
|
|
152
|
+
return function (_x) {
|
|
153
|
+
return _ref.apply(this, arguments);
|
|
154
|
+
};
|
|
155
|
+
}());
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}, {
|
|
90
159
|
key: "cancelButton",
|
|
91
160
|
value: function cancelButton() {
|
|
92
161
|
return /*#__PURE__*/React.createElement(Button, {
|
|
@@ -99,8 +168,10 @@ export var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
99
168
|
value: function addToBankButton() {
|
|
100
169
|
var _this$state = this.state,
|
|
101
170
|
bankType = _this$state.bankType,
|
|
102
|
-
newBankTitle = _this$state.newBankTitle
|
|
103
|
-
|
|
171
|
+
newBankTitle = _this$state.newBankTitle,
|
|
172
|
+
contentShareable = _this$state.contentShareable;
|
|
173
|
+
var contentShareableLoading = contentShareable === 'loading';
|
|
174
|
+
var disabled = bankType === 'existing' && !this.state.selectedBank || bankType === 'new' && (!newBankTitle || !newBankTitle.trim()) || contentShareableLoading;
|
|
104
175
|
return /*#__PURE__*/React.createElement(Button, {
|
|
105
176
|
type: "button",
|
|
106
177
|
color: "primary",
|
|
@@ -108,7 +179,7 @@ export var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
108
179
|
disabled: disabled,
|
|
109
180
|
margin: XSMALL_SIDE_MARGIN,
|
|
110
181
|
"data-automation": "sdk-add-to-bank-button"
|
|
111
|
-
}, t('Add'));
|
|
182
|
+
}, !contentShareableLoading && contentShareable !== 'true' ? t('Add anyway') : t('Add'));
|
|
112
183
|
}
|
|
113
184
|
}, {
|
|
114
185
|
key: "renderBankTypeContent",
|
|
@@ -127,6 +198,35 @@ export var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
127
198
|
type: "text"
|
|
128
199
|
});
|
|
129
200
|
}
|
|
201
|
+
}, {
|
|
202
|
+
key: "renderContentShareabilityMessage",
|
|
203
|
+
value: function renderContentShareabilityMessage() {
|
|
204
|
+
var content = null;
|
|
205
|
+
if (this.state.contentShareable === 'loading') {
|
|
206
|
+
content = /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement(Spinner, {
|
|
207
|
+
size: "x-small",
|
|
208
|
+
renderTitle: t('Checking content shareability...')
|
|
209
|
+
}), "\xA0", t('Validating content...'));
|
|
210
|
+
} else if (this.state.contentShareable === 'true') {
|
|
211
|
+
// No message needed. The API call to check shareability is very fast in most cases,
|
|
212
|
+
// so the user may be distracted by a message here.
|
|
213
|
+
content = null;
|
|
214
|
+
} else if (this.state.contentShareable === 'false') {
|
|
215
|
+
content = /*#__PURE__*/React.createElement(Flex, null, _ref2, /*#__PURE__*/React.createElement(Flex.Item, {
|
|
216
|
+
shouldShrink: true
|
|
217
|
+
}, /*#__PURE__*/React.createElement(Text, {
|
|
218
|
+
color: "danger"
|
|
219
|
+
}, t('You are attempting to add content containing course links which may not work when used in other courses.'))));
|
|
220
|
+
} else {
|
|
221
|
+
content = /*#__PURE__*/React.createElement(Text, {
|
|
222
|
+
color: "warning"
|
|
223
|
+
}, _ref3, "\xA0", t('There was an error attempting to validate shareability.'));
|
|
224
|
+
}
|
|
225
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
226
|
+
as: "div",
|
|
227
|
+
margin: "small 0 0 0"
|
|
228
|
+
}, content);
|
|
229
|
+
}
|
|
130
230
|
}, {
|
|
131
231
|
key: "renderContent",
|
|
132
232
|
value: function renderContent() {
|
|
@@ -141,7 +241,7 @@ export var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
141
241
|
}), /*#__PURE__*/React.createElement(RadioInput, {
|
|
142
242
|
value: "new",
|
|
143
243
|
label: t('New item bank')
|
|
144
|
-
})),
|
|
244
|
+
})), _ref4, this.renderBankTypeContent(), this.renderContentShareabilityMessage());
|
|
145
245
|
}
|
|
146
246
|
}, {
|
|
147
247
|
key: "render",
|
|
@@ -167,6 +267,8 @@ export var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
167
267
|
return AddToBankModal;
|
|
168
268
|
}(Component);
|
|
169
269
|
AddToBankModal.propTypes = {
|
|
270
|
+
canvasOrigin: PropTypes.string,
|
|
271
|
+
checkContentShareability: PropTypes.func.isRequired,
|
|
170
272
|
closeModal: PropTypes.func.isRequired,
|
|
171
273
|
createBank: PropTypes.func.isRequired,
|
|
172
274
|
moveBankEntryFromQuizEntry: PropTypes.func.isRequired,
|
|
@@ -185,9 +287,11 @@ AddToBankModal.propTypes = {
|
|
|
185
287
|
onAdd: PropTypes.func,
|
|
186
288
|
onContinue: PropTypes.func,
|
|
187
289
|
uiSet: PropTypes.func.isRequired,
|
|
290
|
+
workingEntry: ImmutablePropTypes.record.isRequired,
|
|
188
291
|
quizId: PropTypes.string.isRequired
|
|
189
292
|
};
|
|
190
293
|
AddToBankModal.defaultProps = {
|
|
294
|
+
canvasOrigin: '',
|
|
191
295
|
handleValidationErrorsFromApi: function handleValidationErrorsFromApi() {},
|
|
192
296
|
onAdd: function onAdd() {},
|
|
193
297
|
onContinue: function onContinue() {}
|
|
@@ -148,12 +148,14 @@ export var BankEntry = (_dec = withStyleOverrides(generateStyle, generateCompone
|
|
|
148
148
|
clearChanges: _this.clearChanges,
|
|
149
149
|
clearValidationErrorsFromApi: _this.clearValidationErrorsFromApi,
|
|
150
150
|
contextUuid: null,
|
|
151
|
+
disableSubmit: Boolean(_this.state.validationErrorsFromApi && Object.values(_this.state.validationErrorsFromApi).length),
|
|
151
152
|
entry: entry,
|
|
152
153
|
guid: "".concat(_this.props.bankEntry.id, "_bank_entry_edit"),
|
|
153
154
|
handleQuizEntryPointsChange: _this.handlePointsChange,
|
|
154
155
|
itemEditArea: _this.itemEditArea,
|
|
155
156
|
parentId: _this.props.bankId,
|
|
156
157
|
parentType: PARENT_TYPE_BANK,
|
|
158
|
+
shouldValidateShareableContent: true,
|
|
157
159
|
stimulus: entry,
|
|
158
160
|
submitHandler: _this.submitHandler,
|
|
159
161
|
validationErrorsFromApi: _this.state.validationErrorsFromApi,
|
package/es/building/api/items.js
CHANGED
|
@@ -34,6 +34,19 @@ export function getItem(itemId) {
|
|
|
34
34
|
});
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
+
export function checkItemShareability(item, canvasOrigin) {
|
|
38
|
+
var url = '/api/items/check_shareability';
|
|
39
|
+
var requestBody = JSON.stringify({
|
|
40
|
+
item: updateItemParams(item),
|
|
41
|
+
source_origin: canvasOrigin
|
|
42
|
+
});
|
|
43
|
+
var fetcher = new Fetcher({
|
|
44
|
+
onError: function onError() {}
|
|
45
|
+
});
|
|
46
|
+
return fetcher.post(url, {
|
|
47
|
+
body: requestBody
|
|
48
|
+
});
|
|
49
|
+
}
|
|
37
50
|
export function createItem(item, parentId, parentType) {
|
|
38
51
|
var parentItemId = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : null;
|
|
39
52
|
var resource = parentType === 'bank' ? 'banks' : 'quizzes';
|
|
@@ -79,4 +79,17 @@ export function updateStimulus(stimulus, parentId, parentType) {
|
|
|
79
79
|
return stimulusData;
|
|
80
80
|
});
|
|
81
81
|
};
|
|
82
|
+
}
|
|
83
|
+
export function checkStimulusShareability(stimulus, canvasOrigin) {
|
|
84
|
+
var url = '/api/stimuli/check_shareability';
|
|
85
|
+
var requestBody = JSON.stringify({
|
|
86
|
+
stimulus: updateStimulusParams(stimulus),
|
|
87
|
+
source_origin: canvasOrigin
|
|
88
|
+
});
|
|
89
|
+
var fetcher = new Fetcher({
|
|
90
|
+
onError: function onError() {}
|
|
91
|
+
});
|
|
92
|
+
return fetcher.post(url, {
|
|
93
|
+
body: requestBody
|
|
94
|
+
});
|
|
82
95
|
}
|
|
@@ -325,6 +325,7 @@ var QuizEntryEdit = (_dec = withStyleOverrides(generateStyle, generateComponentT
|
|
|
325
325
|
onContinue: this.handleAddToBankContinue,
|
|
326
326
|
onAdd: this.handleAddToBank,
|
|
327
327
|
getEntry: this.getEntryForBank,
|
|
328
|
+
workingEntry: this.props.workingEntry,
|
|
328
329
|
entryId: this.props.guid,
|
|
329
330
|
entryType: this.props.quizEntry.entryType,
|
|
330
331
|
quizId: this.props.quizId,
|
|
@@ -1,14 +1,19 @@
|
|
|
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";
|
|
6
9
|
import EntrySave from "./presenter.js";
|
|
7
10
|
export function mapStateToProps(state, props) {
|
|
8
11
|
// Error Related:
|
|
9
12
|
var workingEntry = props.entry.getWorkingInstance();
|
|
10
13
|
var isValid = props.isValid !== void 0 ? props.isValid : workingEntry.isValid();
|
|
11
14
|
return {
|
|
15
|
+
canvasOrigin: state.getIn(['config', 'canvasOrigin']),
|
|
16
|
+
checkContentShareability: props.entry.isStimulus ? checkStimulusShareability : checkItemShareability,
|
|
12
17
|
isValid: isValid
|
|
13
18
|
};
|
|
14
19
|
}
|
|
@@ -16,6 +21,7 @@ var mapDispatchToProps = {
|
|
|
16
21
|
clearNextQuizEntry: clearNextQuizEntry,
|
|
17
22
|
hideError: hideError,
|
|
18
23
|
screenreaderNotification: screenreaderNotification,
|
|
19
|
-
showError: showError
|
|
24
|
+
showError: showError,
|
|
25
|
+
withConfirm: withConfirm
|
|
20
26
|
};
|
|
21
27
|
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 ReactDOM from 'react-dom';
|
|
10
11
|
import { Button } from '@instructure/ui-buttons';
|
|
11
12
|
import { View } from '@instructure/ui-view';
|
|
@@ -32,36 +33,91 @@ export var EntrySave = /*#__PURE__*/function (_Component) {
|
|
|
32
33
|
});
|
|
33
34
|
_this.props.screenreaderNotification(msg);
|
|
34
35
|
};
|
|
36
|
+
_this.confirmShareableContent = function () {
|
|
37
|
+
var _this$props = _this.props,
|
|
38
|
+
canvasOrigin = _this$props.canvasOrigin,
|
|
39
|
+
checkContentShareability = _this$props.checkContentShareability,
|
|
40
|
+
entry = _this$props.entry,
|
|
41
|
+
withConfirm = _this$props.withConfirm;
|
|
42
|
+
_this.setState({
|
|
43
|
+
canSubmit: false
|
|
44
|
+
});
|
|
45
|
+
checkContentShareability(entry.getWorkingInstance(), canvasOrigin).then(function () {
|
|
46
|
+
_this.successfulSubmit();
|
|
47
|
+
}).catch(/*#__PURE__*/function () {
|
|
48
|
+
var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(err) {
|
|
49
|
+
var _err$response, _err$response2;
|
|
50
|
+
var body, text;
|
|
51
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
52
|
+
while (1) {
|
|
53
|
+
switch (_context.prev = _context.next) {
|
|
54
|
+
case 0:
|
|
55
|
+
_context.next = 2;
|
|
56
|
+
return (_err$response = err.response) === null || _err$response === void 0 ? void 0 : _err$response.json();
|
|
57
|
+
case 2:
|
|
58
|
+
body = _context.sent;
|
|
59
|
+
text = t('There was an error attempting to validate shareability.');
|
|
60
|
+
if (((_err$response2 = err.response) === null || _err$response2 === void 0 ? void 0 : _err$response2.status) === 400 && body.shareable === false) {
|
|
61
|
+
text = t('You are attempting to save content containing course links which may not work when used in other courses.');
|
|
62
|
+
}
|
|
63
|
+
withConfirm(function () {
|
|
64
|
+
_this.successfulSubmit();
|
|
65
|
+
}, {
|
|
66
|
+
title: t('Are you sure?'),
|
|
67
|
+
text: text,
|
|
68
|
+
continueText: t('Save anyway'),
|
|
69
|
+
onCancel: function onCancel() {
|
|
70
|
+
_this.setState({
|
|
71
|
+
canSubmit: true
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
case 6:
|
|
76
|
+
case "end":
|
|
77
|
+
return _context.stop();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}, _callee);
|
|
81
|
+
}));
|
|
82
|
+
return function (_x) {
|
|
83
|
+
return _ref.apply(this, arguments);
|
|
84
|
+
};
|
|
85
|
+
}());
|
|
86
|
+
};
|
|
35
87
|
_this.onSubmit = /*#__PURE__*/function () {
|
|
36
|
-
var
|
|
37
|
-
return _regeneratorRuntime.wrap(function
|
|
88
|
+
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(e) {
|
|
89
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
38
90
|
while (1) {
|
|
39
|
-
switch (
|
|
91
|
+
switch (_context2.prev = _context2.next) {
|
|
40
92
|
case 0:
|
|
41
93
|
e.preventDefault();
|
|
42
94
|
if (!_this.props.isValid) {
|
|
43
|
-
|
|
95
|
+
_context2.next = 5;
|
|
44
96
|
break;
|
|
45
97
|
}
|
|
46
|
-
_this.
|
|
47
|
-
|
|
98
|
+
if (_this.props.shouldValidateShareableContent) {
|
|
99
|
+
_this.confirmShareableContent();
|
|
100
|
+
} else {
|
|
101
|
+
_this.successfulSubmit();
|
|
102
|
+
}
|
|
103
|
+
_context2.next = 10;
|
|
48
104
|
break;
|
|
49
105
|
case 5:
|
|
50
106
|
_this.createScreenReaderNotification();
|
|
51
|
-
|
|
107
|
+
_context2.next = 8;
|
|
52
108
|
return _this.props.showError(_this.props.guid);
|
|
53
109
|
case 8:
|
|
54
110
|
_this.props.clearNextQuizEntry();
|
|
55
111
|
_this.focusFirstErrorField();
|
|
56
112
|
case 10:
|
|
57
113
|
case "end":
|
|
58
|
-
return
|
|
114
|
+
return _context2.stop();
|
|
59
115
|
}
|
|
60
116
|
}
|
|
61
|
-
},
|
|
117
|
+
}, _callee2);
|
|
62
118
|
}));
|
|
63
|
-
return function (
|
|
64
|
-
return
|
|
119
|
+
return function (_x2) {
|
|
120
|
+
return _ref2.apply(this, arguments);
|
|
65
121
|
};
|
|
66
122
|
}();
|
|
67
123
|
_this.focusFirstErrorField = function () {
|
|
@@ -99,46 +155,46 @@ export var EntrySave = /*#__PURE__*/function (_Component) {
|
|
|
99
155
|
}, {
|
|
100
156
|
key: "successfulSubmit",
|
|
101
157
|
value: function () {
|
|
102
|
-
var _successfulSubmit = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function
|
|
158
|
+
var _successfulSubmit = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
|
|
103
159
|
var validationResult;
|
|
104
|
-
return _regeneratorRuntime.wrap(function
|
|
160
|
+
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
105
161
|
while (1) {
|
|
106
|
-
switch (
|
|
162
|
+
switch (_context3.prev = _context3.next) {
|
|
107
163
|
case 0:
|
|
108
164
|
this.setState({
|
|
109
165
|
canSubmit: false
|
|
110
166
|
});
|
|
111
|
-
|
|
112
|
-
|
|
167
|
+
_context3.prev = 1;
|
|
168
|
+
_context3.next = 4;
|
|
113
169
|
return this.props.submitHandler();
|
|
114
170
|
case 4:
|
|
115
|
-
validationResult =
|
|
171
|
+
validationResult = _context3.sent;
|
|
116
172
|
if (!(validationResult === API_INPUT_VALIDATION_ERROR)) {
|
|
117
|
-
|
|
173
|
+
_context3.next = 8;
|
|
118
174
|
break;
|
|
119
175
|
}
|
|
120
176
|
this.createScreenReaderNotification();
|
|
121
177
|
throw new Error('User input validation error received from API.');
|
|
122
178
|
case 8:
|
|
123
|
-
|
|
179
|
+
_context3.next = 14;
|
|
124
180
|
break;
|
|
125
181
|
case 10:
|
|
126
|
-
|
|
127
|
-
|
|
182
|
+
_context3.prev = 10;
|
|
183
|
+
_context3.t0 = _context3["catch"](1);
|
|
128
184
|
this.setState({
|
|
129
185
|
canSubmit: true
|
|
130
186
|
});
|
|
131
|
-
return
|
|
187
|
+
return _context3.abrupt("return");
|
|
132
188
|
case 14:
|
|
133
189
|
this.props.switchOffEditing();
|
|
134
190
|
this.props.hideError(this.props.guid);
|
|
135
191
|
this.props.screenreaderNotification(t('Changes to question saved.'));
|
|
136
192
|
case 17:
|
|
137
193
|
case "end":
|
|
138
|
-
return
|
|
194
|
+
return _context3.stop();
|
|
139
195
|
}
|
|
140
196
|
}
|
|
141
|
-
},
|
|
197
|
+
}, _callee3, this, [[1, 10]]);
|
|
142
198
|
}));
|
|
143
199
|
function successfulSubmit() {
|
|
144
200
|
return _successfulSubmit.apply(this, arguments);
|
|
@@ -171,11 +227,14 @@ export var EntrySave = /*#__PURE__*/function (_Component) {
|
|
|
171
227
|
}(Component);
|
|
172
228
|
EntrySave.propTypes = {
|
|
173
229
|
cancelHandler: PropTypes.func,
|
|
230
|
+
canvasOrigin: PropTypes.string,
|
|
231
|
+
checkContentShareability: PropTypes.func.isRequired,
|
|
174
232
|
clearChanges: PropTypes.func.isRequired,
|
|
175
233
|
// From connected component
|
|
176
234
|
clearNextQuizEntry: PropTypes.func.isRequired,
|
|
177
235
|
disableSubmit: PropTypes.bool,
|
|
178
236
|
displayPosition: PropTypes.number,
|
|
237
|
+
entry: ImmutablePropTypes.record.isRequired,
|
|
179
238
|
guid: PropTypes.string,
|
|
180
239
|
hideError: PropTypes.func.isRequired,
|
|
181
240
|
initialFocusId: PropTypes.string,
|
|
@@ -183,17 +242,21 @@ EntrySave.propTypes = {
|
|
|
183
242
|
itemEditArea: PropTypes.object,
|
|
184
243
|
showError: PropTypes.func.isRequired,
|
|
185
244
|
screenreaderNotification: PropTypes.func.isRequired,
|
|
245
|
+
shouldValidateShareableContent: PropTypes.bool,
|
|
186
246
|
submitHandler: PropTypes.func.isRequired,
|
|
187
247
|
// from makescrollable / from props being passed in occasionally
|
|
188
248
|
switchOnEditing: PropTypes.func.isRequired,
|
|
189
|
-
switchOffEditing: PropTypes.func.isRequired
|
|
249
|
+
switchOffEditing: PropTypes.func.isRequired,
|
|
250
|
+
withConfirm: PropTypes.func.isRequired
|
|
190
251
|
};
|
|
191
252
|
EntrySave.defaultProps = {
|
|
192
253
|
cancelHandler: noop,
|
|
193
|
-
|
|
254
|
+
canvasOrigin: '',
|
|
194
255
|
displayPosition: null,
|
|
256
|
+
disableSubmit: false,
|
|
195
257
|
guid: null,
|
|
196
258
|
initialFocusId: null,
|
|
197
|
-
itemEditArea: null
|
|
259
|
+
itemEditArea: null,
|
|
260
|
+
shouldValidateShareableContent: false
|
|
198
261
|
};
|
|
199
262
|
export default EntrySave;
|
|
@@ -310,6 +310,7 @@ export var StimulusEdit = (_dec = withStyleOverrides(generateStyle, generateComp
|
|
|
310
310
|
onAdd: this.handleAddToBank,
|
|
311
311
|
onContinue: this.handleAddToBankContinue,
|
|
312
312
|
getEntry: this.getEntryForBank,
|
|
313
|
+
workingEntry: this.props.workingStimulus,
|
|
313
314
|
quizId: this.props.quizId,
|
|
314
315
|
entryId: this.props.guid,
|
|
315
316
|
entryType: this.props.quizEntry.entryType
|
|
@@ -10,6 +10,8 @@ exports.default = void 0;
|
|
|
10
10
|
var _reactRedux = require("../../../common/react-redux.js");
|
|
11
11
|
var _banks = require("../../api/banks.js");
|
|
12
12
|
var _bankEntries = require("../../api/bankEntries.js");
|
|
13
|
+
var _items = require("../../../building/api/items.js");
|
|
14
|
+
var _stimuli = require("../../../building/api/stimuli.js");
|
|
13
15
|
var _presenter = _interopRequireDefault(require("./presenter.js"));
|
|
14
16
|
var modalActions = _interopRequireWildcard(require("../../../common/actions/modal.js"));
|
|
15
17
|
var _banks2 = require("../../../common/actions/banks.js");
|
|
@@ -18,6 +20,8 @@ var _quizCommon = require("@instructure/quiz-common");
|
|
|
18
20
|
var _modalHelpers = require("../../../common/util/modalHelpers.js");
|
|
19
21
|
function mapStateToProps(state, props) {
|
|
20
22
|
return {
|
|
23
|
+
canvasOrigin: state.getIn(['config', 'canvasOrigin']),
|
|
24
|
+
checkContentShareability: props.entryType === 'Item' ? _items.checkItemShareability : _stimuli.checkStimulusShareability,
|
|
21
25
|
modalTrigger: (0, _modalHelpers.getModalTrigger)(state),
|
|
22
26
|
modalOpen: state.getIn(['modal', 'isOpen']) === [_quizCommon.ADD_TO_BANK_MODAL, props.entryType, props.entryId].join(':')
|
|
23
27
|
};
|
|
@@ -6,12 +6,15 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
8
|
exports.default = exports.AddToBankModal = void 0;
|
|
9
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
10
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
9
11
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
12
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
11
13
|
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
12
14
|
var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper"));
|
|
13
15
|
var _react = _interopRequireWildcard(require("react"));
|
|
14
16
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
17
|
+
var _reactImmutableProptypes = _interopRequireDefault(require("react-immutable-proptypes"));
|
|
15
18
|
var _uiButtons = require("@instructure/ui-buttons");
|
|
16
19
|
var _uiHeading = require("@instructure/ui-heading");
|
|
17
20
|
var _uiTextInput = require("@instructure/ui-text-input");
|
|
@@ -19,10 +22,24 @@ var _uiRadioInput = require("@instructure/ui-radio-input");
|
|
|
19
22
|
var _uiA11yContent = require("@instructure/ui-a11y-content");
|
|
20
23
|
var _Bank = _interopRequireDefault(require("../../../common/records/Bank.js"));
|
|
21
24
|
var _presenter = _interopRequireDefault(require("../../../common/components/resources/BankSelection/presenter.js"));
|
|
25
|
+
var _uiSpinner = require("@instructure/ui-spinner");
|
|
26
|
+
var _uiText = require("@instructure/ui-text");
|
|
27
|
+
var _uiIcons = require("@instructure/ui-icons");
|
|
28
|
+
var _uiView = require("@instructure/ui-view");
|
|
29
|
+
var _uiFlex = require("@instructure/ui-flex");
|
|
22
30
|
var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message"));
|
|
23
31
|
var _quizCommon = require("@instructure/quiz-common");
|
|
24
32
|
var _featureCheck = require("../../../common/util/featureCheck.js");
|
|
25
|
-
var
|
|
33
|
+
var _ref2 = /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
|
|
34
|
+
padding: "0 small 0 0"
|
|
35
|
+
}, /*#__PURE__*/_react.default.createElement(_uiIcons.IconNoLine, {
|
|
36
|
+
color: "error",
|
|
37
|
+
size: "small"
|
|
38
|
+
}));
|
|
39
|
+
var _ref3 = /*#__PURE__*/_react.default.createElement(_uiIcons.IconWarningLine, {
|
|
40
|
+
color: "warning"
|
|
41
|
+
});
|
|
42
|
+
var _ref4 = /*#__PURE__*/_react.default.createElement("br", null);
|
|
26
43
|
var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
27
44
|
(0, _inherits2.default)(AddToBankModal, _Component);
|
|
28
45
|
var _super = (0, _createSuper2.default)(AddToBankModal);
|
|
@@ -35,6 +52,7 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
35
52
|
_this = _super.call.apply(_super, [this].concat(args));
|
|
36
53
|
_this.state = {
|
|
37
54
|
bankType: 'existing',
|
|
55
|
+
contentShareable: 'loading',
|
|
38
56
|
newBankTitle: '',
|
|
39
57
|
selectedBank: null
|
|
40
58
|
};
|
|
@@ -95,6 +113,57 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
95
113
|
return _this;
|
|
96
114
|
}
|
|
97
115
|
(0, _createClass2.default)(AddToBankModal, [{
|
|
116
|
+
key: "componentDidUpdate",
|
|
117
|
+
value: function componentDidUpdate(prevProps) {
|
|
118
|
+
var _this2 = this;
|
|
119
|
+
var _this$props = this.props,
|
|
120
|
+
canvasOrigin = _this$props.canvasOrigin,
|
|
121
|
+
modalOpen = _this$props.modalOpen,
|
|
122
|
+
checkContentShareability = _this$props.checkContentShareability,
|
|
123
|
+
workingEntry = _this$props.workingEntry;
|
|
124
|
+
if (modalOpen && !prevProps.modalOpen) {
|
|
125
|
+
this.setState({
|
|
126
|
+
contentShareable: 'loading'
|
|
127
|
+
});
|
|
128
|
+
checkContentShareability(workingEntry, canvasOrigin).then(function () {
|
|
129
|
+
_this2.setState({
|
|
130
|
+
contentShareable: 'true'
|
|
131
|
+
});
|
|
132
|
+
}).catch(/*#__PURE__*/function () {
|
|
133
|
+
var _ref = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(err) {
|
|
134
|
+
var _err$response, _err$response2;
|
|
135
|
+
var body;
|
|
136
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
137
|
+
while (1) {
|
|
138
|
+
switch (_context.prev = _context.next) {
|
|
139
|
+
case 0:
|
|
140
|
+
_context.next = 2;
|
|
141
|
+
return (_err$response = err.response) === null || _err$response === void 0 ? void 0 : _err$response.json();
|
|
142
|
+
case 2:
|
|
143
|
+
body = _context.sent;
|
|
144
|
+
if (((_err$response2 = err.response) === null || _err$response2 === void 0 ? void 0 : _err$response2.status) === 400 && body.shareable === false) {
|
|
145
|
+
_this2.setState({
|
|
146
|
+
contentShareable: 'false'
|
|
147
|
+
});
|
|
148
|
+
} else {
|
|
149
|
+
_this2.setState({
|
|
150
|
+
contentShareable: 'unknown'
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
case 4:
|
|
154
|
+
case "end":
|
|
155
|
+
return _context.stop();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}, _callee);
|
|
159
|
+
}));
|
|
160
|
+
return function (_x) {
|
|
161
|
+
return _ref.apply(this, arguments);
|
|
162
|
+
};
|
|
163
|
+
}());
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}, {
|
|
98
167
|
key: "cancelButton",
|
|
99
168
|
value: function cancelButton() {
|
|
100
169
|
return /*#__PURE__*/_react.default.createElement(_uiButtons.Button, {
|
|
@@ -107,8 +176,10 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
107
176
|
value: function addToBankButton() {
|
|
108
177
|
var _this$state = this.state,
|
|
109
178
|
bankType = _this$state.bankType,
|
|
110
|
-
newBankTitle = _this$state.newBankTitle
|
|
111
|
-
|
|
179
|
+
newBankTitle = _this$state.newBankTitle,
|
|
180
|
+
contentShareable = _this$state.contentShareable;
|
|
181
|
+
var contentShareableLoading = contentShareable === 'loading';
|
|
182
|
+
var disabled = bankType === 'existing' && !this.state.selectedBank || bankType === 'new' && (!newBankTitle || !newBankTitle.trim()) || contentShareableLoading;
|
|
112
183
|
return /*#__PURE__*/_react.default.createElement(_uiButtons.Button, {
|
|
113
184
|
type: "button",
|
|
114
185
|
color: "primary",
|
|
@@ -116,7 +187,7 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
116
187
|
disabled: disabled,
|
|
117
188
|
margin: _quizCommon.XSMALL_SIDE_MARGIN,
|
|
118
189
|
"data-automation": "sdk-add-to-bank-button"
|
|
119
|
-
}, (0, _formatMessage.default)('Add'));
|
|
190
|
+
}, !contentShareableLoading && contentShareable !== 'true' ? (0, _formatMessage.default)('Add anyway') : (0, _formatMessage.default)('Add'));
|
|
120
191
|
}
|
|
121
192
|
}, {
|
|
122
193
|
key: "renderBankTypeContent",
|
|
@@ -135,6 +206,35 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
135
206
|
type: "text"
|
|
136
207
|
});
|
|
137
208
|
}
|
|
209
|
+
}, {
|
|
210
|
+
key: "renderContentShareabilityMessage",
|
|
211
|
+
value: function renderContentShareabilityMessage() {
|
|
212
|
+
var content = null;
|
|
213
|
+
if (this.state.contentShareable === 'loading') {
|
|
214
|
+
content = /*#__PURE__*/_react.default.createElement(_uiText.Text, null, /*#__PURE__*/_react.default.createElement(_uiSpinner.Spinner, {
|
|
215
|
+
size: "x-small",
|
|
216
|
+
renderTitle: (0, _formatMessage.default)('Checking content shareability...')
|
|
217
|
+
}), "\xA0", (0, _formatMessage.default)('Validating content...'));
|
|
218
|
+
} else if (this.state.contentShareable === 'true') {
|
|
219
|
+
// No message needed. The API call to check shareability is very fast in most cases,
|
|
220
|
+
// so the user may be distracted by a message here.
|
|
221
|
+
content = null;
|
|
222
|
+
} else if (this.state.contentShareable === 'false') {
|
|
223
|
+
content = /*#__PURE__*/_react.default.createElement(_uiFlex.Flex, null, _ref2, /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
|
|
224
|
+
shouldShrink: true
|
|
225
|
+
}, /*#__PURE__*/_react.default.createElement(_uiText.Text, {
|
|
226
|
+
color: "danger"
|
|
227
|
+
}, (0, _formatMessage.default)('You are attempting to add content containing course links which may not work when used in other courses.'))));
|
|
228
|
+
} else {
|
|
229
|
+
content = /*#__PURE__*/_react.default.createElement(_uiText.Text, {
|
|
230
|
+
color: "warning"
|
|
231
|
+
}, _ref3, "\xA0", (0, _formatMessage.default)('There was an error attempting to validate shareability.'));
|
|
232
|
+
}
|
|
233
|
+
return /*#__PURE__*/_react.default.createElement(_uiView.View, {
|
|
234
|
+
as: "div",
|
|
235
|
+
margin: "small 0 0 0"
|
|
236
|
+
}, content);
|
|
237
|
+
}
|
|
138
238
|
}, {
|
|
139
239
|
key: "renderContent",
|
|
140
240
|
value: function renderContent() {
|
|
@@ -149,7 +249,7 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
149
249
|
}), /*#__PURE__*/_react.default.createElement(_uiRadioInput.RadioInput, {
|
|
150
250
|
value: "new",
|
|
151
251
|
label: (0, _formatMessage.default)('New item bank')
|
|
152
|
-
})),
|
|
252
|
+
})), _ref4, this.renderBankTypeContent(), this.renderContentShareabilityMessage());
|
|
153
253
|
}
|
|
154
254
|
}, {
|
|
155
255
|
key: "render",
|
|
@@ -176,6 +276,8 @@ var AddToBankModal = /*#__PURE__*/function (_Component) {
|
|
|
176
276
|
}(_react.Component);
|
|
177
277
|
exports.AddToBankModal = AddToBankModal;
|
|
178
278
|
AddToBankModal.propTypes = {
|
|
279
|
+
canvasOrigin: _propTypes.default.string,
|
|
280
|
+
checkContentShareability: _propTypes.default.func.isRequired,
|
|
179
281
|
closeModal: _propTypes.default.func.isRequired,
|
|
180
282
|
createBank: _propTypes.default.func.isRequired,
|
|
181
283
|
moveBankEntryFromQuizEntry: _propTypes.default.func.isRequired,
|
|
@@ -194,9 +296,11 @@ AddToBankModal.propTypes = {
|
|
|
194
296
|
onAdd: _propTypes.default.func,
|
|
195
297
|
onContinue: _propTypes.default.func,
|
|
196
298
|
uiSet: _propTypes.default.func.isRequired,
|
|
299
|
+
workingEntry: _reactImmutableProptypes.default.record.isRequired,
|
|
197
300
|
quizId: _propTypes.default.string.isRequired
|
|
198
301
|
};
|
|
199
302
|
AddToBankModal.defaultProps = {
|
|
303
|
+
canvasOrigin: '',
|
|
200
304
|
handleValidationErrorsFromApi: function handleValidationErrorsFromApi() {},
|
|
201
305
|
onAdd: function onAdd() {},
|
|
202
306
|
onContinue: function onContinue() {}
|
|
@@ -155,12 +155,14 @@ var BankEntry = (_dec = (0, _quizCommon.withStyleOverrides)(_styles.default, _th
|
|
|
155
155
|
clearChanges: _this.clearChanges,
|
|
156
156
|
clearValidationErrorsFromApi: _this.clearValidationErrorsFromApi,
|
|
157
157
|
contextUuid: null,
|
|
158
|
+
disableSubmit: Boolean(_this.state.validationErrorsFromApi && Object.values(_this.state.validationErrorsFromApi).length),
|
|
158
159
|
entry: entry,
|
|
159
160
|
guid: "".concat(_this.props.bankEntry.id, "_bank_entry_edit"),
|
|
160
161
|
handleQuizEntryPointsChange: _this.handlePointsChange,
|
|
161
162
|
itemEditArea: _this.itemEditArea,
|
|
162
163
|
parentId: _this.props.bankId,
|
|
163
164
|
parentType: _quizCommon.PARENT_TYPE_BANK,
|
|
165
|
+
shouldValidateShareableContent: true,
|
|
164
166
|
stimulus: entry,
|
|
165
167
|
submitHandler: _this.submitHandler,
|
|
166
168
|
validationErrorsFromApi: _this.state.validationErrorsFromApi,
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.getItem = getItem;
|
|
8
|
+
exports.checkItemShareability = checkItemShareability;
|
|
8
9
|
exports.createItem = createItem;
|
|
9
10
|
exports.updateItem = updateItem;
|
|
10
11
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
@@ -42,6 +43,19 @@ function getItem(itemId) {
|
|
|
42
43
|
});
|
|
43
44
|
};
|
|
44
45
|
}
|
|
46
|
+
function checkItemShareability(item, canvasOrigin) {
|
|
47
|
+
var url = '/api/items/check_shareability';
|
|
48
|
+
var requestBody = JSON.stringify({
|
|
49
|
+
item: updateItemParams(item),
|
|
50
|
+
source_origin: canvasOrigin
|
|
51
|
+
});
|
|
52
|
+
var fetcher = new _Fetcher.default({
|
|
53
|
+
onError: function onError() {}
|
|
54
|
+
});
|
|
55
|
+
return fetcher.post(url, {
|
|
56
|
+
body: requestBody
|
|
57
|
+
});
|
|
58
|
+
}
|
|
45
59
|
function createItem(item, parentId, parentType) {
|
|
46
60
|
var parentItemId = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : null;
|
|
47
61
|
var resource = parentType === 'bank' ? 'banks' : 'quizzes';
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.createStimulus = createStimulus;
|
|
8
8
|
exports.updateStimulus = updateStimulus;
|
|
9
|
+
exports.checkStimulusShareability = checkStimulusShareability;
|
|
9
10
|
var _quizCommon = require("@instructure/quiz-common");
|
|
10
11
|
var _alerts = require("../../common/actions/alerts.js");
|
|
11
12
|
var _callHandlers = require("../../common/api/callHandlers.js");
|
|
@@ -86,4 +87,17 @@ function updateStimulus(stimulus, parentId, parentType) {
|
|
|
86
87
|
return stimulusData;
|
|
87
88
|
});
|
|
88
89
|
};
|
|
90
|
+
}
|
|
91
|
+
function checkStimulusShareability(stimulus, canvasOrigin) {
|
|
92
|
+
var url = '/api/stimuli/check_shareability';
|
|
93
|
+
var requestBody = JSON.stringify({
|
|
94
|
+
stimulus: updateStimulusParams(stimulus),
|
|
95
|
+
source_origin: canvasOrigin
|
|
96
|
+
});
|
|
97
|
+
var fetcher = new _Fetcher.default({
|
|
98
|
+
onError: function onError() {}
|
|
99
|
+
});
|
|
100
|
+
return fetcher.post(url, {
|
|
101
|
+
body: requestBody
|
|
102
|
+
});
|
|
89
103
|
}
|
|
@@ -333,6 +333,7 @@ var QuizEntryEdit = (_dec = (0, _quizCommon.withStyleOverrides)(_styles.default,
|
|
|
333
333
|
onContinue: this.handleAddToBankContinue,
|
|
334
334
|
onAdd: this.handleAddToBank,
|
|
335
335
|
getEntry: this.getEntryForBank,
|
|
336
|
+
workingEntry: this.props.workingEntry,
|
|
336
337
|
entryId: this.props.guid,
|
|
337
338
|
entryType: this.props.quizEntry.entryType,
|
|
338
339
|
quizId: this.props.quizId,
|
|
@@ -7,16 +7,21 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.mapStateToProps = mapStateToProps;
|
|
8
8
|
exports.default = void 0;
|
|
9
9
|
var _reactRedux = require("../../../../react-redux.js");
|
|
10
|
+
var _items = require("../../../../../building/api/items.js");
|
|
11
|
+
var _stimuli = require("../../../../../building/api/stimuli.js");
|
|
10
12
|
var _makeEditable = _interopRequireDefault(require("../../../shared/functionality/makeEditable.js"));
|
|
11
13
|
var _errorsShowing = require("../../../../actions/errorsShowing.js");
|
|
12
14
|
var _alerts = require("../../../../actions/alerts.js");
|
|
13
15
|
var _modifications = require("../../../../actions/modifications.js");
|
|
16
|
+
var _modal = require("../../../../actions/modal.js");
|
|
14
17
|
var _presenter = _interopRequireDefault(require("./presenter.js"));
|
|
15
18
|
function mapStateToProps(state, props) {
|
|
16
19
|
// Error Related:
|
|
17
20
|
var workingEntry = props.entry.getWorkingInstance();
|
|
18
21
|
var isValid = props.isValid !== void 0 ? props.isValid : workingEntry.isValid();
|
|
19
22
|
return {
|
|
23
|
+
canvasOrigin: state.getIn(['config', 'canvasOrigin']),
|
|
24
|
+
checkContentShareability: props.entry.isStimulus ? _stimuli.checkStimulusShareability : _items.checkItemShareability,
|
|
20
25
|
isValid: isValid
|
|
21
26
|
};
|
|
22
27
|
}
|
|
@@ -24,7 +29,8 @@ var mapDispatchToProps = {
|
|
|
24
29
|
clearNextQuizEntry: _modifications.clearNextQuizEntry,
|
|
25
30
|
hideError: _errorsShowing.hideError,
|
|
26
31
|
screenreaderNotification: _alerts.screenreaderNotification,
|
|
27
|
-
showError: _errorsShowing.showError
|
|
32
|
+
showError: _errorsShowing.showError,
|
|
33
|
+
withConfirm: _modal.withConfirm
|
|
28
34
|
};
|
|
29
35
|
var _default = (0, _makeEditable.default)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_presenter.default));
|
|
30
36
|
exports.default = _default;
|
|
@@ -14,6 +14,7 @@ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits
|
|
|
14
14
|
var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper"));
|
|
15
15
|
var _react = _interopRequireWildcard(require("react"));
|
|
16
16
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
17
|
+
var _reactImmutableProptypes = _interopRequireDefault(require("react-immutable-proptypes"));
|
|
17
18
|
var _reactDom = _interopRequireDefault(require("react-dom"));
|
|
18
19
|
var _uiButtons = require("@instructure/ui-buttons");
|
|
19
20
|
var _uiView = require("@instructure/ui-view");
|
|
@@ -40,36 +41,91 @@ var EntrySave = /*#__PURE__*/function (_Component) {
|
|
|
40
41
|
});
|
|
41
42
|
_this.props.screenreaderNotification(msg);
|
|
42
43
|
};
|
|
44
|
+
_this.confirmShareableContent = function () {
|
|
45
|
+
var _this$props = _this.props,
|
|
46
|
+
canvasOrigin = _this$props.canvasOrigin,
|
|
47
|
+
checkContentShareability = _this$props.checkContentShareability,
|
|
48
|
+
entry = _this$props.entry,
|
|
49
|
+
withConfirm = _this$props.withConfirm;
|
|
50
|
+
_this.setState({
|
|
51
|
+
canSubmit: false
|
|
52
|
+
});
|
|
53
|
+
checkContentShareability(entry.getWorkingInstance(), canvasOrigin).then(function () {
|
|
54
|
+
_this.successfulSubmit();
|
|
55
|
+
}).catch(/*#__PURE__*/function () {
|
|
56
|
+
var _ref = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(err) {
|
|
57
|
+
var _err$response, _err$response2;
|
|
58
|
+
var body, text;
|
|
59
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
60
|
+
while (1) {
|
|
61
|
+
switch (_context.prev = _context.next) {
|
|
62
|
+
case 0:
|
|
63
|
+
_context.next = 2;
|
|
64
|
+
return (_err$response = err.response) === null || _err$response === void 0 ? void 0 : _err$response.json();
|
|
65
|
+
case 2:
|
|
66
|
+
body = _context.sent;
|
|
67
|
+
text = (0, _formatMessage.default)('There was an error attempting to validate shareability.');
|
|
68
|
+
if (((_err$response2 = err.response) === null || _err$response2 === void 0 ? void 0 : _err$response2.status) === 400 && body.shareable === false) {
|
|
69
|
+
text = (0, _formatMessage.default)('You are attempting to save content containing course links which may not work when used in other courses.');
|
|
70
|
+
}
|
|
71
|
+
withConfirm(function () {
|
|
72
|
+
_this.successfulSubmit();
|
|
73
|
+
}, {
|
|
74
|
+
title: (0, _formatMessage.default)('Are you sure?'),
|
|
75
|
+
text: text,
|
|
76
|
+
continueText: (0, _formatMessage.default)('Save anyway'),
|
|
77
|
+
onCancel: function onCancel() {
|
|
78
|
+
_this.setState({
|
|
79
|
+
canSubmit: true
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
case 6:
|
|
84
|
+
case "end":
|
|
85
|
+
return _context.stop();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}, _callee);
|
|
89
|
+
}));
|
|
90
|
+
return function (_x) {
|
|
91
|
+
return _ref.apply(this, arguments);
|
|
92
|
+
};
|
|
93
|
+
}());
|
|
94
|
+
};
|
|
43
95
|
_this.onSubmit = /*#__PURE__*/function () {
|
|
44
|
-
var
|
|
45
|
-
return _regenerator.default.wrap(function
|
|
96
|
+
var _ref2 = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2(e) {
|
|
97
|
+
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
46
98
|
while (1) {
|
|
47
|
-
switch (
|
|
99
|
+
switch (_context2.prev = _context2.next) {
|
|
48
100
|
case 0:
|
|
49
101
|
e.preventDefault();
|
|
50
102
|
if (!_this.props.isValid) {
|
|
51
|
-
|
|
103
|
+
_context2.next = 5;
|
|
52
104
|
break;
|
|
53
105
|
}
|
|
54
|
-
_this.
|
|
55
|
-
|
|
106
|
+
if (_this.props.shouldValidateShareableContent) {
|
|
107
|
+
_this.confirmShareableContent();
|
|
108
|
+
} else {
|
|
109
|
+
_this.successfulSubmit();
|
|
110
|
+
}
|
|
111
|
+
_context2.next = 10;
|
|
56
112
|
break;
|
|
57
113
|
case 5:
|
|
58
114
|
_this.createScreenReaderNotification();
|
|
59
|
-
|
|
115
|
+
_context2.next = 8;
|
|
60
116
|
return _this.props.showError(_this.props.guid);
|
|
61
117
|
case 8:
|
|
62
118
|
_this.props.clearNextQuizEntry();
|
|
63
119
|
_this.focusFirstErrorField();
|
|
64
120
|
case 10:
|
|
65
121
|
case "end":
|
|
66
|
-
return
|
|
122
|
+
return _context2.stop();
|
|
67
123
|
}
|
|
68
124
|
}
|
|
69
|
-
},
|
|
125
|
+
}, _callee2);
|
|
70
126
|
}));
|
|
71
|
-
return function (
|
|
72
|
-
return
|
|
127
|
+
return function (_x2) {
|
|
128
|
+
return _ref2.apply(this, arguments);
|
|
73
129
|
};
|
|
74
130
|
}();
|
|
75
131
|
_this.focusFirstErrorField = function () {
|
|
@@ -107,46 +163,46 @@ var EntrySave = /*#__PURE__*/function (_Component) {
|
|
|
107
163
|
}, {
|
|
108
164
|
key: "successfulSubmit",
|
|
109
165
|
value: function () {
|
|
110
|
-
var _successfulSubmit = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function
|
|
166
|
+
var _successfulSubmit = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
111
167
|
var validationResult;
|
|
112
|
-
return _regenerator.default.wrap(function
|
|
168
|
+
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
113
169
|
while (1) {
|
|
114
|
-
switch (
|
|
170
|
+
switch (_context3.prev = _context3.next) {
|
|
115
171
|
case 0:
|
|
116
172
|
this.setState({
|
|
117
173
|
canSubmit: false
|
|
118
174
|
});
|
|
119
|
-
|
|
120
|
-
|
|
175
|
+
_context3.prev = 1;
|
|
176
|
+
_context3.next = 4;
|
|
121
177
|
return this.props.submitHandler();
|
|
122
178
|
case 4:
|
|
123
|
-
validationResult =
|
|
179
|
+
validationResult = _context3.sent;
|
|
124
180
|
if (!(validationResult === _quizCommon.API_INPUT_VALIDATION_ERROR)) {
|
|
125
|
-
|
|
181
|
+
_context3.next = 8;
|
|
126
182
|
break;
|
|
127
183
|
}
|
|
128
184
|
this.createScreenReaderNotification();
|
|
129
185
|
throw new Error('User input validation error received from API.');
|
|
130
186
|
case 8:
|
|
131
|
-
|
|
187
|
+
_context3.next = 14;
|
|
132
188
|
break;
|
|
133
189
|
case 10:
|
|
134
|
-
|
|
135
|
-
|
|
190
|
+
_context3.prev = 10;
|
|
191
|
+
_context3.t0 = _context3["catch"](1);
|
|
136
192
|
this.setState({
|
|
137
193
|
canSubmit: true
|
|
138
194
|
});
|
|
139
|
-
return
|
|
195
|
+
return _context3.abrupt("return");
|
|
140
196
|
case 14:
|
|
141
197
|
this.props.switchOffEditing();
|
|
142
198
|
this.props.hideError(this.props.guid);
|
|
143
199
|
this.props.screenreaderNotification((0, _formatMessage.default)('Changes to question saved.'));
|
|
144
200
|
case 17:
|
|
145
201
|
case "end":
|
|
146
|
-
return
|
|
202
|
+
return _context3.stop();
|
|
147
203
|
}
|
|
148
204
|
}
|
|
149
|
-
},
|
|
205
|
+
}, _callee3, this, [[1, 10]]);
|
|
150
206
|
}));
|
|
151
207
|
function successfulSubmit() {
|
|
152
208
|
return _successfulSubmit.apply(this, arguments);
|
|
@@ -180,11 +236,14 @@ var EntrySave = /*#__PURE__*/function (_Component) {
|
|
|
180
236
|
exports.EntrySave = EntrySave;
|
|
181
237
|
EntrySave.propTypes = {
|
|
182
238
|
cancelHandler: _propTypes.default.func,
|
|
239
|
+
canvasOrigin: _propTypes.default.string,
|
|
240
|
+
checkContentShareability: _propTypes.default.func.isRequired,
|
|
183
241
|
clearChanges: _propTypes.default.func.isRequired,
|
|
184
242
|
// From connected component
|
|
185
243
|
clearNextQuizEntry: _propTypes.default.func.isRequired,
|
|
186
244
|
disableSubmit: _propTypes.default.bool,
|
|
187
245
|
displayPosition: _propTypes.default.number,
|
|
246
|
+
entry: _reactImmutableProptypes.default.record.isRequired,
|
|
188
247
|
guid: _propTypes.default.string,
|
|
189
248
|
hideError: _propTypes.default.func.isRequired,
|
|
190
249
|
initialFocusId: _propTypes.default.string,
|
|
@@ -192,18 +251,22 @@ EntrySave.propTypes = {
|
|
|
192
251
|
itemEditArea: _propTypes.default.object,
|
|
193
252
|
showError: _propTypes.default.func.isRequired,
|
|
194
253
|
screenreaderNotification: _propTypes.default.func.isRequired,
|
|
254
|
+
shouldValidateShareableContent: _propTypes.default.bool,
|
|
195
255
|
submitHandler: _propTypes.default.func.isRequired,
|
|
196
256
|
// from makescrollable / from props being passed in occasionally
|
|
197
257
|
switchOnEditing: _propTypes.default.func.isRequired,
|
|
198
|
-
switchOffEditing: _propTypes.default.func.isRequired
|
|
258
|
+
switchOffEditing: _propTypes.default.func.isRequired,
|
|
259
|
+
withConfirm: _propTypes.default.func.isRequired
|
|
199
260
|
};
|
|
200
261
|
EntrySave.defaultProps = {
|
|
201
262
|
cancelHandler: _noop.default,
|
|
202
|
-
|
|
263
|
+
canvasOrigin: '',
|
|
203
264
|
displayPosition: null,
|
|
265
|
+
disableSubmit: false,
|
|
204
266
|
guid: null,
|
|
205
267
|
initialFocusId: null,
|
|
206
|
-
itemEditArea: null
|
|
268
|
+
itemEditArea: null,
|
|
269
|
+
shouldValidateShareableContent: false
|
|
207
270
|
};
|
|
208
271
|
var _default = EntrySave;
|
|
209
272
|
exports.default = _default;
|
|
@@ -317,6 +317,7 @@ var StimulusEdit = (_dec = (0, _quizCommon.withStyleOverrides)(_styles.default,
|
|
|
317
317
|
onAdd: this.handleAddToBank,
|
|
318
318
|
onContinue: this.handleAddToBankContinue,
|
|
319
319
|
getEntry: this.getEntryForBank,
|
|
320
|
+
workingEntry: this.props.workingStimulus,
|
|
320
321
|
quizId: this.props.quizId,
|
|
321
322
|
entryId: this.props.guid,
|
|
322
323
|
entryType: this.props.quizEntry.entryType
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/quiz-core",
|
|
3
|
-
"version": "20.35.1-
|
|
3
|
+
"version": "20.35.1-rc10.6+fa6c4eddf",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "The Quiz React SDK by Instructure Inc.",
|
|
6
6
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"@instructure/emotion": "^8.56.3",
|
|
47
47
|
"@instructure/grading-utils": "^1.0.0",
|
|
48
48
|
"@instructure/outcomes-ui": "^3.2.2",
|
|
49
|
-
"@instructure/quiz-common": "^20.35.1-
|
|
50
|
-
"@instructure/quiz-i18n": "^20.35.1-
|
|
51
|
-
"@instructure/quiz-interactions": "^20.35.1-
|
|
52
|
-
"@instructure/quiz-number-input": "^20.35.1-
|
|
53
|
-
"@instructure/quiz-rce": "^20.35.1-
|
|
49
|
+
"@instructure/quiz-common": "^20.35.1-rc10.6+fa6c4eddf",
|
|
50
|
+
"@instructure/quiz-i18n": "^20.35.1-rc10.6+fa6c4eddf",
|
|
51
|
+
"@instructure/quiz-interactions": "^20.35.1-rc10.6+fa6c4eddf",
|
|
52
|
+
"@instructure/quiz-number-input": "^20.35.1-rc10.6+fa6c4eddf",
|
|
53
|
+
"@instructure/quiz-rce": "^20.35.1-rc10.6+fa6c4eddf",
|
|
54
54
|
"@instructure/ui-a11y-content": "^8.56.3",
|
|
55
55
|
"@instructure/ui-alerts": "^8.56.3",
|
|
56
56
|
"@instructure/ui-avatar": "^8.56.3",
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
"file-saver": "~2.0.5",
|
|
115
115
|
"humps": "^2.0.0",
|
|
116
116
|
"immutable": "^3.8.1",
|
|
117
|
-
"instructure-validations": "^20.35.1-
|
|
117
|
+
"instructure-validations": "^20.35.1-rc10.6+fa6c4eddf",
|
|
118
118
|
"ipaddr.js": "^1.5.4",
|
|
119
119
|
"isomorphic-fetch": "^2.2.0",
|
|
120
120
|
"isuuid": "^0.1.0",
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
"jquery": "^2.2.3",
|
|
164
164
|
"karma-junit-reporter": "^2.0.1",
|
|
165
165
|
"most-subject": "^5.3.0",
|
|
166
|
-
"quiz-presets": "^20.35.1-
|
|
166
|
+
"quiz-presets": "^20.35.1-rc10.6+fa6c4eddf",
|
|
167
167
|
"react": "^16.8.6",
|
|
168
168
|
"react-addons-test-utils": "^15.6.2",
|
|
169
169
|
"react-dom": "^16.8.6",
|
|
@@ -179,5 +179,5 @@
|
|
|
179
179
|
"publishConfig": {
|
|
180
180
|
"access": "public"
|
|
181
181
|
},
|
|
182
|
-
"gitHead": "
|
|
182
|
+
"gitHead": "fa6c4eddf1ebf4a2f89b7159991a58165ff92307"
|
|
183
183
|
}
|