@instructure/quiz-core 20.8.0 → 20.8.1-rc.1

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.
@@ -11,7 +11,7 @@ import { clear, newActiveBankEntry, newActiveBank } from "../../common/actions/u
11
11
  import t from '@instructure/quiz-i18n/es/format-message';
12
12
  import { handleError } from "../../common/api/helpers.js";
13
13
  import { removeFromPolling } from "./copyingBanksPoller.js";
14
- import { BANKS_BANK_PAGINATION, BANKS_BANK_ENTRY_PAGINATION, DELETE_BANK_CALL, UPDATE_BANK_CALL, CAN_EDIT, READ_ONLY, REMOVED_ACCESS, SHARED_WITH_USER, SHARED_WITH_COURSE } from '@instructure/quiz-common';
14
+ import { BANKS_BANK_PAGINATION, BANKS_BANK_ENTRY_PAGINATION, DELETE_BANK_CALL, UPDATE_BANK_CALL, CAN_EDIT, READ_ONLY, REMOVED_ACCESS, SHARED_WITH_USER, SHARED_WITH_COURSE, SHARED_WITH_ACCOUNT } from '@instructure/quiz-common';
15
15
  import { noop } from 'lodash';
16
16
  import { NIL } from 'uuid';
17
17
  var banksApiEndpoint = '/api/banks';
@@ -226,10 +226,10 @@ export var shareBank = function shareBank(_shareBank) {
226
226
  };
227
227
  dispatch(handleShareBankResponse(sharedBank));
228
228
  });
229
- } else if (_shareBank.entityType === SHARED_WITH_COURSE) {
229
+ } else {
230
230
  var sharedBank = {
231
231
  id: sharedBankInfo.id,
232
- entityType: SHARED_WITH_COURSE,
232
+ entityType: _shareBank.entityType,
233
233
  entityId: _shareBank.entityId,
234
234
  title: _shareBank.title,
235
235
  permission: sharedBankInfo.permission,
@@ -272,10 +272,8 @@ export var getSharedBank = function getSharedBank(bankId, entityType, entityId)
272
272
  });
273
273
  };
274
274
  };
275
- export var getSharedBanks = function getSharedBanks(bank, getUserInfo, getCourseInfo) {
275
+ export var getSharedBanks = function getSharedBanks(bank, getUserInfo, getCourseInfo, getAccountInfo) {
276
276
  var url = "".concat(banksApiEndpoint, "/").concat(bank.id, "/shared_banks");
277
- var userSharedBanks = [];
278
- var courseSharedBanks = [];
279
277
  return function (dispatch, getState) {
280
278
  var fetcher = new Fetcher({
281
279
  onError: handleError(dispatch, t('Failed to fetch shared banks.'))
@@ -290,8 +288,10 @@ export var getSharedBanks = function getSharedBanks(bank, getUserInfo, getCourse
290
288
  permission: CAN_EDIT,
291
289
  bank_id: bank.id
292
290
  });
293
- }
291
+ } // USERS
292
+
294
293
 
294
+ var userSharedBanks = [];
295
295
  var userUuids = sharedBanksInfo.filter(function (sb) {
296
296
  return sb.entity_type === SHARED_WITH_USER;
297
297
  }).map(function (sb) {
@@ -316,7 +316,9 @@ export var getSharedBanks = function getSharedBanks(bank, getUserInfo, getCourse
316
316
  }
317
317
  });
318
318
  dispatch(handleShareBanksResponse(userSharedBanks));
319
- });
319
+ }); // COURSES
320
+
321
+ var courseSharedBanks = [];
320
322
  var courseUuids = sharedBanksInfo.filter(function (sb) {
321
323
  return sb.entity_type === SHARED_WITH_COURSE;
322
324
  }).map(function (sb) {
@@ -340,6 +342,32 @@ export var getSharedBanks = function getSharedBanks(bank, getUserInfo, getCourse
340
342
  }
341
343
  });
342
344
  dispatch(handleShareBanksResponse(courseSharedBanks));
345
+ }); // ACCOUNTS
346
+
347
+ var accountSharedBanks = [];
348
+ var accountUuids = sharedBanksInfo.filter(function (sb) {
349
+ return sb.entity_type === SHARED_WITH_ACCOUNT;
350
+ }).map(function (sb) {
351
+ return sb.entity_id;
352
+ });
353
+ getAccountInfo(accountUuids).then(function (accountsInfo) {
354
+ accountsInfo.forEach(function (accountInfo) {
355
+ var sharedBankInfo = sharedBanksInfo.find(function (sb) {
356
+ return sb.entity_type === SHARED_WITH_ACCOUNT && sb.entity_id === accountInfo.uuid;
357
+ });
358
+
359
+ if (sharedBankInfo) {
360
+ accountSharedBanks.push({
361
+ id: sharedBankInfo.id,
362
+ entityType: sharedBankInfo.entity_type,
363
+ entityId: sharedBankInfo.entity_id,
364
+ title: accountInfo.name,
365
+ permission: sharedBankInfo.permission,
366
+ bankId: sharedBankInfo.bank_id
367
+ });
368
+ }
369
+ });
370
+ dispatch(handleShareBanksResponse(accountSharedBanks));
343
371
  });
