@instructure/quiz-core 22.0.0 → 22.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/es/banks/components/CopyMoveBankEntryModal/presenter.js +84 -15
  2. package/es/common/components/layout/sidebar/Stimulus/Collection/presenter.js +6 -3
  3. package/es/common/components/layout/sidebar/Stimulus/presenter.js +98 -38
  4. package/es/common/components/layout/sidebar/Stimulus/styles.js +2 -26
  5. package/es/common/components/layout/sidebar/Stimulus/theme.js +1 -10
  6. package/es/common/components/resources/BankSelection/presenter.js +31 -8
  7. package/es/common/components/resources/sessionItemResult/SessionItemResult/presenter.js +20 -20
  8. package/es/common/components/resources/stimulus/StimulusEdit/presenter.js +31 -29
  9. package/es/common/components/resources/stimulus/StimulusEditInfo/presenter.js +2 -1
  10. package/es/common/components/shared/GenericAsyncSearch/GenericAsyncSearch.js +10 -3
  11. package/es/common/records/QuizEntry.js +29 -17
  12. package/es/common/records/SessionItem.js +6 -0
  13. package/es/taking/api/taking.js +1 -1
  14. package/lib/banks/components/CopyMoveBankEntryModal/presenter.js +84 -15
  15. package/lib/common/components/layout/sidebar/Stimulus/Collection/presenter.js +6 -3
  16. package/lib/common/components/layout/sidebar/Stimulus/presenter.js +98 -38
  17. package/lib/common/components/layout/sidebar/Stimulus/styles.js +2 -26
  18. package/lib/common/components/layout/sidebar/Stimulus/theme.js +1 -10
  19. package/lib/common/components/resources/BankSelection/presenter.js +31 -8
  20. package/lib/common/components/resources/sessionItemResult/SessionItemResult/presenter.js +20 -20
  21. package/lib/common/components/resources/stimulus/StimulusEdit/presenter.js +31 -29
  22. package/lib/common/components/resources/stimulus/StimulusEditInfo/presenter.js +2 -1
  23. package/lib/common/components/shared/GenericAsyncSearch/GenericAsyncSearch.js +10 -3
  24. package/lib/common/records/QuizEntry.js +29 -17
  25. package/lib/common/records/SessionItem.js +6 -0
  26. package/lib/taking/api/taking.js +1 -1
  27. package/package.json +9 -9
@@ -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')
@@ -89,6 +89,7 @@ export var Collection = (_dec = withStyleOverrides(generateStyle, generateCompon
89
89
  }, _this3.props.renderSidebarItem(item, displayPosition, sidebarOpen));
90
90
  });
91
91
  var transitionType = isShowingItems ? 'slide-down' : 'slide-up';
92
+ var screenReaderText = this.props.isPassage ? t('Collapse passage questions') : t('Collapse stimulus questions');
92
93
  return jsx(Transition, {
93
94
  "in": isShowingItems || this.shouldDisplayAllItems(),
94
95
  type: transitionType
@@ -100,7 +101,7 @@ export var Collection = (_dec = withStyleOverrides(generateStyle, generateCompon
100
101
  withBackground: false,
101
102
  withBorder: false,
102
103
  renderIcon: IconArrowOpenUpLine,
103
- screenReaderLabel: t('Collapse stimulus questions')
104
+ screenReaderLabel: screenReaderText
104
105
  })), jsx("div", null, itemComponents)));
105
106
  }
