@instructure/quiz-core 21.0.1-rc.20 → 21.0.1-rc.22

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.
@@ -31,17 +31,27 @@ import BankSelection from '../../../common/components/resources/BankSelection/pr
31
31
  import { Modal, ModalHeader, ModalBody, ModalFooter, COPY_MOVE_BANK_ENTRY_MODAL_KEEP_COPY, TextInput, XSMALL_SIDE_MARGIN } from '@instructure/quiz-common';
32
32
  import { featureOn } from '../../../common/util/featureCheck';
33
33
  export var CopyMoveBankEntryModal = /*#__PURE__*/function (_Component) {
34
- function CopyMoveBankEntryModal() {
34
+ function CopyMoveBankEntryModal(props) {
35
35
  var _this2;
36
36
  _classCallCheck(this, CopyMoveBankEntryModal);
37
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
38
- args[_key] = arguments[_key];
39
- }
40
- _this2 = _callSuper(this, CopyMoveBankEntryModal, [].concat(args));
37
+ _this2 = _callSuper(this, CopyMoveBankEntryModal, [props]);
38
+ /**
39
+ * @type {React.RefObject<RadioInput> | null}
40
+ */
41
+ _defineProperty(_this2, "radioInputRef", null);
42
+ /**
43
+ * @type {React.RefObject<TextInput> | null}
44
+ */
45
+ _defineProperty(_this2, "textInputRef", null);
41
46
  _defineProperty(_this2, "state", {
42
47
  bankType: 'existing',
43
48
  newBankTitle: '',
44
- selectedBank: null
49
+ selectedBank: null,
50
+ radioValidationError: null,
51
+ selectValidationError: null
52
+ });
53
+ _defineProperty(_this2, "setBankInputRef", function (ref) {
54
+ _this2.bankSelectionInputRef = ref;
45
55
  });
46
56
  _defineProperty(_this2, "copyOrMove", function (newBankId) {
47
57
  if (_this2.props.keepCopy) {
@@ -51,7 +61,55 @@ export var CopyMoveBankEntryModal = /*#__PURE__*/function (_Component) {
51
61
  }
52
62
  _this2.closeAction();
53
63
  });
64
+ _defineProperty(_this2, "clearValidationErrors", function () {
65
+ _this2.setState({
66
+ radioValidationError: null,
67
+ selectValidationError: null
68
+ });
69
+ });
70
+ _defineProperty(_this2, "validateAction", function () {
71
+ var _this2$state = _this2.state,
72
+ bankType = _this2$state.bankType,
73
+ newBankTitle = _this2$state.newBankTitle,
74
+ selectedBank = _this2$state.selectedBank;
75
+ if (!bankType) {
76
+ var _this2$radioInputRef;
77
+ (_this2$radioInputRef = _this2.radioInputRef) === null || _this2$radioInputRef === void 0 || (_this2$radioInputRef = _this2$radioInputRef.current) === null || _this2$radioInputRef === void 0 || _this2$radioInputRef.focus();
78
+ _this2.setState({
79
+ radioValidationError: [{
80
+ text: t('Please choose a Copy/Move option'),
81
+ type: 'newError'
82
+ }]
83
+ });
84
+ return false;
85
+ }
86
+ if (bankType === 'existing' && !selectedBank) {
87
+ _this2.bankSelectionInputRef.focus();
88
+ _this2.setState({
89
+ selectValidationError: [{
90
+ text: t('Please select a bank'),
91
+ type: 'newError'
92
+ }]
93
+ });
94
+ return false;
95
+ }
96
+ if (bankType === 'new' && (!newBankTitle || !newBankTitle.trim())) {
97
+ var _this2$textInputRef;
98
+ (_this2$textInputRef = _this2.textInputRef) === null || _this2$textInputRef === void 0 || (_this2$textInputRef = _this2$textInputRef.current) === null || _this2$textInputRef === void 0 || _this2$textInputRef.focus();
99
+ _this2.setState({
100
+ selectValidationError: [{
101
+ text: t('Please enter a new bank title'),
102
+ type: 'newError'
103
+ }]
104
+ });
105
+ return false;
106
+ }
107
+ return true;
108
+ });
54
109
  _defineProperty(_this2, "continueAction", function () {
110
+ if (!_this2.validateAction()) {
111
+ return;
112
+ }
55
113
  if (_this2.state.bankType === 'new') {
56
114
  var newBank = Bank.create({
57
115
  title: _this2.state.newBankTitle,
@@ -92,12 +150,14 @@ export var CopyMoveBankEntryModal = /*#__PURE__*/function (_Component) {
92
150
  return _this2.initiateCopy(newBankId).then(_this2.props.onAdd);
93
151
  });
94
152
  _defineProperty(_this2, "closeAction", function () {
153
+ _this2.clearValidationErrors();
95
154
  if (_this2.props.modalTrigger) {
96
155
  _this2.props.modalTrigger.focus();
97
156
  }
98
157
  _this2.props.closeModal();
99
158
  });
100
159
  _defineProperty(_this2, "onBankSelection", function (e, option) {
160
+ _this2.clearValidationErrors();
101
161
  _this2.setState({
102
162
  selectedBank: new Bank(option)
103
163
  });
@@ -106,15 +166,20 @@ export var CopyMoveBankEntryModal = /*#__PURE__*/function (_Component) {
106
166
  _this2.props.uiSet(COPY_MOVE_BANK_ENTRY_MODAL_KEEP_COPY, e.target.checked);
107
167
  });
108
168
  _defineProperty(_this2, "handleRadioChange", function (event, value) {
169
+ _this2.clearValidationErrors();
109
170
  _this2.setState({
110
171
  bankType: value
111
172
  });
112
173
  });
113
174
  _defineProperty(_this2, "onTitleChange", function (e) {
175
+ _this2.clearValidationErrors();
114
176
  _this2.setState({
115
177
  newBankTitle: e.target.value
116
178
  });
117
179
  });
180
+ _this2.radioInputRef = React.createRef();
181
+ _this2.textInputRef = React.createRef();
182
+ _this2.bankSelectionInputRef = React.createRef();
118
183
  return _this2;
119
184
  }
120
185
  _inherits(CopyMoveBankEntryModal, _Component);
@@ -129,14 +194,9 @@ export var CopyMoveBankEntryModal = /*#__PURE__*/function (_Component) {
129
194
  }, {
130
195
  key: "addToBankButton",
131
196
  value: function addToBankButton() {
132
- var _this$state = this.state,
133
- bankType = _this$state.bankType,
134
- newBankTitle = _this$state.newBankTitle;
135
- var disabled = bankType === 'existing' && !this.state.selectedBank || bankType === 'new' && (!newBankTitle || !newBankTitle.trim());
136
197
  return /*#__PURE__*/React.createElement(Button, {
137
198
  color: "primary",
138
199
  onClick: this.continueAction,
139
- disabled: disabled,
140
200
  margin: XSMALL_SIDE_MARGIN,
141
201
  "data-automation": "sdk-add-to-bank-button"
142
202
  }, t('Add'));
@@ -146,16 +206,22 @@ export var CopyMoveBankEntryModal = /*#__PURE__*/function (_Component) {
146
206
  value: function renderBankTypeContent() {
147
207
  if (this.state.bankType === 'existing') {
148
208
  return /*#__PURE__*/React.createElement(BankSelection, {
209
+ inputRef: this.setBankInputRef,
149
210
  onBankSelection: this.onBankSelection,
150
211
  selectedBank: this.state.selectedBank,
151
- "data-automation": "sdk-bank-selection"
212
+ "data-automation": "sdk-bank-selection",
213
+ externalError: this.state.selectValidationError,
214
+ isRequired: true
152
215
  });
153
216
  }
154
217
  return /*#__PURE__*/React.createElement(TextInput, {
155
218
  onChange: this.onTitleChange,
156
219
  value: this.state.newBankTitle,
157
220
  renderLabel: t('New Bank Title'),
158
- type: "text"
221
+ type: "text",
222
+ messages: this.state.selectValidationError,
223
+ ref: this.textInputRef,
224
+ isRequired: true
159
225
  });
160
226
  }
161
227
  }, {
@@ -165,10 +231,13 @@ export var CopyMoveBankEntryModal = /*#__PURE__*/function (_Component) {
165
231
  onChange: this.handleRadioChange,
166
232
  name: t('Bank Type'),
167
233
  defaultValue: this.state.bankType,
168
- description: /*#__PURE__*/React.createElement(ScreenReaderContent, null, t('Bank Type'))
234
+ description: /*#__PURE__*/React.createElement(ScreenReaderContent, null, t('Bank Type')),
235
+ messages: this.state.radioValidationError,
236
+ isRequired: true
169
237
  }, /*#__PURE__*/React.createElement(RadioInput, {
170
238
  value: "existing",
171
- label: t('Existing item bank')
239
+ label: t('Existing item bank'),
240
+ ref: this.radioInputRef
172
241
  }), /*#__PURE__*/React.createElement(RadioInput, {
173
242
  value: "new",
174
243
  label: t('New item bank')
@@ -27,13 +27,15 @@ import { toErrors } from '../../../util/instUIMessages';
27
27
  import { simpleFetchBanks } from '../../../../banks/api/banks';
28
28
  import { GenericAsyncSearch } from '../../shared/GenericAsyncSearch/GenericAsyncSearch';
29
29
  export var BankSelection = /*#__PURE__*/function (_Component) {
30
- function BankSelection() {
30
+ function BankSelection(props) {
31
31
  var _this2;
32
32
  _classCallCheck(this, BankSelection);
33
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
34
- args[_key] = arguments[_key];
35
- }
36
- _this2 = _callSuper(this, BankSelection, [].concat(args));
33
+ _this2 = _callSuper(this, BankSelection, [props]);
34
+ _defineProperty(_this2, "setInputRef", function (ref) {
35
+ var _this2$props$inputRef, _this2$props;
36
+ _this2.inputRef = ref;
37
+ (_this2$props$inputRef = (_this2$props = _this2.props).inputRef) === null || _this2$props$inputRef === void 0 || _this2$props$inputRef.call(_this2$props, ref);
38
+ });
37
39
  _defineProperty(_this2, "searchBanks", function (search) {
38
40
  return _this2.props.simpleFetchBanks({
39
41
  search: search
@@ -56,18 +58,31 @@ export var BankSelection = /*#__PURE__*/function (_Component) {
56
58
  archived: bankOption.archived
57
59
  });
58
60
  });
61
+ _this2.inputRef = null;
59
62
  return _this2;
60
63
  }
61
64
  _inherits(BankSelection, _Component);
62
65
  return _createClass(BankSelection, [{
66
+ key: "focusSelectField",
67
+ value: function focusSelectField() {
68
+ if (this.inputRef) {
69
+ this.inputRef.focus();
70
+ }
71
+ }
72
+ }, {
63
73
  key: "getErrors",
64
74
  value: function getErrors() {
65
75
  var selectedBank = this.props.selectedBank;
66
76
  if (selectedBank && selectedBank.archived) {
77
+ this.focusSelectField();
67
78
  return toErrors([t('The item bank "{ bankTitle }" no longer exists. Please select a valid bank.', {
68
79
  bankTitle: selectedBank.title
69
80
  })]);
70
81
  }
82
+ if (this.props.externalError) {
83
+ this.focusSelectField();
84
+ return this.props.externalError;
85
+ }
71
86
  }
72
87
  }, {
73
88
  key: "selectedOption",
@@ -83,13 +98,15 @@ export var BankSelection = /*#__PURE__*/function (_Component) {
83
98
  key: "render",
84
99
  value: function render() {
85
100
  return /*#__PURE__*/React.createElement(GenericAsyncSearch, {
101
+ inputRef: this.setInputRef,
86
102
  onSelectionChange: this.onSelect,
87
103
  label: this.props.label || t('Select the destination bank'),
88
104
  placeholder: t('Search for a bank'),
89
105
  selectedOption: this.selectedOption(),
90
106
  getOptions: this.searchBanks,
91
107
  messages: this.getErrors(),
92
- selectAutomation: 'sdk-item-bank-modal'
108
+ selectAutomation: 'sdk-item-bank-modal',
109
+ isRequired: this.props.isRequired
93
110
  });
94
111
  }
95
112
  }]);
@@ -98,12 +115,18 @@ _defineProperty(BankSelection, "propTypes", {
98
115
  label: PropTypes.string,
99
116
  onBankSelection: PropTypes.func,
100
117
  selectedBank: ImmutablePropTypes.record,
101
- simpleFetchBanks: PropTypes.func
118
+ simpleFetchBanks: PropTypes.func,
119
+ externalError: ImmutablePropTypes.record,
120
+ inputRef: PropTypes.func,
121
+ isRequired: PropTypes.bool
102
122
  });
103
123
  _defineProperty(BankSelection, "defaultProps", {
104
124
  label: null,
105
125
  onBankSelection: function onBankSelection() {},
106
126
  selectedBank: null,
107
- simpleFetchBanks: simpleFetchBanks
127
+ simpleFetchBanks: simpleFetchBanks,
128
+ externalError: null,
129
+ inputRef: function inputRef() {},
130
+ isRequired: false
108
131
  });
109
132
  export default BankSelection;
@@ -30,7 +30,9 @@ export var GenericAsyncSearch = /*#__PURE__*/function (_Component) {
30
30
  _classCallCheck(this, GenericAsyncSearch);
31
31
  _this2 = _callSuper(this, GenericAsyncSearch, arguments);
32
32
  _defineProperty(_this2, "setInputRef", function (inputRef) {
33
+ var _this2$props$inputRef, _this2$props;
33
34
  _this2.inputRef = inputRef;
35
+ (_this2$props$inputRef = (_this2$props = _this2.props).inputRef) === null || _this2$props$inputRef === void 0 || _this2$props$inputRef.call(_this2$props, inputRef);
34
36
  });
35
37
  _defineProperty(_this2, "state", {
36
38
  inputValue: _this2.props.selectedOption ? _this2.props.selectedOption.text : '',
@@ -161,7 +163,8 @@ export var GenericAsyncSearch = /*#__PURE__*/function (_Component) {
161
163
  onRequestHighlightOption: this.handleHighlightOption,
162
164
  onRequestSelectOption: this.handleSelectOption,
163
165
  onKeyDown: this.handleKeyDown,
164
- messages: this.props.messages
166
+ messages: this.props.messages,
167
+ isRequired: this.props.isRequired
165
168
  }, this.renderOptions());
166
169
  }
167
170
  }]);
@@ -178,13 +181,17 @@ _defineProperty(GenericAsyncSearch, "propTypes", {
178
181
  }),
179
182
  messages: PropTypes.array,
180
183
  selectAutomation: PropTypes.string,
181
- getOptions: PropTypes.func.isRequired
184
+ getOptions: PropTypes.func.isRequired,
185
+ inputRef: PropTypes.func,
186
+ isRequired: PropTypes.bool
182
187
  });
183
188
  _defineProperty(GenericAsyncSearch, "defaultProps", {
184
189
  debounceDelay: 500,
185
190
  minChars: 3,
186
191
  label: null,
187
192
  placeholder: null,
188
- selectAutomation: null
193
+ selectAutomation: null,
194
+ inputRef: function inputRef() {},
195
+ isRequired: false
189
196
  });
190
197
  export default GenericAsyncSearch;
@@ -40,17 +40,27 @@ function _callSuper(_this, derived, args) {
40
40
  return (0, _possibleConstructorReturn2["default"])(_this, isNativeReflectConstruct() ? Reflect.construct(derived, args || [], (0, _getPrototypeOf2["default"])(_this).constructor) : derived.apply(_this, args));
41
41
  }
42
42
  var CopyMoveBankEntryModal = exports.CopyMoveBankEntryModal = /*#__PURE__*/function (_Component) {
43
- function CopyMoveBankEntryModal() {
43
+ function CopyMoveBankEntryModal(props) {
44
44
  var _this2;
45
45
  (0, _classCallCheck2["default"])(this, CopyMoveBankEntryModal);
46
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
47
- args[_key] = arguments[_key];
48
- }
49
- _this2 = _callSuper(this, CopyMoveBankEntryModal, [].concat(args));
46
+ _this2 = _callSuper(this, CopyMoveBankEntryModal, [props]);
47
+ /**
48
+ * @type {React.RefObject<RadioInput> | null}
49
+ */
50
+ (0, _defineProperty2["default"])(_this2, "radioInputRef", null);
51
+ /**
52
+ * @type {React.RefObject<TextInput> | null}
53
+ */
54
+ (0, _defineProperty2["default"])(_this2, "textInputRef", null);
50
55
  (0, _defineProperty2["default"])(_this2, "state", {
51
56
  bankType: 'existing',
52
57
  newBankTitle: '',
53
- selectedBank: null
58
+ selectedBank: null,
59
+ radioValidationError: null,
60
+ selectValidationError: null
61
+ });
62
+ (0, _defineProperty2["default"])(_this2, "setBankInputRef", function (ref) {
63
+ _this2.bankSelectionInputRef = ref;
54
64
  });
55
65
  (0, _defineProperty2["default"])(_this2, "copyOrMove", function (newBankId) {
56
66
  if (_this2.props.keepCopy) {
@@ -60,7 +70,55 @@ var CopyMoveBankEntryModal = exports.CopyMoveBankEntryModal = /*#__PURE__*/funct
60
70
  }
61
71
  _this2.closeAction();
62
72
  });
73
+ (0, _defineProperty2["default"])(_this2, "clearValidationErrors", function () {
74
+ _this2.setState({
75
+ radioValidationError: null,
76
+ selectValidationError: null
77
+ });
78
+ });
79
+ (0, _defineProperty2["default"])(_this2, "validateAction", function () {
80
+ var _this2$state = _this2.state,
81
+ bankType = _this2$state.bankType,
82
+ newBankTitle = _this2$state.newBankTitle,
83
+ selectedBank = _this2$state.selectedBank;
84
+ if (!bankType) {
85
+ var _this2$radioInputRef;
86
+ (_this2$radioInputRef = _this2.radioInputRef) === null || _this2$radioInputRef === void 0 || (_this2$radioInputRef = _this2$radioInputRef.current) === null || _this2$radioInputRef === void 0 || _this2$radioInputRef.focus();
87
+ _this2.setState({
88
+ radioValidationError: [{
89
+ text: (0, _formatMessage["default"])('Please choose a Copy/Move option'),
90
+ type: 'newError'
91
+ }]
92
+ });
93
+ return false;
94
+ }
95
+ if (bankType === 'existing' && !selectedBank) {
96
+ _this2.bankSelectionInputRef.focus();
97
+ _this2.setState({
98
+ selectValidationError: [{
99
+ text: (0, _formatMessage["default"])('Please select a bank'),
100
+ type: 'newError'
101
+ }]
102
+ });
103
+ return false;
104
+ }
105
+ if (bankType === 'new' && (!newBankTitle || !newBankTitle.trim())) {
106
+ var _this2$textInputRef;
107
+ (_this2$textInputRef = _this2.textInputRef) === null || _this2$textInputRef === void 0 || (_this2$textInputRef = _this2$textInputRef.current) === null || _this2$textInputRef === void 0 || _this2$textInputRef.focus();
108
+ _this2.setState({
109
+ selectValidationError: [{
110
+ text: (0, _formatMessage["default"])('Please enter a new bank title'),
111
+ type: 'newError'
112
+ }]
113
+ });
114
+ return false;
115
+ }
116
+ return true;
117
+ });
63
118
  (0, _defineProperty2["default"])(_this2, "continueAction", function () {
119
+ if (!_this2.validateAction()) {
120
+ return;
121
+ }
64
122
  if (_this2.state.bankType === 'new') {
65
123
  var newBank = _Bank["default"].create({
66
124
  title: _this2.state.newBankTitle,
@@ -101,12 +159,14 @@ var CopyMoveBankEntryModal = exports.CopyMoveBankEntryModal = /*#__PURE__*/funct
101
159
  return _this2.initiateCopy(newBankId).then(_this2.props.onAdd);
102
160
  });
103
161
  (0, _defineProperty2["default"])(_this2, "closeAction", function () {
162
+ _this2.clearValidationErrors();
104
163
  if (_this2.props.modalTrigger) {
105
164
  _this2.props.modalTrigger.focus();
106
165
  }
107
166
  _this2.props.closeModal();
108
167
  });
109
168
  (0, _defineProperty2["default"])(_this2, "onBankSelection", function (e, option) {
169
+ _this2.clearValidationErrors();
110
170
  _this2.setState({
111
171
  selectedBank: new _Bank["default"](option)
112
172
  });
@@ -115,15 +175,20 @@ var CopyMoveBankEntryModal = exports.CopyMoveBankEntryModal = /*#__PURE__*/funct
115
175
  _this2.props.uiSet(_quizCommon.COPY_MOVE_BANK_ENTRY_MODAL_KEEP_COPY, e.target.checked);
116
176
  });
117
177
  (0, _defineProperty2["default"])(_this2, "handleRadioChange", function (event, value) {
178
+ _this2.clearValidationErrors();
118
179
  _this2.setState({
119
180
  bankType: value
120
181
  });
121
182
  });
122
183
  (0, _defineProperty2["default"])(_this2, "onTitleChange", function (e) {
184
+ _this2.clearValidationErrors();
123
185
  _this2.setState({
124
186
  newBankTitle: e.target.value
125
187
  });
126
188
  });
189
+ _this2.radioInputRef = _react["default"].createRef();
190
+ _this2.textInputRef = _react["default"].createRef();
191
+ _this2.bankSelectionInputRef = _react["default"].createRef();
127
192
  return _this2;
128
193
  }
129
194
  (0, _inherits2["default"])(CopyMoveBankEntryModal, _Component);
@@ -138,14 +203,9 @@ var CopyMoveBankEntryModal = exports.CopyMoveBankEntryModal = /*#__PURE__*/funct
138
203
  }, {
139
204
  key: "addToBankButton",
140
205
  value: function addToBankButton() {
141
- var _this$state = this.state,
142
- bankType = _this$state.bankType,
143
- newBankTitle = _this$state.newBankTitle;
144
- var disabled = bankType === 'existing' && !this.state.selectedBank || bankType === 'new' && (!newBankTitle || !newBankTitle.trim());
145
206
  return /*#__PURE__*/_react["default"].createElement(_uiButtons.Button, {
146
207
  color: "primary",
147
208
  onClick: this.continueAction,
148
- disabled: disabled,
149
209
  margin: _quizCommon.XSMALL_SIDE_MARGIN,
150
210
  "data-automation": "sdk-add-to-bank-button"
151
211
  }, (0, _formatMessage["default"])('Add'));
@@ -155,16 +215,22 @@ var CopyMoveBankEntryModal = exports.CopyMoveBankEntryModal = /*#__PURE__*/funct
155
215
  value: function renderBankTypeContent() {
156
216
  if (this.state.bankType === 'existing') {
157
217
  return /*#__PURE__*/_react["default"].createElement(_presenter["default"], {
218
+ inputRef: this.setBankInputRef,
158
219
  onBankSelection: this.onBankSelection,
159
220
  selectedBank: this.state.selectedBank,
160
- "data-automation": "sdk-bank-selection"
221
+ "data-automation": "sdk-bank-selection",
222
+ externalError: this.state.selectValidationError,
223
+ isRequired: true
161
224
  });
162
225
  }
163
226
  return /*#__PURE__*/_react["default"].createElement(_quizCommon.TextInput, {
164
227
  onChange: this.onTitleChange,
165
228
  value: this.state.newBankTitle,
166
229
  renderLabel: (0, _formatMessage["default"])('New Bank Title'),
167
- type: "text"
230
+ type: "text",
231
+ messages: this.state.selectValidationError,
232
+ ref: this.textInputRef,
233
+ isRequired: true
168
234
  });
169
235
  }
170
236
  }, {
@@ -174,10 +240,13 @@ var CopyMoveBankEntryModal = exports.CopyMoveBankEntryModal = /*#__PURE__*/funct
174
240
  onChange: this.handleRadioChange,
175
241
  name: (0, _formatMessage["default"])('Bank Type'),
176
242
  defaultValue: this.state.bankType,
177
- description: /*#__PURE__*/_react["default"].createElement(_uiA11yContent.ScreenReaderContent, null, (0, _formatMessage["default"])('Bank Type'))
243
+ description: /*#__PURE__*/_react["default"].createElement(_uiA11yContent.ScreenReaderContent, null, (0, _formatMessage["default"])('Bank Type')),
244
+ messages: this.state.radioValidationError,
245
+ isRequired: true
178
246
  }, /*#__PURE__*/_react["default"].createElement(_uiRadioInput.RadioInput, {
179
247
  value: "existing",
180
- label: (0, _formatMessage["default"])('Existing item bank')
248
+ label: (0, _formatMessage["default"])('Existing item bank'),
249
+ ref: this.radioInputRef
181
250
  }), /*#__PURE__*/_react["default"].createElement(_uiRadioInput.RadioInput, {
182
251
  value: "new",
183
252
  label: (0, _formatMessage["default"])('New item bank')
@@ -36,13 +36,15 @@ function _callSuper(_this, derived, args) {
36
36
  return (0, _possibleConstructorReturn2["default"])(_this, isNativeReflectConstruct() ? Reflect.construct(derived, args || [], (0, _getPrototypeOf2["default"])(_this).constructor) : derived.apply(_this, args));
37
37
  }
38
38
  var BankSelection = exports.BankSelection = /*#__PURE__*/function (_Component) {
39
- function BankSelection() {
39
+ function BankSelection(props) {
40
40
  var _this2;
41
41
  (0, _classCallCheck2["default"])(this, BankSelection);
42
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
43
- args[_key] = arguments[_key];
44
- }
45
- _this2 = _callSuper(this, BankSelection, [].concat(args));
42
+ _this2 = _callSuper(this, BankSelection, [props]);
43
+ (0, _defineProperty2["default"])(_this2, "setInputRef", function (ref) {
44
+ var _this2$props$inputRef, _this2$props;
45
+ _this2.inputRef = ref;
46
+ (_this2$props$inputRef = (_this2$props = _this2.props).inputRef) === null || _this2$props$inputRef === void 0 || _this2$props$inputRef.call(_this2$props, ref);
47
+ });
46
48
  (0, _defineProperty2["default"])(_this2, "searchBanks", function (search) {
47
49
  return _this2.props.simpleFetchBanks({
48
50
  search: search
@@ -65,18 +67,31 @@ var BankSelection = exports.BankSelection = /*#__PURE__*/function (_Component) {
65
67
  archived: bankOption.archived
66
68
  });
67
69
  });
70
+ _this2.inputRef = null;
68
71
  return _this2;
69
72
  }
70
73
  (0, _inherits2["default"])(BankSelection, _Component);
71
74
  return (0, _createClass2["default"])(BankSelection, [{
75
+ key: "focusSelectField",
76
+ value: function focusSelectField() {
77
+ if (this.inputRef) {
78
+ this.inputRef.focus();
79
+ }
80
+ }
81
+ }, {
72
82
  key: "getErrors",
73
83
  value: function getErrors() {
74
84
  var selectedBank = this.props.selectedBank;
75
85
  if (selectedBank && selectedBank.archived) {
86
+ this.focusSelectField();
76
87
  return (0, _instUIMessages.toErrors)([(0, _formatMessage["default"])('The item bank "{ bankTitle }" no longer exists. Please select a valid bank.', {
77
88
  bankTitle: selectedBank.title
78
89
  })]);
79
90
  }
91
+ if (this.props.externalError) {
92
+ this.focusSelectField();
93
+ return this.props.externalError;
94
+ }
80
95
  }
81
96
  }, {
82
97
  key: "selectedOption",
@@ -92,13 +107,15 @@ var BankSelection = exports.BankSelection = /*#__PURE__*/function (_Component) {
92
107
  key: "render",
93
108
  value: function render() {
94
109
  return /*#__PURE__*/_react["default"].createElement(_GenericAsyncSearch.GenericAsyncSearch, {
110
+ inputRef: this.setInputRef,
95
111
  onSelectionChange: this.onSelect,
96
112
  label: this.props.label || (0, _formatMessage["default"])('Select the destination bank'),
97
113
  placeholder: (0, _formatMessage["default"])('Search for a bank'),
98
114
  selectedOption: this.selectedOption(),
99
115
  getOptions: this.searchBanks,
100
116
  messages: this.getErrors(),
101
- selectAutomation: 'sdk-item-bank-modal'
117
+ selectAutomation: 'sdk-item-bank-modal',
118
+ isRequired: this.props.isRequired
102
119
  });
103
120
  }
104
121
  }]);
@@ -107,12 +124,18 @@ var BankSelection = exports.BankSelection = /*#__PURE__*/function (_Component) {
107
124
  label: _propTypes["default"].string,
108
125
  onBankSelection: _propTypes["default"].func,
109
126
  selectedBank: _reactImmutableProptypes["default"].record,
110
- simpleFetchBanks: _propTypes["default"].func
127
+ simpleFetchBanks: _propTypes["default"].func,
128
+ externalError: _reactImmutableProptypes["default"].record,
129
+ inputRef: _propTypes["default"].func,
130
+ isRequired: _propTypes["default"].bool
111
131
  });
112
132
  (0, _defineProperty2["default"])(BankSelection, "defaultProps", {
113
133
  label: null,
114
134
  onBankSelection: function onBankSelection() {},
115
135
  selectedBank: null,
116
- simpleFetchBanks: _banks.simpleFetchBanks
136
+ simpleFetchBanks: _banks.simpleFetchBanks,
137
+ externalError: null,
138
+ inputRef: function inputRef() {},
139
+ isRequired: false
117
140
  });
118
141
  var _default = exports["default"] = BankSelection;
@@ -39,7 +39,9 @@ var GenericAsyncSearch = exports.GenericAsyncSearch = /*#__PURE__*/function (_Co
39
39
  (0, _classCallCheck2["default"])(this, GenericAsyncSearch);
40
40
  _this2 = _callSuper(this, GenericAsyncSearch, arguments);
41
41
  (0, _defineProperty2["default"])(_this2, "setInputRef", function (inputRef) {
42
+ var _this2$props$inputRef, _this2$props;
42
43
  _this2.inputRef = inputRef;
44
+ (_this2$props$inputRef = (_this2$props = _this2.props).inputRef) === null || _this2$props$inputRef === void 0 || _this2$props$inputRef.call(_this2$props, inputRef);
43
45
  });
44
46
  (0, _defineProperty2["default"])(_this2, "state", {
45
47
  inputValue: _this2.props.selectedOption ? _this2.props.selectedOption.text : '',
@@ -170,7 +172,8 @@ var GenericAsyncSearch = exports.GenericAsyncSearch = /*#__PURE__*/function (_Co
170
172
  onRequestHighlightOption: this.handleHighlightOption,
171
173
  onRequestSelectOption: this.handleSelectOption,
172
174
  onKeyDown: this.handleKeyDown,
173
- messages: this.props.messages
175
+ messages: this.props.messages,
176
+ isRequired: this.props.isRequired
174
177
  }, this.renderOptions());
175
178
  }
176
179
  }]);
@@ -187,13 +190,17 @@ var GenericAsyncSearch = exports.GenericAsyncSearch = /*#__PURE__*/function (_Co
187
190
  }),
188
191
  messages: _propTypes["default"].array,
189
192
  selectAutomation: _propTypes["default"].string,
190
- getOptions: _propTypes["default"].func.isRequired
193
+ getOptions: _propTypes["default"].func.isRequired,
194
+ inputRef: _propTypes["default"].func,
195
+ isRequired: _propTypes["default"].bool
191
196
  });
192
197
  (0, _defineProperty2["default"])(GenericAsyncSearch, "defaultProps", {
193
198
  debounceDelay: 500,
194
199
  minChars: 3,
195
200
  label: null,
196
201
  placeholder: null,
197
- selectAutomation: null
202
+ selectAutomation: null,
203
+ inputRef: function inputRef() {},
204
+ isRequired: false
198
205
  });
199
206
  var _default = exports["default"] = GenericAsyncSearch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/quiz-core",
3
- "version": "21.0.1-rc.20+86057c52c",
3
+ "version": "21.0.1-rc.22+82a9a6da7",
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": "10.14.0",
47
47
  "@instructure/grading-utils": "^1.0.0",
48
48
  "@instructure/outcomes-ui": "3.2.3",
49
- "@instructure/quiz-common": "21.0.1-rc.20+86057c52c",
50
- "@instructure/quiz-i18n": "21.0.1-rc.20+86057c52c",
51
- "@instructure/quiz-interactions": "21.0.1-rc.20+86057c52c",
52
- "@instructure/quiz-number-input": "21.0.1-rc.20+86057c52c",
53
- "@instructure/quiz-rce": "21.0.1-rc.20+86057c52c",
49
+ "@instructure/quiz-common": "21.0.1-rc.22+82a9a6da7",
50
+ "@instructure/quiz-i18n": "21.0.1-rc.22+82a9a6da7",
51
+ "@instructure/quiz-interactions": "21.0.1-rc.22+82a9a6da7",
52
+ "@instructure/quiz-number-input": "21.0.1-rc.22+82a9a6da7",
53
+ "@instructure/quiz-rce": "21.0.1-rc.22+82a9a6da7",
54
54
  "@instructure/ui-a11y-content": "10.14.0",
55
55
  "@instructure/ui-alerts": "10.14.0",
56
56
  "@instructure/ui-avatar": "10.14.0",
@@ -109,7 +109,7 @@
109
109
  "file-saver": "~2.0.5",
110
110
  "humps": "^2.0.0",
111
111
  "immutable": "^3.8.1",
112
- "instructure-validations": "21.0.1-rc.20+86057c52c",
112
+ "instructure-validations": "21.0.1-rc.22+82a9a6da7",
113
113
  "ipaddr.js": "^1.5.4",
114
114
  "isomorphic-fetch": "^2.2.0",
115
115
  "isuuid": "^0.1.0",
@@ -158,7 +158,7 @@
158
158
  "jquery": "^2.2.3",
159
159
  "karma-junit-reporter": "^2.0.1",
160
160
  "most-subject": "^5.3.0",
161
- "quiz-presets": "21.0.1-rc.20+86057c52c",
161
+ "quiz-presets": "21.0.1-rc.22+82a9a6da7",
162
162
  "react": "^16.8.6",
163
163
  "react-addons-test-utils": "^15.6.2",
164
164
  "react-dom": "^16.8.6",
@@ -174,5 +174,5 @@
174
174
  "publishConfig": {
175
175
  "access": "public"
176
176
  },
177
- "gitHead": "86057c52ce038aa96623acb895c08e5e505554d6"
177
+ "gitHead": "82a9a6da7bf0bf5df739a6bbe5298bfa05e1f6fc"
178
178
  }