344
372
  });
345
373
  };
@@ -173,8 +173,10 @@ export var Banks = (_dec = withStyle(generateStyle, generateComponentTheme), _de
173
173
  focusCreateBankButton: _this.focusCreateBankButton,
174
174
  getCourseInfo: _this.props.getCourseInfo,
175
175
  getUserInfo: _this.props.getUserInfo,
176
+ getSubaccountInfo: _this.props.getSubaccountInfo,
176
177
  getShareableCourses: _this.props.getShareableCourses,
177
178
  getShareableUsers: _this.props.getShareableUsers,
179
+ getShareableSubaccounts: _this.props.getShareableSubaccounts,
178
180
  isCompact: _this.props.isCompact,
179
181
  itemBankSearchTableEnabled: _this.props.itemBankSearchTableEnabled,
180
182
  minChars: _this.props.minChars,
@@ -402,6 +404,7 @@ export var Banks = (_dec = withStyle(generateStyle, generateComponentTheme), _de
402
404
  createBank: PropTypes.func.isRequired,
403
405
  currentUser: PropTypes.shape({
404
406
  bank_admin: PropTypes.bool,
407
+ can_share_banks_with_subaccounts: PropTypes.bool,
405
408
  email: PropTypes.string,
406
409
  enrollment_names: PropTypes.arrayOf(PropTypes.string),
407
410
  full_name: PropTypes.string,
@@ -419,7 +422,11 @@ export var Banks = (_dec = withStyle(generateStyle, generateComponentTheme), _de
419
422
  getShareableCourses: PropTypes.func,
420
423
  // from consumer
421
424
  getShareableUsers: PropTypes.func,
422
- // from consumer,
425
+ // from consumer
426
+ getShareableSubaccounts: PropTypes.func,
427
+ // from consumer
428
+ getSubaccountInfo: PropTypes.func,
429
+ // from consumer
423
430
  getCourseAssignments: PropTypes.func,
424
431
  // from consumer
425
432
  isCompact: PropTypes.bool,
@@ -456,6 +463,8 @@ export var Banks = (_dec = withStyle(generateStyle, generateComponentTheme), _de
456
463
  getShareableCourses: null,
457
464
  getShareableUsers: null,
458
465
  getCourseAssignments: null,
466
+ getShareableSubaccounts: null,
467
+ getSubaccountInfo: null,
459
468
  minChars: void 0,
460
469
  isCompact: false,
461
470
  navigateToBuild: null,
@@ -399,6 +399,7 @@ export var BanksList = (_dec = withStyle(generateStyle, generateComponentTheme),
399
399
  focusCreateBankButton: this.props.focusCreateBankButton,
400
400
  getCourseInfo: this.props.getCourseInfo,
401
401
  getUserInfo: this.props.getUserInfo,
402
+ getSubaccountInfo: this.props.getSubaccountInfo,
402
403
  isOpen: this.state.sharingModalOpen,
403
404
  minChars: this.props.minChars,
404
405
  modalTrigger: this.sharingButtons[this.state.sharingModalBank.id],
@@ -406,6 +407,7 @@ export var BanksList = (_dec = withStyle(generateStyle, generateComponentTheme),
406
407
  onShare: this.props.onShare,
407
408
  getShareableCourses: this.props.getShareableCourses,
408
409
  getShareableUsers: this.props.getShareableUsers,
410
+ getShareableSubaccounts: this.props.getShareableSubaccounts,
409
411
  updateSharedCount: this.updateSharedCount
410
412
  });
411
413
  }
@@ -510,6 +512,7 @@ export var BanksList = (_dec = withStyle(generateStyle, generateComponentTheme),
510
512
  createBankCloneJob: PropTypes.func.isRequired,
511
513
  currentUser: PropTypes.shape({
512
514
  bank_admin: PropTypes.bool,
515
+ can_share_banks_with_subaccounts: PropTypes.bool,
513
516
  email: PropTypes.string,
514
517
  enrollment_names: PropTypes.arrayOf(PropTypes.string),
515
518
  full_name: PropTypes.string,
@@ -523,6 +526,7 @@ export var BanksList = (_dec = withStyle(generateStyle, generateComponentTheme),
523
526
  getUserInfo: PropTypes.func,
524
527
  getShareableCourses: PropTypes.func,
525
528
  getShareableUsers: PropTypes.func,
529
+ getShareableSubaccounts: PropTypes.func,
526
530
  minChars: PropTypes.number,
527
531
  navigateToBank: PropTypes.func.isRequired,
528
532
  onShare: PropTypes.func,
@@ -538,6 +542,7 @@ export var BanksList = (_dec = withStyle(generateStyle, generateComponentTheme),
538
542
  getUserInfo: null,
539
543
  getShareableCourses: null,
540
544
  getShareableUsers: null,
545
+ getShareableSubaccounts: null,
541
546
  minChars: void 0,
542
547
  locale: null,
543
548
  timezone: null,
@@ -22,7 +22,7 @@ import { ContextualIconButton } from "../ContextualIconButton/index.js";
22
22
  import RootAccountSharing from "../RootAccountSharing.js";
23
23
  import { SimpleSelect } from '@instructure/ui-simple-select';
24
24
  import generateStyle from "./styles.js";
25
- import { CAN_EDIT, READ_ONLY, REMOVED_ACCESS, SHARED_WITH_USER, SHARED_WITH_COURSE } from '@instructure/quiz-common';
25
+ import { CAN_EDIT, READ_ONLY, REMOVED_ACCESS, SHARED_WITH_USER, SHARED_WITH_COURSE, SHARED_WITH_ACCOUNT } from '@instructure/quiz-common';
26
26
  import t from '@instructure/quiz-i18n/es/format-message';
27
27
 
28
28
  var _ref4 = jsx(IconCoursesLine, {
@@ -148,11 +148,10 @@ export var ShareList = (_dec = withStyle(generateStyle, null), _dec(_class = (_t
148
148
  }, {
149
149
  key: "render",
150
150
  value: function render() {
151
- var _this$props$currentUs;
152
-
153
151
  var _this$props = this.props,
154
152
  shares = _this$props.shares,
155
- subAccountBankSharingEnabled = _this$props.subAccountBankSharingEnabled;
153
+ subAccountBankSharingEnabled = _this$props.subAccountBankSharingEnabled,
154
+ currentUser = _this$props.currentUser;
156
155
  var newEntityIds = this.props.newEntities.map(function (e) {
157
156
  return e.get('id');
158
157
  });
@@ -165,6 +164,9 @@ export var ShareList = (_dec = withStyle(generateStyle, null), _dec(_class = (_t
165
164
  var existingCourses = existingShares.filter(function (s) {
166
165
  return s.get('entityType') === SHARED_WITH_COURSE;
167
166
  });
167
+ var existingAccounts = existingShares.filter(function (s) {
168
+ return s.get('entityType') === SHARED_WITH_ACCOUNT;
169
+ });
168
170
  return jsx("div", {
169
171
  className: "fs-mask"
170
172
  }, !subAccountBankSharingEnabled && jsx(Text, {
@@ -199,16 +201,24 @@ export var ShareList = (_dec = withStyle(generateStyle, null), _dec(_class = (_t
199
201
  lineHeight: "double"
200
202
  }, t('Currently shared with')), jsx(Grid, {
201
203
  vAlign: "middle"
202
- }, existingCourses.map(this.renderEntity))), subAccountBankSharingEnabled && jsx(Tabs.Panel, {
203
- renderTitle: t('Accounts'),
204
+ }, existingCourses.map(this.renderEntity))), subAccountBankSharingEnabled && ((currentUser === null || currentUser === void 0 ? void 0 : currentUser.bank_admin) || (currentUser === null || currentUser === void 0 ? void 0 : currentUser.can_share_banks_with_subaccounts)) && jsx(Tabs.Panel, {
205
+ renderTitle: t('Accounts ({ accountsCount })', {
206
+ accountsCount: existingAccounts.size
207
+ }),
204
208
  isSelected: this.state.selectedTabIndex === 2,
205
209
  padding: "large small small small"
206
- }, ((_this$props$currentUs = this.props.currentUser) === null || _this$props$currentUs === void 0 ? void 0 : _this$props$currentUs.bank_admin) && jsx(RootAccountSharing, {
210
+ }, (currentUser === null || currentUser === void 0 ? void 0 : currentUser.bank_admin) && jsx(RootAccountSharing, {
207
211
  accountName: this.props.accountName,
208
212
  onShareChange: this.props.onToggleAccountShare,
209
213
  onShareTypeChange: this.props.onAccountPermissionChange,
210
214
  accountPermission: this.props.accountPermission
211
- })))));
215
+ }), (currentUser === null || currentUser === void 0 ? void 0 : currentUser.can_share_banks_with_subaccounts) && this.props.renderSearchSection(SHARED_WITH_ACCOUNT), jsx(Text, {
216
+ as: "div",
217
+ weight: "bold",
218
+ lineHeight: "double"
219
+ }, t('Currently shared with')), jsx(Grid, {
220
+ vAlign: "middle"
221
+ }, existingAccounts.map(this.renderEntity))))));
212
222
  }
213
223
  }]);
214
224
 
@@ -217,7 +227,8 @@ export var ShareList = (_dec = withStyle(generateStyle, null), _dec(_class = (_t
217
227
  }(Component), _class2.propTypes = {
218
228
  canEdit: PropTypes.bool.isRequired,
219
229
  currentUser: PropTypes.shape({
220
- bank_admin: PropTypes.bool
230
+ bank_admin: PropTypes.bool,
231
+ can_share_banks_with_subaccounts: PropTypes.bool
221
232
  }),
222
233
  improvedBankSharingEnabled: PropTypes.bool.isRequired,
223
234
  newEntities: ImmutablePropTypes.list,
@@ -12,7 +12,7 @@ import t from '@instructure/quiz-i18n/es/format-message';
12
12
  import { Select } from '@instructure/ui-select';
13
13
  import { Spinner } from '@instructure/ui-spinner';
14
14
  import TagWrapper from "../../../common/components/shared/TagWrapper/index.js";
15
- import { SHARED_WITH_USER, SHARED_WITH_COURSE, SELECT_EMPTY_OPTION } from '@instructure/quiz-common';
15
+ import { SHARED_WITH_USER, SHARED_WITH_COURSE, SHARED_WITH_ACCOUNT, SELECT_EMPTY_OPTION } from '@instructure/quiz-common';
16
16
  export var AsyncSearch = /*#__PURE__*/function (_Component) {
17
17
  _inherits(AsyncSearch, _Component);
18
18
 
@@ -34,6 +34,7 @@ export var AsyncSearch = /*#__PURE__*/function (_Component) {
34
34
  isShowingOptions: false,
35
35
  isLoading: false,
36
36
  highlightedOptionId: null,
37
+ shareableSubaccounts: [],
37
38
  shareableCourses: [],
38
39
  shareableUsers: []
39
40
  };
@@ -45,7 +46,7 @@ export var AsyncSearch = /*#__PURE__*/function (_Component) {
45
46
  };
46
47
 
47
48
  _this.handleHideOptions = function () {
48
- var allOptions = [].concat(_toConsumableArray(_this.filterOptions(_this.state.shareableCourses)), _toConsumableArray(_this.filterOptions(_this.state.shareableUsers))); // an option matching user input exists
49
+ var allOptions = [].concat(_toConsumableArray(_this.filterOptions(_this.state.shareableSubaccounts)), _toConsumableArray(_this.filterOptions(_this.state.shareableCourses)), _toConsumableArray(_this.filterOptions(_this.state.shareableUsers))); // an option matching user input exists
49
50
 
50
51
  if (allOptions.length === 1) {
51
52
  var onlyOption = allOptions[0]; // automatically select the matching option
@@ -166,7 +167,8 @@ export var AsyncSearch = /*#__PURE__*/function (_Component) {
166
167
 
167
168
  _this.search = debounce(_this.props.debounceDelay, function (value) {
168
169
  var shouldSearchPeople = !_this.props.searchType || _this.props.searchType === SHARED_WITH_USER;
169
- var shouldSearchCourses = !_this.props.searchType || _this.props.searchType === SHARED_WITH_COURSE; // TODO add the promise cancellation for avoiding having disordered requests
170
+ var shouldSearchCourses = !_this.props.searchType || _this.props.searchType === SHARED_WITH_COURSE;
171
+ var shouldSearchSubaccounts = _this.props.searchType === SHARED_WITH_ACCOUNT; // TODO add the promise cancellation for avoiding having disordered requests
170
172
 
171
173
  if (shouldSearchPeople) {
172
174
  _this.props.getShareableUsers(value).then(function (shareableUsers) {
@@ -191,6 +193,18 @@ export var AsyncSearch = /*#__PURE__*/function (_Component) {
191
193
  });
192
194
  });
193
195
  }
196
+
197
+ if (shouldSearchSubaccounts) {
198
+ _this.props.getShareableSubaccounts(value).then(function (shareableSubaccounts) {
199
+ var filteredAccounts = _this.filterOptions(shareableSubaccounts);
200
+
201
+ _this.setState({
202
+ shareableSubaccounts: shareableSubaccounts,
203
+ highlightedOptionId: filteredAccounts.length ? filteredAccounts[0].uuid : _this.state.highlightedOptionId,
204
+ isLoading: false
205
+ });
206
+ });
207
+ }
194
208
  });
195
209
  return _this;
196
210
  }
@@ -218,6 +232,16 @@ export var AsyncSearch = /*#__PURE__*/function (_Component) {
218
232
  });
219
233
  }
220
234
 
235
+ var account = find({
236
+ uuid: id
237
+ }, this.state.shareableSubaccounts);
238
+
239
+ if (account) {
240
+ return _objectSpread(_objectSpread({}, account), {}, {
241
+ entityType: SHARED_WITH_ACCOUNT
242
+ });
243
+ }
244
+
221
245
  return find({
222
246
  uuid: id
223
247
  }, this.props.selectedOption);
@@ -232,7 +256,7 @@ export var AsyncSearch = /*#__PURE__*/function (_Component) {
232
256
  key: option.uuid,
233
257
  id: option.uuid,
234
258
  index: index,
235
- text: option.fullName || option.title,
259
+ text: option.fullName || option.title || option.name,
236
260
  onClick: _this2.dismissTag
237
261
  });
238
262
  });
@@ -284,6 +308,24 @@ export var AsyncSearch = /*#__PURE__*/function (_Component) {
284
308
  }, course.title);
285
309
  }));
286
310
  }
311
+ }, {
312
+ key: "renderSubaccountsOptions",
313
+ value: function renderSubaccountsOptions(subaccounts) {
314
+ var _this6 = this;
315
+
316
+ return /*#__PURE__*/React.createElement(Select.Group, {
317
+ key: SHARED_WITH_ACCOUNT,
318
+ renderLabel: t('Accounts')
319
+ }, subaccounts.map(function (subaccount) {
320
+ return /*#__PURE__*/React.createElement(Select.Option, {
321
+ // eslint-disable-next-line react/jsx-no-literals
322
+ "data-automation": "sdk-item-bank-option-subaccount-".concat(subaccount.uuid),
323
+ id: subaccount.uuid,
324
+ key: subaccount.uuid,
325
+ isHighlighted: subaccount.uuid === _this6.state.highlightedOptionId
326
+ }, subaccount.name);
327
+ }));
328
+ }
287
329
  }, {
288
330
  key: "emptyOption",
289
331
  value: function emptyOption() {
@@ -313,6 +355,12 @@ export var AsyncSearch = /*#__PURE__*/function (_Component) {
313
355
  groups.push(this.renderCoursesOptions(courses));
314
356
  }
315
357
 
358
+ var subaccounts = this.filterOptions(this.state.shareableSubaccounts);
359
+
360
+ if (subaccounts.length) {
361
+ groups.push(this.renderSubaccountsOptions(subaccounts));
362
+ }
363
+
316
364
  return groups.length ? groups : /*#__PURE__*/React.createElement(Select.Option, {
317
365
  id: SELECT_EMPTY_OPTION,
318
366
  key: SELECT_EMPTY_OPTION
@@ -321,17 +369,27 @@ export var AsyncSearch = /*#__PURE__*/function (_Component) {
321
369
  size: "x-small"
322
370
  }) : this.emptyOption());
323
371
  }
372
+ }, {
373
+ key: "placeholder",
374
+ value: function placeholder() {
375
+ if (this.props.searchType === SHARED_WITH_ACCOUNT) {
376
+ return t('Enter subaccount name');
377
+ } else if (this.props.searchType === SHARED_WITH_COURSE) {
378
+ return t('Enter course name or course id');
379
+ } else {
380
+ return t('Enter name or login id');
381
+ }
382
+ }
324
383
  }, {
325
384
  key: "render",
326
385
  value: function render() {
327
386
  var _this$state = this.state,
328
387
  inputValue = _this$state.inputValue,
329
388
  isShowingOptions = _this$state.isShowingOptions;
330
- var placeholder = this.props.searchType === SHARED_WITH_COURSE ? t('Enter course name or course id') : t('Enter name or login id');
331
389
  return /*#__PURE__*/React.createElement(Select, {
332
390
  "data-automation": "sdk-item-bank-share-input",
333
391
  renderLabel: t('Share With'),
334
- placeholder: placeholder,
392
+ placeholder: this.placeholder(),
335
393
  inputValue: inputValue,
336
394
  isShowingOptions: isShowingOptions,
337
395
  inputRef: this.setInputRef,
@@ -357,6 +415,7 @@ AsyncSearch.propTypes = {
357
415
  onSelectionChange: PropTypes.func.isRequired,
358
416
  getShareableCourses: PropTypes.func.isRequired,
359
417
  getShareableUsers: PropTypes.func.isRequired,
418
+ getShareableSubaccounts: PropTypes.func.isRequired,
360
419
  searchType: PropTypes.string,
361
420
  selectedOption: PropTypes.arrayOf(PropTypes.shape({
362
421
  avatar: PropTypes.string,
@@ -81,7 +81,7 @@ export var SharingModalPresenter = (_dec = withStyle(generateStyle, generateComp
81
81
  var size = _this.props.sharedBanks.size;
82
82
 
83
83
  if (size >= 0 && size !== _this.props.bank.sharedCount || size === 0) {
84
- _this.props.getSharedBanks(_this.props.bank, _this.props.getUserInfo, _this.props.getCourseInfo);
84
+ _this.props.getSharedBanks(_this.props.bank, _this.props.getUserInfo, _this.props.getCourseInfo, _this.props.getSubaccountInfo);
85
85
  } else {
86
86
  // eslint-disable-next-line react/no-did-mount-set-state
87
87
  _this.setState({
@@ -253,7 +253,7 @@ export var SharingModalPresenter = (_dec = withStyle(generateStyle, generateComp
253
253
  id: entity.uuid,
254
254
  entityType: entity.entityType,
255
255
  entityId: entity.uuid,
256
- title: entity.fullName || entity.title,
256
+ title: entity.fullName || entity.title || entity.name,
257
257
  avatar: entity.avatar,
258
258
  email: entity.email,
259
259
  permission: _this.state.searchPermission
@@ -377,6 +377,7 @@ export var SharingModalPresenter = (_dec = withStyle(generateStyle, generateComp
377
377
  }, jsx(Grid.Row, null, jsx(Grid.Col, null, jsx(AsyncSearch, {
378
378
  getShareableCourses: _this.props.getShareableCourses,
379
379
  getShareableUsers: _this.props.getShareableUsers,
380
+ getShareableSubaccounts: _this.props.getShareableSubaccounts,
380
381
  improvedBankSharingEnabled: _this.props.improvedBankSharingEnabled,
381
382
  minChars: _this.props.minChars,
382
383
  onSelectionChange: _this.handleSearchSelectionChange,
@@ -565,6 +566,7 @@ export var SharingModalPresenter = (_dec = withStyle(generateStyle, generateComp
565
566
  bank: ImmutablePropTypes.record.isRequired,
566
567
  currentUser: PropTypes.shape({
567
568
  bank_admin: PropTypes.bool,
569
+ can_share_banks_with_subaccounts: PropTypes.bool,
568
570
  email: PropTypes.string,
569
571
  enrollment_names: PropTypes.arrayOf(PropTypes.string),
570
572
  full_name: PropTypes.string,
@@ -578,6 +580,8 @@ export var SharingModalPresenter = (_dec = withStyle(generateStyle, generateComp
578
580
  getShareableUsers: PropTypes.func.isRequired,
579
581
  getSharedBanks: PropTypes.func.isRequired,
580
582
  getUserInfo: PropTypes.func.isRequired,
583
+ getShareableSubaccounts: PropTypes.func.isRequired,
584
+ getSubaccountInfo: PropTypes.func.isRequired,
581
585
  improvedBankSharingEnabled: PropTypes.bool,
582
586
  isOpen: PropTypes.bool,
583
587
  minChars: PropTypes.number,
@@ -108,8 +108,10 @@ export var BanksTray = /*#__PURE__*/function (_Component) {
108
108
  getCourseInfo: this.props.getCourseInfo,
109
109
  getCourseAssignments: this.props.getCourseAssignments,
110
110
  getUserInfo: this.props.getUserInfo,
111
+ getSubaccountInfo: this.props.getSubaccountInfo,
111
112
  getShareableCourses: this.props.getShareableCourses,
112
113
  getShareableUsers: this.props.getShareableUsers,
114
+ getShareableSubaccounts: this.props.getShareableSubaccounts,
113
115
  minChars: this.props.minChars,
114
116
  onShare: this.props.onShare,
115
117
  scope: this.props.itemBanksScope
@@ -171,6 +173,7 @@ BanksTray.propTypes = {
171
173
  clear: PropTypes.func.isRequired,
172
174
  currentUser: PropTypes.shape({
173
175
  bank_admin: PropTypes.bool,
176
+ can_share_banks_with_subaccounts: PropTypes.bool,
174
177
  email: PropTypes.string,
175
178
  enrollment_names: PropTypes.arrayOf(PropTypes.string),
176
179
  full_name: PropTypes.string,
@@ -182,6 +185,8 @@ BanksTray.propTypes = {
182
185
  getUserInfo: PropTypes.func,
183
186
  getShareableCourses: PropTypes.func,
184
187
  getShareableUsers: PropTypes.func,
188
+ getShareableSubaccounts: PropTypes.func,
189
+ getSubaccountInfo: PropTypes.func,
185
190
  minChars: PropTypes.number,
186
191
  newActiveBank: PropTypes.func.isRequired,
187
192
  newActiveBankEntry: PropTypes.func.isRequired,
@@ -204,6 +209,8 @@ BanksTray.defaultProps = {
204
209
  currentUser: null,
205
210
  getShareableCourses: null,
206
211
  getShareableUsers: null,
212
+ getShareableSubaccounts: null,
213
+ getSubaccountInfo: null,
207
214
  minChars: void 0,
208
215
  getCourseInfo: null,
209
216
  getCourseAssignments: null,
@@ -1,3 +1,4 @@
1
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
1
2
  import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
2
3
  import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
3
4
  import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
@@ -10,11 +11,14 @@ var _dec, _class, _class2, _temp;
10
11
  import React, { Component } from 'react';
11
12
  import PropTypes from 'prop-types';
12
13
  import ImmutablePropTypes from 'react-immutable-proptypes';
14
+ import classNames from 'classnames';
13
15
  import { Text } from '@instructure/ui-text';
14
16
  import { Link } from '@instructure/ui-link';
15
17
  import { Flex } from '@instructure/ui-flex';
16
18
  import { ScreenReaderContent } from '@instructure/ui-a11y-content';
17
19
  import { Table } from '@instructure/ui-table';
20
+ import { IconButton } from '@instructure/ui-buttons';
21
+ import { IconInfoLine, IconConfigureLine } from '@instructure/ui-icons';
18
22
  import { themeable } from '@instructure/ui-themeable';
19
23
  import t from '@instructure/quiz-i18n/es/format-message';
20
24
  import ModerateTableRow from "../ModerateTableRow/index.js";
@@ -23,24 +27,27 @@ import OutstandingQuizzesModal from "../OutstandingQuizzesModal/index.js";
23
27
  import ModerateTray from "../../sidebar/ModerateTray/index.js";
24
28
  import Spinner from "../../../../common/components/shared/spinner/Spinner.js";
25
29
  var styles = {
26
- componentId: 'esFtE',
30
+ componentId: 'eDRzW',
27
31
  template: function template(theme) {
28
- return "\n\n.esFtE_bwKH{display:block;margin:".concat(theme.emptyTextMargin || 'inherit', " 0 0 0}\n\n.esFtE_xNcP{background-color:").concat(theme.pageBackgroundColor || 'inherit', ";flex:1;overflow:auto}");
32
+ return "\n\n.eDRzW_bwKH{display:block;margin:".concat(theme.emptyTextMargin || 'inherit', " 0 0 0}\n\n.eDRzW_xNcP{background-color:").concat(theme.pageBackgroundColor || 'inherit', ";flex:1;overflow:auto}\n\n.eDRzW_eeML{display:inline-block;transition:transform 0.3s}\n\n.eDRzW_XujX{transform:scaleX(-1)}");
29
33
  },
30
- 'emptyText': 'esFtE_bwKH',
31
- 'page': 'esFtE_xNcP'
34
+ 'emptyText': 'eDRzW_bwKH',
35
+ 'page': 'eDRzW_xNcP',
36
+ 'scoreToggleWrapper': 'eDRzW_eeML',
37
+ 'mirror': 'eDRzW_XujX'
32
38
  };
33
39
  import theme from "./theme.js";
34
40
  import ResetQuiz from "../../sidebar/ResetQuiz/index.js";
35
41
  import { OUTSTANDING_QUIZZES_MODAL } from '@instructure/quiz-common';
36
- import { IconInfoLine } from '@instructure/ui-icons';
37
42
  import { chunk } from 'lodash';
38
43
 
39
44
  var _ref2 = /*#__PURE__*/React.createElement(Flex.Item, null, /*#__PURE__*/React.createElement(IconInfoLine, null));
40
45
 
41
- var _ref4 = /*#__PURE__*/React.createElement(Spinner, null);
46
+ var _ref4 = /*#__PURE__*/React.createElement(IconConfigureLine, null);
42
47
 
43
- var _ref5 = /*#__PURE__*/React.createElement(ResetQuiz, null);
48
+ var _ref5 = /*#__PURE__*/React.createElement(Spinner, null);
49
+
50
+ var _ref6 = /*#__PURE__*/React.createElement(ResetQuiz, null);
44
51
 
45
52
  export var ModerateTable = (_dec = themeable(theme, styles), _dec(_class = (_temp = _class2 = /*#__PURE__*/function (_Component) {
46
53
  _inherits(ModerateTable, _Component);
@@ -58,6 +65,7 @@ export var ModerateTable = (_dec = themeable(theme, styles), _dec(_class = (_tem
58
65
 
59
66
  _this = _super.call.apply(_super, [this].concat(args));
60
67
  _this.state = {
68
+ displayScoreAsPercentage: true,
61
69
  // To support voiceover when the table changes
62
70
  moderatePanelIterations: 0,
63
71
  selectedStudent: null,
@@ -150,6 +158,18 @@ export var ModerateTable = (_dec = themeable(theme, styles), _dec(_class = (_tem
150
158
  _this.pollAutogradingStatus(submittedQuizSessions);
151
159
  };
152
160
 
161
+ _this.handleScoreToggle = function () {
162
+ _this.setState(function (prevState) {
163
+ return {
164
+ displayScoreAsPercentage: !prevState.displayScoreAsPercentage
165
+ };
166
+ });
167
+ };
168
+
169
+ _this.scoreToggleScreenreaderMessage = function () {
170
+ return _this.state.displayScoreAsPercentage ? t('Toggle scores to raw points') : t('Toggle scores to percentages');
171
+ };
172
+
153
173
  _this.openModalOnClick = function () {
154
174
  _this.props.openModal(OUTSTANDING_QUIZZES_MODAL);
155
175
  };
@@ -231,7 +251,8 @@ export var ModerateTable = (_dec = themeable(theme, styles), _dec(_class = (_tem
231
251
  onModerateLogClick: onModerateLogClick,
232
252
  rowData: rowData,
233
253
  shouldRenderModerateButton: shouldRenderModerateButton,
234
- focusTarget: _this2.state.selectedStudent
254
+ focusTarget: _this2.state.selectedStudent,
255
+ displayScoreAsPercentage: _this2.state.displayScoreAsPercentage
235
256
  });
236
257
  });
237
258
  }
@@ -291,6 +312,20 @@ export var ModerateTable = (_dec = themeable(theme, styles), _dec(_class = (_tem
291
312
  afterSubmit: this.props.afterManualSubmit
292
313
  })));
293
314
  }
315
+ }, {
316
+ key: "renderScoreToggle",
317
+ value: function renderScoreToggle() {
318
+ return /*#__PURE__*/React.createElement("div", {
319
+ className: classNames(styles.scoreToggleWrapper, _defineProperty({}, styles.mirror, !this.state.displayScoreAsPercentage))
320
+ }, /*#__PURE__*/React.createElement(IconButton, {
321
+ size: "small",
322
+ margin: "0 x-small",
323
+ withBackground: false,
324
+ withBorder: false,
325
+ screenReaderLabel: this.scoreToggleScreenreaderMessage(),
326
+ onClick: this.handleScoreToggle
327
+ }, _ref4));
328
+ }
294
329
  }, {
295
330
  key: "renderTable",
296
331
  value: function renderTable() {
@@ -305,7 +340,7 @@ export var ModerateTable = (_dec = themeable(theme, styles), _dec(_class = (_tem
305
340
  id: "moderation-table-attempts"
306
341
  }, t('Attempts')), !this.props.anonymousGrading && /*#__PURE__*/React.createElement(Table.ColHeader, {
307
342
  id: "moderation-table-score"
308
- }, t('Score')), !this.props.anonymousGrading && /*#__PURE__*/React.createElement(Table.ColHeader, {
343
+ }, t('Score'), this.renderScoreToggle()), !this.props.anonymousGrading && /*#__PURE__*/React.createElement(Table.ColHeader, {
309
344
  id: "moderation-table-time"
310
345
  }, t('Time')), !this.props.anonymousGrading && /*#__PURE__*/React.createElement(Table.ColHeader, {
311
346
  id: "moderation-table-log"
@@ -325,7 +360,7 @@ export var ModerateTable = (_dec = themeable(theme, styles), _dec(_class = (_tem
325
360
  isFetching = _this$props5.isFetching,
326
361
  tableData = _this$props5.tableData,
327
362
  emptyMessage = _this$props5.emptyMessage;
328
- if (isFetching || this.state.isWaiting) return _ref4;
363
+ if (isFetching || this.state.isWaiting) return _ref5;
329
364
  if (tableData.length) return this.renderTable();
330
365
  return /*#__PURE__*/React.createElement("span", {
331
366
  className: styles.emptyText
@@ -340,7 +375,7 @@ export var ModerateTable = (_dec = themeable(theme, styles), _dec(_class = (_tem
340
375
  className: styles.page
341
376
  }, /*#__PURE__*/React.createElement(ModerateTray, {
342
377
  onClose: this.onCloseTray
343
- }, !this.props.anonymousGrading && _ref5, this.props.children), this.renderContent());
378
+ }, !this.props.anonymousGrading && _ref6, this.props.children), this.renderContent());
344
379
  }
345
380
  }]);
346
381
 
@@ -143,8 +143,12 @@ export var ModerateTableRow = (_dec = themeable(theme, styles), _dec(_class = (_
143
143
  var message = t('No Score');
144
144
 
145
145
  if (result.get('score') != null) {
146
- var percentage = result.get('score') / result.get('pointsPossible');
147
- message = _this3.formatPercentMax2FractionDigits(percentage);
146
+ if (_this3.props.displayScoreAsPercentage) {
147
+ var percentage = result.get('score') / result.get('pointsPossible');
148
+ message = _this3.formatPercentMax2FractionDigits(percentage);
149
+ } else {
150
+ message = "".concat(t.number(result.get('score')), "/").concat(t.number(result.get('pointsPossible')));
151
+ }
148
152
  }
149
153
 
150
154
  if (result.get('pointsPossible') === 0) {
@@ -360,6 +364,7 @@ export var ModerateTableRow = (_dec = themeable(theme, styles), _dec(_class = (_
360
364
  return ModerateTableRow;
361
365
  }(withI18nSupport(Component)), _class2.propTypes = {
362
366
  anonymousGrading: PropTypes.bool.isRequired,
367
+ displayScoreAsPercentage: PropTypes.bool,
363
368
  onModerateButtonClick: PropTypes.func.isRequired,
364
369
  onModerateLogClick: PropTypes.func.isRequired,
365
370
  onAccommodationsClick: PropTypes.func,
@@ -380,6 +385,7 @@ export var ModerateTableRow = (_dec = themeable(theme, styles), _dec(_class = (_
380
385
  shouldRenderModerateButton: PropTypes.bool,
381
386
  focusTarget: PropTypes.string
382
387
  }, _class2.defaultProps = {
388
+ displayScoreAsPercentage: true,
383
389
  shouldRenderModerateButton: true,
384
390
  focusTarget: null,
385
391
  onAccommodationsClick: null