106
107
  }, {
@@ -111,6 +112,7 @@ export var Collection = (_dec = withStyleOverrides(generateStyle, generateCompon
111
112
  itemCollection = _this$props2.itemCollection,
112
113
  isShowingItems = _this$props2.isShowingItems;
113
114
  var transitionType = !isShowingItems ? 'slide-up' : 'slide-down';
115
+ var screenReaderText = this.props.isPassage ? t('Expand passage questions') : t('Expand stimulus questions');
114
116
  return jsx(Transition, {
115
117
  "in": !isShowingItems,
116
118
  type: transitionType
@@ -124,7 +126,7 @@ export var Collection = (_dec = withStyleOverrides(generateStyle, generateCompon
124
126
  withBackground: false,
125
127
  withBorder: false,
126
128
  renderIcon: IconArrowOpenDownLine,
127
- screenReaderLabel: t('Expand stimulus questions')
129
+ screenReaderLabel: screenReaderText
128
130
  })));
129
131
  }
130
132
  }, {
@@ -155,7 +157,8 @@ export var Collection = (_dec = withStyleOverrides(generateStyle, generateCompon
155
157
  // set in connect
156
158
  setSidebarStimulusIsShowing: PropTypes.func.isRequired,
157
159
  styles: PropTypes.object,
158
- makeStyles: PropTypes.func
160
+ makeStyles: PropTypes.func,
161
+ isPassage: PropTypes.bool
159
162
  }), _defineProperty(_Collection, "defaultProps", {
160
163
  isShowingItems: false
161
164
  }), _Collection)) || _class);
@@ -35,6 +35,8 @@ import t from '@instructure/quiz-i18n/es/format-message';
35
35
  import { Flex, END_EDITING_TRIGGER_CLASSNAME, withStyleOverrides } from '@instructure/quiz-common';
36
36
  import { Tooltip } from '@instructure/ui-tooltip';
37
37
  import { ScreenReaderContent } from '@instructure/ui-a11y-content';
38
+ import { View } from '@instructure/ui-view';
39
+ import { Text } from '@instructure/ui-text';
38
40
  export var DISPLAY_AS_SUMMARY_LIMIT = 5;
39
41
  export var SidebarStimulus = (_dec = withStyleOverrides(generateStyle, generateComponentTheme), _dec(_class = (_SidebarStimulus = /*#__PURE__*/function (_Component) {
40
42
  function SidebarStimulus() {
@@ -64,18 +66,26 @@ export var SidebarStimulus = (_dec = withStyleOverrides(generateStyle, generateC
64
66
  value: function componentDidUpdate() {
65
67
  this.props.makeStyles();
66
68
  }
69
+ }, {
70
+ key: "stimulusIsPassage",
71
+ value: function stimulusIsPassage() {
72
+ var _this$props$stimulus;
73
+ return (_this$props$stimulus = this.props.stimulus) === null || _this$props$stimulus === void 0 ? void 0 : _this$props$stimulus.isPassage;
74
+ }
67
75
  }, {
68
76
  key: "renderCollection",
69
77
  value: function renderCollection() {
70
- if (this.props.isDragging) {
71
- return;
72
- }
78
+ var _this$props$stimulus2;
73
79
  var _this$props = this.props,
74
80
  displayPosition = _this$props.displayPosition,
75
81
  isOver = _this$props.isOver,
76
82
  isShowingItems = _this$props.isShowingItems,
77
83
  renderSidebarItem = _this$props.renderSidebarItem,
78
- sidebarOpen = _this$props.sidebarOpen;
84
+ sidebarOpen = _this$props.sidebarOpen,
85
+ isDragging = _this$props.isDragging;
86
+ if (this.stimulusIsPassage() || isDragging) {
87
+ return null;
88
+ }
79
89
  return jsx(Collection, {
80
90
  firstPosition: displayPosition,
81
91
  isOver: isOver,
@@ -83,22 +93,30 @@ export var SidebarStimulus = (_dec = withStyleOverrides(generateStyle, generateC
83
93
  itemCollection: this.props.childEntries,
84
94
  renderSidebarItem: renderSidebarItem,
85
95
  sidebarOpen: sidebarOpen,
86
- stimulusId: this.props.stimulus.id
96
+ stimulusId: this.props.stimulus.id,
97
+ isPassage: (_this$props$stimulus2 = this.props.stimulus) === null || _this$props$stimulus2 === void 0 ? void 0 : _this$props$stimulus2.isPassage
87
98
  });
88
99
  }
89
100
  }, {
90
101
  key: "renderButton",
91
102
  value: function renderButton() {
92
- var displayPosition = this.props.displayPosition;
93
- var textForNavigation = t('Navigate to stimulus at position {displayPosition}', {
103
+ var _this$props2 = this.props,
104
+ displayPosition = _this$props2.displayPosition,
105
+ sidebarOpen = _this$props2.sidebarOpen;
106
+ var itemName = this.stimulusIsPassage() ? 'passage' : 'stimulus';
107
+ var textForNavigation = t('Navigate to {itemName} at position {displayPosition}', {
108
+ itemName: itemName,
94
109
  displayPosition: displayPosition
95
110
  });
111
+ var content = sidebarOpen ? '' : textForNavigation;
112
+ var tip = jsx(Text, {
113
+ "aria-hidden": !sidebarOpen,
114
+ "aria-label": content
115
+ }, content);
96
116
  return jsx(Tooltip, {
97
- renderTip: this.props.sidebarOpen ? '' : jsx("span", {
98
- "aria-hidden": "true"
99
- }, textForNavigation),
117
+ renderTip: tip,
100
118
  placement: "start",
101
- on: this.props.sidebarOpen ? [] : ['hover', 'focus']
119
+ on: sidebarOpen ? [] : ['hover', 'focus']
102
120
  }, jsx(Link, {
103
121
  href: "#",
104
122
  margin: "small",
@@ -110,33 +128,82 @@ export var SidebarStimulus = (_dec = withStyleOverrides(generateStyle, generateC
110
128
  className: END_EDITING_TRIGGER_CLASSNAME
111
129
  }, jsx(ScreenReaderContent, null, textForNavigation)));
112
130
  }
131
+ }, {
132
+ key: "infoHeaderLabel",
133
+ value: function infoHeaderLabel() {
134
+ return this.stimulusIsPassage() ? t('Passage') : t('Stimulus');
135
+ }
136
+ }, {
137
+ key: "renderSummary",
138
+ value: function renderSummary() {
139
+ var _this$props3 = this.props,
140
+ displayPosition = _this$props3.displayPosition,
141
+ isDragging = _this$props3.isDragging,
142
+ isShowingItems = _this$props3.isShowingItems,
143
+ sidebarOpen = _this$props3.sidebarOpen,
144
+ stimulus = _this$props3.stimulus;
145
+ if (this.stimulusIsPassage()) {
146
+ return null;
147
+ }
148
+ return jsx(Summary, {
149
+ startPosition: displayPosition,
150
+ isDragging: isDragging,
151
+ isShowingItems: isShowingItems,
152
+ stimulusId: stimulus.id,
153
+ sidebarOpen: sidebarOpen,
154
+ numberOfItems: this.props.childEntries.size
155
+ });
156
+ }
157
+ }, {
158
+ key: "stimulusHoverCss",
159
+ value: function stimulusHoverCss() {
160
+ return {
161
+ // TODO: figure out how to get rid of the last of these styles.
162
+ ':hover': this.props.styles.onHover
163
+ };
164
+ }
113
165
  }, {
114
166
  key: "renderClosed",
115
167
  value: function renderClosed() {
116
- return jsx("div", {
117
- css: this.props.styles.sidebarItem
118
- }, jsx("div", {
119
- css: this.props.styles.sidebarItemClosedButton
168
+ return jsx(View, {
169
+ borderWidth: "0 0 small 0",
170
+ borderColor: "primary",
171
+ as: "div"
172
+ }, jsx(View, {
173
+ textAlign: "center",
174
+ padding: "xx-small 0",
175
+ borderWidth: "none large none none",
176
+ borderColor: "transparent",
177
+ css: this.stimulusHoverCss(),
178
+ as: "div"
120
179
  }, this.renderButton()), this.renderCollection());
121
180
  }
122
181
  }, {
123
182
  key: "renderOpen",
124
183
  value: function renderOpen() {
125
- var _this$props2 = this.props,
126
- children = _this$props2.children,
127
- displayPosition = _this$props2.displayPosition,
128
- isDragging = _this$props2.isDragging,
129
- isShowingItems = _this$props2.isShowingItems,
130
- sidebarOpen = _this$props2.sidebarOpen,
131
- stimulus = _this$props2.stimulus;
132
- return jsx("div", {
133
- css: this.props.styles.sidebarItem
134
- }, jsx("div", {
135
- css: this.props.styles.stimulusHeader
136
- }, jsx("div", {
137
- css: this.props.styles.infoHeader
138
- }, t('Stimulus')), jsx("div", {
139
- css: this.props.styles.stimulusBody
184
+ var _this$props4 = this.props,
185
+ stimulus = _this$props4.stimulus,
186
+ children = _this$props4.children;
187
+ return jsx(View, {
188
+ borderWidth: "0 0 small 0",
189
+ borderColor: "primary",
190
+ as: "div"
191
+ }, jsx(View, {
192
+ padding: "small 0",
193
+ borderWidth: "none large none none",
194
+ borderColor: "transparent",
195
+ css: this.stimulusHoverCss(),
196
+ as: "div"
197
+ }, jsx(View, {
198
+ margin: "auto auto x-small x-small",
199
+ padding: "auto auto auto x-small",
200
+ as: "div"
201
+ }, jsx(Text, {
202
+ size: "x-small",
203
+ color: "secondary"
204
+ }, this.infoHeaderLabel())), jsx(View, {
205
+ margin: "auto auto auto small",
206
+ as: "div"
140
207
  }, jsx(Flex, {
141
208
  justifyItems: "space-between"
142
209
  }, jsx(Flex.Item, null, this.renderButton()), jsx(Flex.Item, {
@@ -146,14 +213,7 @@ export var SidebarStimulus = (_dec = withStyleOverrides(generateStyle, generateC
146
213
  tabIndex: "-1"
147
214
  }, jsx(Title, {
148
215
  title: stimulus.title
149
- })), jsx(Flex.Item, null, children)), jsx(Summary, {
150
- startPosition: displayPosition,
151
- isDragging: isDragging,
152
- isShowingItems: isShowingItems,
153
- sidebarOpen: sidebarOpen,
154
- stimulusId: stimulus.id,
155
- numberOfItems: this.props.childEntries.size
156
- }))), this.renderCollection());
216
+ })), jsx(Flex.Item, null, children)), this.renderSummary())), this.renderCollection());
157
217
  }
158
218
  }, {
159
219
  key: "render",
@@ -1,31 +1,7 @@
1
1
  var generateStyle = function generateStyle(componentTheme) {
2
2
  return {
3
- sidebarItem: {
4
- borderBottom: "".concat(componentTheme.sidebarItemBorderWidth, " solid ").concat(componentTheme.sidebarItemBorderColor)
5
- },
6
- sidebarItemClosedButton: {
7
- borderRight: "".concat(componentTheme.hoverBorderWidth, " solid ").concat(componentTheme.borderColor),
8
- padding: componentTheme.sidebarClosedButtonPadding,
9
- textAlign: 'center',
10
- '&:hover': {
11
- borderRight: "".concat(componentTheme.hoverBorderWidth, " solid ").concat(componentTheme.hoverBorderColor)
12
- }
13
- },
14
- stimulusHeader: {
15
- padding: "".concat(componentTheme.sidebarHeaderPadding, " 0"),
16
- borderRight: "".concat(componentTheme.hoverBorderWidth, " solid ").concat(componentTheme.borderColor),
17
- '&:hover:': {
18
- borderRight: "".concat(componentTheme.hoverBorderWidth, " solid ").concat(componentTheme.hoverBorderColor)
19
- }
20
- },
21
- stimulusBody: {
22
- marginLeft: '5%'
23
- },
24
- infoHeader: {
25
- fontSize: componentTheme.sidebarIsOpenInfoHeaderFontSize,
26
- color: componentTheme.sidebarIsOpenInfoHeaderColor,
27
- marginBottom: componentTheme.sidebarIsOpenInfoHeaderMargin,
28
- paddingLeft: componentTheme.sidebarIsOpenInfoHeaderPadding
3
+ onHover: {
4
+ borderRight: "".concat(componentTheme.hoverBorderWidth, " solid ").concat(componentTheme.hoverBorderColor)
29
5
  }
30
6
  };
31
7
  };
@@ -5,16 +5,7 @@ var generateComponentTheme = function generateComponentTheme(_ref) {
5
5
  typography = _ref.typography;
6
6
  return {
7
7
  borderColor: colors.contrasts.white1010,
8
- hoverBorderColor: colors.contrasts.blue4570,
9
- hoverBorderWidth: borders.widthLarge,
10
- sidebarClosedButtonPadding: "".concat(spacing.xxSmall, " 0"),
11
- sidebarHeaderPadding: spacing.small,
12
- sidebarItemBorderWidth: borders.widthSmall,
13
- sidebarItemBorderColor: colors.contrasts.grey1214,
14
- sidebarIsOpenInfoHeaderFontSize: typography.fontSizeXSmall,
15
- sidebarIsOpenInfoHeaderPadding: spacing.xSmall,
16
- sidebarIsOpenInfoHeaderMargin: spacing.xSmall,
17
- sidebarIsOpenInfoHeaderColor: colors.contrasts.grey4570
8
+ hoverBorderColor: colors.contrasts.blue4570
18
9
  };
19
10
  };
20
11
  export default generateComponentTheme;
@@ -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;
@@ -91,9 +91,9 @@ export var SessionItemResult = (_dec = withStyleOverrides(generateStyle, generat
91
91
  return typeof this.pointsPossible === 'number';
92
92
  }
93
93
  }, {
94
- key: "position",
95
- value: function position() {
96
- return this.props.sessionItem.position;
94
+ key: "questionNumber",
95
+ value: function questionNumber() {
96
+ return this.props.sessionItem.questionNumber;
97
97
  }
98
98
  }, {
99
99
  key: "unscorable",
@@ -179,38 +179,38 @@ export var SessionItemResult = (_dec = withStyleOverrides(generateStyle, generat
179
179
  value: function renderHeader() {
180
180
  return jsx("div", {
181
181
  css: this.props.styles.sessionItemResultHeader
182
- }, this.renderResultPosition(), !this.props.restrictQuantitativeData && (this.hasRegradeInfo() ? this.renderRegradePoints() : this.renderPoints()));
182
+ }, this.renderResultQuestionNumber(), !this.props.restrictQuantitativeData && (this.hasRegradeInfo() ? this.renderRegradePoints() : this.renderPoints()));
183
183
  }
184
184
  }, {
185
- key: "renderResultPosition",
186
- value: function renderResultPosition() {
187
- var position = this.position();
188
- var positionText;
185
+ key: "renderResultQuestionNumber",
186
+ value: function renderResultQuestionNumber() {
187
+ var questionNumber = this.questionNumber();
188
+ var questionNumberText;
189
189
  if (this.regraded() && this.unscorable()) {
190
- positionText = t('Results for question {position, number}. There was a problem grading this question. This question has been regraded.', {
191
- position: position
190
+ questionNumberText = t('Results for question {questionNumber, number}. There was a problem grading this question. This question has been regraded.', {
191
+ questionNumber: questionNumber
192
192
  });
193
193
  } else if (this.regraded()) {
194
- positionText = t('Results for question {position, number}. This question has been regraded.', {
195
- position: position
194
+ questionNumberText = t('Results for question {questionNumber, number}. This question has been regraded.', {
195
+ questionNumber: questionNumber
196
196
  });
197
197
  } else if (this.unscorable() && this.props.editGraderFeedback) {
198
- positionText = t('Results for question {position, number}. There was a problem grading this question.', {
199
- position: position
198
+ questionNumberText = t('Results for question {questionNumber, number}. There was a problem grading this question.', {
199
+ questionNumber: questionNumber
200
200
  });
201
201
  } else if (this.unscorable()) {
202
- positionText = t('Results for question {position, number}. There was a problem grading this question. Please inform your instructor.', {
203
- position: position
202
+ questionNumberText = t('Results for question {questionNumber, number}. There was a problem grading this question. Please inform your instructor.', {
203
+ questionNumber: questionNumber
204
204
  });
205
205
  } else {
206
- positionText = t('Results for question {position, number}.', {
207
- position: position
206
+ questionNumberText = t('Results for question {questionNumber, number}.', {
207
+ questionNumber: questionNumber
208
208
  });
209
209
  }
210
210
  return jsx(PositionBox, {
211
- position: position,
211
+ position: questionNumber,
212
212
  headingLevel: "h3",
213
- headingText: positionText
213
+ headingText: questionNumberText
214
214
  });
215
215
  }
216
216
  }, {