@inveniosoftware/react-invenio-app-ils 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -440,6 +440,12 @@ const RECORDS_CONFIG = {
440
440
  iconClass: 'dolly'
441
441
  }
442
442
  },
443
+ deliveryMethodSelfCheckout: {
444
+ 'SELF-CHECKOUT': {
445
+ text: 'SELF-CHECKOUT',
446
+ iconClass: 'shopping basket'
447
+ }
448
+ },
443
449
  extensionsMaxCount: 3,
444
450
  loanWillExpireDays: 7,
445
451
  loanActiveStates: ['ITEM_AT_DESK', 'ITEM_ON_LOAN', 'ITEM_IN_TRANSIT_FOR_PICKUP', 'ITEM_IN_TRANSIT_TO_HOUSE'],
@@ -2450,7 +2456,7 @@ const serializer$9 = {
2450
2456
  };
2451
2457
 
2452
2458
  const documentRequestURL = '/document-requests/';
2453
- const apiPaths$2 = {
2459
+ const apiPaths$3 = {
2454
2460
  accept: `${documentRequestURL}:docReqPid/accept`,
2455
2461
  item: `${documentRequestURL}:docReqPid`,
2456
2462
  list: documentRequestURL,
@@ -2459,12 +2465,12 @@ const apiPaths$2 = {
2459
2465
  provider: `${documentRequestURL}:docReqPid/provider`
2460
2466
  };
2461
2467
  const create$8 = async data => {
2462
- const response = await http.post(apiPaths$2.list, data);
2468
+ const response = await http.post(apiPaths$3.list, data);
2463
2469
  response.data = serializer$9.fromJSON(response.data);
2464
2470
  return response;
2465
2471
  };
2466
2472
  const update$8 = async (docRequestPid, data) => {
2467
- const path = reactRouterDom.generatePath(apiPaths$2.item, {
2473
+ const path = reactRouterDom.generatePath(apiPaths$3.item, {
2468
2474
  docReqPid: docRequestPid
2469
2475
  });
2470
2476
  const response = await http.put(path, data);
@@ -2472,7 +2478,7 @@ const update$8 = async (docRequestPid, data) => {
2472
2478
  return response;
2473
2479
  };
2474
2480
  const get$c = async docRequestPid => {
2475
- const path = reactRouterDom.generatePath(apiPaths$2.item, {
2481
+ const path = reactRouterDom.generatePath(apiPaths$3.item, {
2476
2482
  docReqPid: docRequestPid
2477
2483
  });
2478
2484
  const response = await http.get(path);
@@ -2480,7 +2486,7 @@ const get$c = async docRequestPid => {
2480
2486
  return response;
2481
2487
  };
2482
2488
  const del$8 = async docRequestPid => {
2483
- const path = reactRouterDom.generatePath(apiPaths$2.item, {
2489
+ const path = reactRouterDom.generatePath(apiPaths$3.item, {
2484
2490
  docReqPid: docRequestPid
2485
2491
  });
2486
2492
  const response = await http.delete(path);
@@ -2492,19 +2498,19 @@ const performAction = async (urlPath, data) => {
2492
2498
  return response;
2493
2499
  };
2494
2500
  const accept = async docRequestPid => {
2495
- const urlPath = reactRouterDom.generatePath(apiPaths$2.accept, {
2501
+ const urlPath = reactRouterDom.generatePath(apiPaths$3.accept, {
2496
2502
  docReqPid: docRequestPid
2497
2503
  });
2498
2504
  return performAction(urlPath);
2499
2505
  };
2500
2506
  const addDocument$1 = async (docReqPid, data) => {
2501
- const url = reactRouterDom.generatePath(apiPaths$2.document, {
2507
+ const url = reactRouterDom.generatePath(apiPaths$3.document, {
2502
2508
  docReqPid: docReqPid
2503
2509
  });
2504
2510
  return await http.post(url, data);
2505
2511
  };
2506
2512
  const removeDocument$1 = async (docReqPid, data) => {
2507
- const url = reactRouterDom.generatePath(apiPaths$2.document, {
2513
+ const url = reactRouterDom.generatePath(apiPaths$3.document, {
2508
2514
  docReqPid: docReqPid
2509
2515
  });
2510
2516
  // https://github.com/axios/axios/issues/897#issuecomment-343715381
@@ -2513,19 +2519,19 @@ const removeDocument$1 = async (docReqPid, data) => {
2513
2519
  });
2514
2520
  };
2515
2521
  const addProvider$1 = async (docReqPid, data) => {
2516
- const url = reactRouterDom.generatePath(apiPaths$2.provider, {
2522
+ const url = reactRouterDom.generatePath(apiPaths$3.provider, {
2517
2523
  docReqPid: docReqPid
2518
2524
  });
2519
2525
  return await http.post(url, data);
2520
2526
  };
2521
2527
  const removeProvider$1 = async docReqPid => {
2522
- const url = reactRouterDom.generatePath(apiPaths$2.provider, {
2528
+ const url = reactRouterDom.generatePath(apiPaths$3.provider, {
2523
2529
  docReqPid: docReqPid
2524
2530
  });
2525
2531
  return await http.delete(url);
2526
2532
  };
2527
2533
  const decline = async (docRequestPid, data) => {
2528
- const urlPath = reactRouterDom.generatePath(apiPaths$2.decline, {
2534
+ const urlPath = reactRouterDom.generatePath(apiPaths$3.decline, {
2529
2535
  docReqPid: docRequestPid
2530
2536
  });
2531
2537
  return performAction(urlPath, data);
@@ -3445,8 +3451,9 @@ const serializer$4 = {
3445
3451
  fromJSON: serializeResponse$3
3446
3452
  };
3447
3453
 
3448
- const apiPaths$1 = {
3454
+ const apiPaths$2 = {
3449
3455
  checkout: '/circulation/loans/checkout',
3456
+ selfCheckout: '/circulation/loans/self-checkout',
3450
3457
  notificationOverdue: '/circulation/loans/:loanPid/notification-overdue',
3451
3458
  item: '/circulation/loans/:loanPid',
3452
3459
  list: '/circulation/loans/',
@@ -3456,7 +3463,7 @@ const apiPaths$1 = {
3456
3463
  bulkExtend: '/circulation/bulk-extend'
3457
3464
  };
3458
3465
  const get$7 = async loanPid => {
3459
- const path = reactRouterDom.generatePath(apiPaths$1.item, {
3466
+ const path = reactRouterDom.generatePath(apiPaths$2.item, {
3460
3467
  loanPid: loanPid
3461
3468
  });
3462
3469
  const response = await http.get(path);
@@ -3509,7 +3516,7 @@ const doRequest = async function (documentPid, patronPid) {
3509
3516
  method: deliveryMethod
3510
3517
  };
3511
3518
  }
3512
- const response = await http.post(apiPaths$1.request, payload);
3519
+ const response = await http.post(apiPaths$2.request, payload);
3513
3520
  response.data = serializer$4.fromJSON(response.data);
3514
3521
  return response;
3515
3522
  };
@@ -3536,12 +3543,30 @@ const doCheckout = async function (documentPid, itemPid, patronPid) {
3536
3543
  if (force) {
3537
3544
  payload.force = true;
3538
3545
  }
3539
- const response = await http.post(apiPaths$1.checkout, payload);
3546
+ const response = await http.post(apiPaths$2.checkout, payload);
3547
+ response.data = serializer$4.fromJSON(response.data);
3548
+ return response;
3549
+ };
3550
+ const doSelfCheckoutSearchItem = async barcode => {
3551
+ const response = await http.get(`${apiPaths$2.selfCheckout}?barcode=${barcode}`);
3552
+ response.data = serializer$4.fromJSON(response.data);
3553
+ return response;
3554
+ };
3555
+ const doSelfCheckout = async (documentPid, itemPid, patronPid) => {
3556
+ const currentUser = sessionManager.user;
3557
+ const payload = {
3558
+ document_pid: documentPid,
3559
+ item_pid: itemPid,
3560
+ patron_pid: patronPid,
3561
+ transaction_location_pid: `${currentUser.locationPid}`,
3562
+ transaction_user_pid: `${currentUser.id}`
3563
+ };
3564
+ const response = await http.post(apiPaths$2.selfCheckout, payload);
3540
3565
  response.data = serializer$4.fromJSON(response.data);
3541
3566
  return response;
3542
3567
  };
3543
3568
  const assignItemToLoan$1 = async (itemPid, loanPid) => {
3544
- const path = reactRouterDom.generatePath(apiPaths$1.replaceItem, {
3569
+ const path = reactRouterDom.generatePath(apiPaths$2.replaceItem, {
3545
3570
  loanPid: loanPid
3546
3571
  });
3547
3572
  const payload = {
@@ -3555,7 +3580,7 @@ const bulkExtendLoans = async patronPid => {
3555
3580
  const payload = {
3556
3581
  patron_pid: patronPid
3557
3582
  };
3558
- const response = await http.post(apiPaths$1.bulkExtend, payload);
3583
+ const response = await http.post(apiPaths$2.bulkExtend, payload);
3559
3584
  return response;
3560
3585
  };
3561
3586
  class QueryBuilder$4 {
@@ -3669,19 +3694,19 @@ const queryBuilder$4 = () => {
3669
3694
  return new QueryBuilder$4();
3670
3695
  };
3671
3696
  const list$7 = async query => {
3672
- const response = await http.get(`${apiPaths$1.list}?q=${query}`);
3697
+ const response = await http.get(`${apiPaths$2.list}?q=${query}`);
3673
3698
  response.data.total = getSearchTotal(response.data.hits);
3674
3699
  response.data.hits = response.data.hits.hits.map(hit => serializer$4.fromJSON(hit));
3675
3700
  return response;
3676
3701
  };
3677
3702
  const sendOverdueLoansNotificationReminder$1 = async payload => {
3678
- const path = reactRouterDom.generatePath(apiPaths$1.notificationOverdue, {
3703
+ const path = reactRouterDom.generatePath(apiPaths$2.notificationOverdue, {
3679
3704
  loanPid: payload.loanPid
3680
3705
  });
3681
3706
  return await http.post(path, payload);
3682
3707
  };
3683
3708
  const count$2 = async query => {
3684
- const response = await http.get(`${apiPaths$1.list}?q=${query}`);
3709
+ const response = await http.get(`${apiPaths$2.list}?q=${query}`);
3685
3710
  response.data = getSearchTotal(response.data.hits);
3686
3711
  return response;
3687
3712
  };
@@ -3705,13 +3730,13 @@ const updateDates = async function (loanPid) {
3705
3730
  if (requestExpireDate) {
3706
3731
  payload.request_expire_date = requestExpireDate;
3707
3732
  }
3708
- const path = reactRouterDom.generatePath(apiPaths$1.updateDates, {
3733
+ const path = reactRouterDom.generatePath(apiPaths$2.updateDates, {
3709
3734
  loanPid: loanPid
3710
3735
  });
3711
3736
  return await http.post(path, payload);
3712
3737
  };
3713
3738
  const loanApi = {
3714
- searchBaseURL: `${apiConfig.baseURL}${apiPaths$1.list}`,
3739
+ searchBaseURL: `${apiConfig.baseURL}${apiPaths$2.list}`,
3715
3740
  assignItemToLoan: assignItemToLoan$1,
3716
3741
  query: queryBuilder$4,
3717
3742
  list: list$7,
@@ -3720,6 +3745,8 @@ const loanApi = {
3720
3745
  doAction: doAction,
3721
3746
  doRequest: doRequest,
3722
3747
  doCheckout: doCheckout,
3748
+ doSelfCheckout: doSelfCheckout,
3749
+ doSelfCheckoutSearchItem: doSelfCheckoutSearchItem,
3723
3750
  sendOverdueLoansNotificationReminder: sendOverdueLoansNotificationReminder$1,
3724
3751
  serializer: serializer$4,
3725
3752
  updateDates: updateDates,
@@ -3758,12 +3785,25 @@ function serializeLocationResponse(hit) {
3758
3785
  }
3759
3786
  return result;
3760
3787
  }
3788
+ function serializeLocationClosurePeriodsResponse(hit) {
3789
+ let result = [];
3790
+ if (!_isEmpty__default["default"](hit)) {
3791
+ result = hit.closure_periods.map(period => ({
3792
+ start: new luxon.DateTime.fromISO(period.start),
3793
+ end: new luxon.DateTime.fromISO(period.end)
3794
+ }));
3795
+ }
3796
+ return result;
3797
+ }
3761
3798
  const internalLocationSerializer = {
3762
3799
  fromJSON: serializeInternalLocationResponse
3763
3800
  };
3764
3801
  const locationSerializer = {
3765
3802
  fromJSON: serializeLocationResponse
3766
3803
  };
3804
+ const locationClosurePeriodsSerializer = {
3805
+ fromJSON: serializeLocationClosurePeriodsResponse
3806
+ };
3767
3807
 
3768
3808
  const internalLocationURL = '/internal-locations/';
3769
3809
  const get$6 = async internalLocationPid => {
@@ -3804,6 +3844,9 @@ const internalLocationApi = {
3804
3844
  };
3805
3845
 
3806
3846
  const locationURL = '/locations/';
3847
+ const apiPaths$1 = {
3848
+ closure_periods: `/closure_periods/`
3849
+ };
3807
3850
  const get$5 = async locationPid => {
3808
3851
  const response = await http.get(`${locationURL}${locationPid}`);
3809
3852
  response.data = locationSerializer.fromJSON(response.data);
@@ -3830,13 +3873,19 @@ const list$5 = async function () {
3830
3873
  response.data.hits = response.data.hits.hits.map(hit => locationSerializer.fromJSON(hit));
3831
3874
  return response;
3832
3875
  };
3876
+ const getClosurePeriods = async (locationPid, year) => {
3877
+ const response = await http.get(`${locationURL}${locationPid}${apiPaths$1.closure_periods}${year}`);
3878
+ response.data = locationClosurePeriodsSerializer.fromJSON(response.data);
3879
+ return response;
3880
+ };
3833
3881
  const locationApi = {
3834
3882
  list: list$5,
3835
3883
  get: get$5,
3836
3884
  delete: del$2,
3837
3885
  create: create$2,
3838
3886
  update: update$2,
3839
- url: locationURL
3887
+ url: locationURL,
3888
+ getClosurePeriods: getClosurePeriods
3840
3889
  };
3841
3890
 
3842
3891
  function serializeResponse$2(hit) {
@@ -12163,6 +12212,7 @@ class LoanListEntry extends React.Component {
12163
12212
  const patronPid = loan.metadata.patron_pid;
12164
12213
  const delivery = _get__default["default"](loan.metadata.delivery, 'method');
12165
12214
  const deliveryMethod = delivery && loan.metadata.state === 'PENDING' ? invenioConfig.CIRCULATION.deliveryMethods[delivery] : '';
12215
+ const isSelfCheckout = delivery === 'SELF-CHECKOUT';
12166
12216
  return /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Item, null, /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Item.Content, null, loan.metadata.is_overdue && /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Label, {
12167
12217
  color: "red"
12168
12218
  }, "Overdue"), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Item.Header, {
@@ -12197,8 +12247,10 @@ class LoanListEntry extends React.Component {
12197
12247
  }, loan.metadata.extension_count || '0'), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.List.Content, null, /*#__PURE__*/React__default["default"].createElement("label", null, " Extensions"))))), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Grid.Column, {
12198
12248
  width: 2,
12199
12249
  textAlign: "center"
12200
- }, deliveryMethod && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, delivery, ' ', deliveryMethod.iconClass && /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Icon, {
12250
+ }, deliveryMethod ? /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, delivery, ' ', deliveryMethod.iconClass && /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Icon, {
12201
12251
  className: deliveryMethod.iconClass
12252
+ })) : isSelfCheckout && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, delivery, ' ', /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Icon, {
12253
+ className: invenioConfig.CIRCULATION.deliveryMethodSelfCheckout[delivery].iconClass
12202
12254
  }))), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Grid.Column, {
12203
12255
  computer: 3,
12204
12256
  largeScreen: 3
@@ -13135,102 +13187,70 @@ var DatePicker$1 = Overridable__default["default"].component('DatePicker', DateP
13135
13187
  class LocationDatePicker extends React.Component {
13136
13188
  constructor(props) {
13137
13189
  super(props);
13138
- this.fetchLocation = async locationPid => {
13139
- this.setState({
13140
- isLoading: true
13141
- });
13142
- try {
13143
- const response = await locationApi.get(locationPid);
13144
- this.setState({
13145
- data: response.data,
13146
- isLoading: false,
13147
- error: {}
13148
- });
13149
- } catch (error) {
13190
+ this.fetchData = () => {
13191
+ this.fetchLocationClosurePeriods();
13192
+ };
13193
+ this.fetchLocationClosurePeriods = async () => {
13194
+ const {
13195
+ locationPid
13196
+ } = this.props;
13197
+ if (!locationPid) {
13150
13198
  this.setState({
13151
13199
  isLoading: false,
13152
- error: error
13200
+ disabledDates: [],
13201
+ error: {
13202
+ message: 'Location PID is missing.'
13203
+ }
13153
13204
  });
13205
+ return;
13154
13206
  }
13155
- };
13156
- this.disableAllDates = (minDate, maxDate, disabled) => {
13157
- let date = luxon.DateTime.fromISO(minDate);
13158
- const dateMax = luxon.DateTime.fromISO(maxDate);
13159
- while (date <= dateMax) {
13160
- const dateISO = date.toISODate();
13161
- disabled.push(dateISO);
13162
- date = date.plus({
13163
- days: 1
13207
+ this.setState({
13208
+ isLoading: true,
13209
+ error: null
13210
+ });
13211
+ const currentYear = luxon.DateTime.now().year;
13212
+ const yearsToFetch = [currentYear - 1, currentYear, currentYear + 1];
13213
+ try {
13214
+ const promises = yearsToFetch.map(year => {
13215
+ const cancellable = withCancel(locationApi.getClosurePeriods(locationPid, year));
13216
+ this.cancellableFetches.push(cancellable);
13217
+ return cancellable.promise;
13164
13218
  });
13165
- }
13166
- };
13167
- this.disableClosures = (maxDate, minDate, data, disabled) => {
13168
- const weekdays = data.metadata.opening_weekdays,
13169
- exceptions = data.metadata.opening_exceptions;
13170
- let date = luxon.DateTime.fromISO(minDate);
13171
- const dateMax = luxon.DateTime.fromISO(maxDate);
13172
- while (date <= dateMax) {
13173
- const dateISO = date.toISODate();
13174
- let isOpen = weekdays[date.weekday - 1].is_open;
13175
- exceptions.forEach(exception => {
13176
- if (exception.start_date <= dateISO && dateISO <= exception.end_date) {
13177
- isOpen = exception.is_open;
13219
+ const responses = await Promise.all(promises);
13220
+ const disabledDateRanges = responses.flatMap(response => response.data);
13221
+ const disabledDates = disabledDateRanges.flatMap(dateRange => {
13222
+ const dates = [];
13223
+ let currentDate = luxon.DateTime.fromISO(dateRange.start);
13224
+ const endDate = luxon.DateTime.fromISO(dateRange.end);
13225
+ while (currentDate <= endDate) {
13226
+ dates.push(currentDate.toISODate());
13227
+ currentDate = currentDate.plus({
13228
+ days: 1
13229
+ });
13178
13230
  }
13231
+ return dates;
13179
13232
  });
13180
- if (!isOpen) {
13181
- disabled.push(dateISO);
13182
- }
13183
- date = date.plus({
13184
- days: 1
13233
+ this.setState({
13234
+ disabledDates: disabledDates,
13235
+ isLoading: false
13185
13236
  });
13186
- }
13187
-
13188
- // Disable recent X days including current date as set in the config
13189
- date = luxon.DateTime.fromISO(minDate);
13190
- let workingDaysToOffset = invenioConfig.CIRCULATION.requestStartOffset;
13191
- let i = 0;
13192
- while (workingDaysToOffset > 0) {
13193
- const dateISO = date.toISODate();
13194
- if (dateISO === disabled[i]) {
13195
- i++;
13196
- } else {
13197
- disabled.push(dateISO);
13198
- workingDaysToOffset--;
13199
- }
13200
- date = date.plus({
13201
- days: 1
13237
+ } catch (fetchError) {
13238
+ console.error('LocationDatePicker: Failed to fetch closure periods.', fetchError);
13239
+ this.setState({
13240
+ isLoading: false,
13241
+ error: fetchError
13202
13242
  });
13203
13243
  }
13204
13244
  };
13205
- this.listDisabled = () => {
13206
- const {
13207
- minDate,
13208
- maxDate
13209
- } = this.props;
13210
- const {
13211
- isLoading,
13212
- error,
13213
- data
13214
- } = this.state;
13215
- const disabled = [];
13216
- if (isLoading) {
13217
- this.disableAllDates(minDate, maxDate, disabled);
13218
- } else if (!error.response && !_isEmpty__default["default"](data)) {
13219
- this.disableClosures(maxDate, minDate, data, disabled);
13220
- }
13221
- return disabled;
13222
- };
13223
- this.fetchData = () => {
13224
- const {
13225
- locationPid
13226
- } = this.props;
13227
- this.fetchLocation(locationPid);
13228
- };
13229
13245
  this.state = {
13230
- data: {},
13246
+ disabledDates: [],
13231
13247
  isLoading: false,
13232
- error: {}
13248
+ error: null
13233
13249
  };
13250
+ this.cancellableFetches = [];
13251
+ }
13252
+ componentWillUnmount() {
13253
+ this.cancellableFetches.forEach(cancellable => cancellable.cancel());
13234
13254
  }
13235
13255
  render() {
13236
13256
  const {
@@ -13242,12 +13262,18 @@ class LocationDatePicker extends React.Component {
13242
13262
  ...otherProps
13243
13263
  } = this.props;
13244
13264
  const {
13245
- isLoading
13265
+ disabledDates,
13266
+ isLoading,
13267
+ error
13246
13268
  } = this.state;
13269
+ if (error) {
13270
+ console.error(error);
13271
+ return null;
13272
+ }
13247
13273
  return /*#__PURE__*/React__default["default"].createElement(DatePicker$1, Object.assign({}, otherProps, {
13248
13274
  minDate: minDate,
13249
13275
  maxDate: maxDate,
13250
- disable: this.listDisabled(),
13276
+ disable: disabledDates,
13251
13277
  handleDateChange: handleDateChange,
13252
13278
  loading: isLoading,
13253
13279
  fetchData: this.fetchData,
@@ -13259,7 +13285,9 @@ class LocationDatePicker extends React.Component {
13259
13285
  }
13260
13286
  LocationDatePicker.defaultProps = {
13261
13287
  defaultValue: '',
13262
- locationPid: null
13288
+ locationPid: null,
13289
+ minDate: null,
13290
+ maxDate: null
13263
13291
  };
13264
13292
 
13265
13293
  const serializeError = error => ({
@@ -15746,9 +15774,8 @@ class ExistingRelations extends React.Component {
15746
15774
  const {
15747
15775
  activePage
15748
15776
  } = this.state;
15749
- const activeRows = rows.slice((activePage - 1) * showMaxRows, activePage * showMaxRows);
15750
15777
  return /*#__PURE__*/React__default["default"].createElement(ResultsTable, {
15751
- data: activeRows,
15778
+ data: rows,
15752
15779
  columns: columns,
15753
15780
  totalHitsCount: rows.length,
15754
15781
  showMaxRows: showMaxRows,
@@ -24871,7 +24898,7 @@ const deleteItem = itemPid => {
24871
24898
  }
24872
24899
  };
24873
24900
  };
24874
- const checkoutItem$2 = function (documentPid, itemPid, patronPid) {
24901
+ const checkoutItem$1 = function (documentPid, itemPid, patronPid) {
24875
24902
  let force = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
24876
24903
  return async dispatch => {
24877
24904
  dispatch({
@@ -25071,7 +25098,7 @@ const mapDispatchToProps$J = dispatch => ({
25071
25098
  deleteItem: itemPid => dispatch(deleteItem(itemPid)),
25072
25099
  checkoutItem: function (documentPid, itemPid, patronPid) {
25073
25100
  let force = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
25074
- return dispatch(checkoutItem$2(documentPid, itemPid, patronPid, force));
25101
+ return dispatch(checkoutItem$1(documentPid, itemPid, patronPid, force));
25075
25102
  }
25076
25103
  });
25077
25104
  const ItemActionMenu = reactRedux.connect(mapStateToProps$W, mapDispatchToProps$J)(ItemActionMenu$1);
@@ -25452,7 +25479,7 @@ const mapDispatchToProps$I = dispatch => ({
25452
25479
  deleteItem: itemPid => dispatch(deleteItem(itemPid)),
25453
25480
  checkoutItem: function (documentPid, itemPid, patronPid) {
25454
25481
  let force = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
25455
- return dispatch(checkoutItem$2(documentPid, itemPid, patronPid, force));
25482
+ return dispatch(checkoutItem$1(documentPid, itemPid, patronPid, force));
25456
25483
  }
25457
25484
  });
25458
25485
  const ItemMetadata$1 = reactRedux.connect(mapStateToProps$U, mapDispatchToProps$I)(ItemMetadata$2);
@@ -26625,7 +26652,7 @@ class LoanMetadata$1 extends React.Component {
26625
26652
  getDelivery(_delivery) {
26626
26653
  const delivery = _get__default["default"](_delivery, 'method');
26627
26654
  if (delivery) {
26628
- const deliveryMethod = invenioConfig.CIRCULATION.deliveryMethods[delivery];
26655
+ const deliveryMethod = invenioConfig.CIRCULATION.deliveryMethods[delivery] || invenioConfig.CIRCULATION.deliveryMethodSelfCheckout[delivery];
26629
26656
  return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, deliveryMethod.text, ' ', deliveryMethod.iconClass && /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Icon, {
26630
26657
  className: deliveryMethod.iconClass
26631
26658
  }));
@@ -27252,16 +27279,18 @@ class LoanUpdateDates$1 extends React.Component {
27252
27279
  }), warning && this.renderWarning(warning), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Form, null, /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Form.Group, null, /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Form.Field, {
27253
27280
  inline: true,
27254
27281
  required: true
27255
- }, /*#__PURE__*/React__default["default"].createElement("label", null, startLabel), /*#__PURE__*/React__default["default"].createElement(DatePicker$1, {
27282
+ }, /*#__PURE__*/React__default["default"].createElement("label", null, startLabel), /*#__PURE__*/React__default["default"].createElement(LocationDatePicker, {
27256
27283
  maxDate: active ? this.today() : null,
27257
27284
  defaultValue: active ? startDate : requestStartDate,
27285
+ locationPid: sessionManager.user.locationPid,
27258
27286
  placeholder: startLabel,
27259
27287
  handleDateChange: value => this.handleStartDateChange(value)
27260
27288
  })), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Form.Field, {
27261
27289
  inline: true,
27262
27290
  required: true
27263
- }, /*#__PURE__*/React__default["default"].createElement("label", null, endLabel), /*#__PURE__*/React__default["default"].createElement(DatePicker$1, {
27291
+ }, /*#__PURE__*/React__default["default"].createElement("label", null, endLabel), /*#__PURE__*/React__default["default"].createElement(LocationDatePicker, {
27264
27292
  defaultValue: active ? endDate : requestExpireDate,
27293
+ locationPid: sessionManager.user.locationPid,
27265
27294
  placeholder: endLabel,
27266
27295
  handleDateChange: value => this.handleEndDateChange(value)
27267
27296
  }))), hint && this.renderHint(hint))), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Modal.Actions, {
@@ -29399,7 +29428,7 @@ class PatronBulkExtendLoans$1 extends React.Component {
29399
29428
  patronPid,
29400
29429
  bulkLoanExtension,
29401
29430
  isLoading,
29402
- hidden,
29431
+ disabled,
29403
29432
  ...uiProps
29404
29433
  } = this.props;
29405
29434
  const {
@@ -29409,12 +29438,13 @@ class PatronBulkExtendLoans$1 extends React.Component {
29409
29438
  open: open,
29410
29439
  onClose: this.close,
29411
29440
  onOpen: this.open,
29412
- trigger: !hidden && /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Button, Object.assign({
29441
+ trigger: /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Button, Object.assign({
29413
29442
  labelPosition: "left",
29414
29443
  fluid: true,
29415
29444
  icon: true,
29416
29445
  primary: true,
29417
- loading: isLoading
29446
+ loading: isLoading,
29447
+ disabled: disabled
29418
29448
  }, uiProps), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Icon, {
29419
29449
  name: "refresh"
29420
29450
  }), "Extend all loans")
@@ -29430,7 +29460,7 @@ class PatronBulkExtendLoans$1 extends React.Component {
29430
29460
  }
29431
29461
  PatronBulkExtendLoans$1.defaultProps = {
29432
29462
  isLoading: false,
29433
- hidden: true
29463
+ disabled: true
29434
29464
  };
29435
29465
 
29436
29466
  const IS_LOADING$l = 'fetchPatronCurrentLoans/IS_LOADING';
@@ -29571,7 +29601,7 @@ const CLEAR_SEARCH = 'itemsSearchBarcode/CLEAR_SEARCH';
29571
29601
  const IS_LOADING$h = 'patronItemCheckout/IS_LOADING';
29572
29602
  const SUCCESS$h = 'patronItemCheckout/SUCCESS';
29573
29603
  const HAS_ERROR$h = 'patronItemCheckout/ERROR';
29574
- const checkoutItem$1 = function (documentPid, itemPid, patronPid) {
29604
+ const checkoutItem = function (documentPid, itemPid, patronPid) {
29575
29605
  let force = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
29576
29606
  return async dispatch => {
29577
29607
  dispatch({
@@ -29612,7 +29642,7 @@ const checkoutItem$1 = function (documentPid, itemPid, patronPid) {
29612
29642
  const mapDispatchToProps$t = dispatch => ({
29613
29643
  checkoutItem: function (documentPid, itemPid, patronPid) {
29614
29644
  let force = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
29615
- return dispatch(checkoutItem$1(documentPid, itemPid, patronPid, force));
29645
+ return dispatch(checkoutItem(documentPid, itemPid, patronPid, force));
29616
29646
  }
29617
29647
  });
29618
29648
  const mapStateToProps$E = state => ({
@@ -29774,7 +29804,7 @@ const mapStateToProps$D = state => ({
29774
29804
  const mapDispatchToProps$s = dispatch => ({
29775
29805
  checkoutItem: function (documentPid, itemPid, patronPid) {
29776
29806
  let force = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
29777
- return dispatch(checkoutItem$1(documentPid, itemPid, patronPid, force));
29807
+ return dispatch(checkoutItem(documentPid, itemPid, patronPid, force));
29778
29808
  }
29779
29809
  });
29780
29810
  const ItemsResultsList = reactRedux.connect(mapStateToProps$D, mapDispatchToProps$s)(ItemsResultsList$1);
@@ -29900,7 +29930,7 @@ const fetchAndCheckoutIfOne = (barcode, patronPid, onSuccess) => {
29900
29930
  type: recordToPidType(itemToCheckout),
29901
29931
  value: itemToCheckout.metadata.pid
29902
29932
  };
29903
- dispatch(checkoutItem$1(documentPid, itemPid, patronPid, true));
29933
+ dispatch(checkoutItem(documentPid, itemPid, patronPid, true));
29904
29934
  onSuccess();
29905
29935
  }
29906
29936
  } catch (error) {
@@ -29935,7 +29965,7 @@ const mapDispatchToProps$r = dispatch => ({
29935
29965
  clearResults: () => dispatch(clearResults()),
29936
29966
  checkoutItem: function (documentPid, itemPid, patronPid) {
29937
29967
  let force = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
29938
- return dispatch(checkoutItem$1(documentPid, itemPid, patronPid, force));
29968
+ return dispatch(checkoutItem(documentPid, itemPid, patronPid, force));
29939
29969
  }
29940
29970
  });
29941
29971
  const mapStateToProps$C = state => ({
@@ -30963,7 +30993,7 @@ class PatronDetails$1 extends React.Component {
30963
30993
  offset: 150
30964
30994
  }, /*#__PURE__*/React__default["default"].createElement(PatronBulkExtendLoans, {
30965
30995
  patronPid: currentPatronPid,
30966
- hidden: currentLoans.total === 0,
30996
+ disabled: currentLoans.total === 0,
30967
30997
  fluid: true,
30968
30998
  color: "blue"
30969
30999
  }), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Divider, {
@@ -37766,11 +37796,11 @@ class SelfCheckoutModal$1 extends React__default["default"].Component {
37766
37796
  size: "large",
37767
37797
  centered: true,
37768
37798
  onClose: () => toggleModal(false)
37769
- }, /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Modal.Header, null, `You are about to checkout a book with barcode:
37799
+ }, /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Modal.Header, null, `You are about to checkout the literature with barcode:
37770
37800
  ${item === null || item === void 0 ? void 0 : item.metadata.barcode}`), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Modal.Content, null, /*#__PURE__*/React__default["default"].createElement(DocumentCard, {
37771
37801
  item: item
37772
37802
  }), /*#__PURE__*/React__default["default"].createElement(ManualCheckout, {
37773
- label: "Wrong book?",
37803
+ label: "Wrong literature?",
37774
37804
  autofocus: true,
37775
37805
  show: true,
37776
37806
  onBarcodeInput: onBarcodeDetected
@@ -37808,22 +37838,19 @@ const notifyResultMessage = message => {
37808
37838
  dispatch(sendWarningNotification(message));
37809
37839
  };
37810
37840
  };
37811
- const searchItem = async (dispatch, term) => {
37812
- const upperCasedTerm = term.toUpperCase();
37813
- const response = await itemApi.list(itemApi.query().withBarcode(upperCasedTerm).qs());
37814
- const item = _first__default["default"](response.data.hits) || null;
37815
- dispatch({
37816
- type: SEARCH_ITEM_SUCCESS,
37817
- payload: item
37818
- });
37819
- };
37820
37841
  const selfCheckOutSearch = term => {
37821
37842
  return async dispatch => {
37822
37843
  dispatch({
37823
37844
  type: SEARCH_IS_LOADING
37824
37845
  });
37825
37846
  try {
37826
- await searchItem(dispatch, term);
37847
+ const upperCasedTerm = term.toUpperCase();
37848
+ const response = await loanApi.doSelfCheckoutSearchItem(upperCasedTerm);
37849
+ const item = response.data || null;
37850
+ dispatch({
37851
+ type: SEARCH_ITEM_SUCCESS,
37852
+ payload: item
37853
+ });
37827
37854
  } catch (error) {
37828
37855
  dispatch({
37829
37856
  type: SEARCH_HAS_ERROR,
@@ -37833,16 +37860,13 @@ const selfCheckOutSearch = term => {
37833
37860
  }
37834
37861
  };
37835
37862
  };
37836
- const checkoutItem = (documentPid, itemPid, patronPid) => {
37863
+ const selfCheckOut = (documentPid, itemPid, patronPid) => {
37837
37864
  return async dispatch => {
37838
37865
  try {
37839
- const response = await loanApi.doCheckout(documentPid, itemPid, patronPid);
37840
- const {
37841
- pid
37842
- } = response.data.metadata;
37843
- const linkToLoan = /*#__PURE__*/React__default["default"].createElement("p", null, "The loan ", pid, " has been created by you! You can view all your current loans on your ", /*#__PURE__*/React__default["default"].createElement(reactRouterDom.Link, {
37866
+ await loanApi.doSelfCheckout(documentPid, itemPid, patronPid);
37867
+ const linkToLoan = /*#__PURE__*/React__default["default"].createElement("p", null, "Self-checkout completed! You can view all your current loans on your", ' ', /*#__PURE__*/React__default["default"].createElement(reactRouterDom.Link, {
37844
37868
  to: FrontSiteRoutes.patronProfile
37845
- }, "profile"), ' ', "page.");
37869
+ }, "profile"), " page.");
37846
37870
  dispatch(sendSuccessNotification('Success!', linkToLoan));
37847
37871
  } catch (error) {
37848
37872
  dispatch(sendErrorNotification(error));
@@ -37851,7 +37875,7 @@ const checkoutItem = (documentPid, itemPid, patronPid) => {
37851
37875
  };
37852
37876
 
37853
37877
  const mapDispatchToProps$a = dispatch => ({
37854
- checkoutItem: (documentPid, itemPid, patronPid) => dispatch(checkoutItem(documentPid, itemPid, patronPid))
37878
+ checkoutItem: (documentPid, itemPid, patronPid) => dispatch(selfCheckOut(documentPid, itemPid, patronPid))
37855
37879
  });
37856
37880
  const mapStateToProps$b = state => ({
37857
37881
  user: state.authenticationManagement.data,
@@ -37885,48 +37909,8 @@ class SelfCheckout$1 extends React__default["default"].Component {
37885
37909
  selfCheckOutSearch
37886
37910
  } = this.props;
37887
37911
  await selfCheckOutSearch(detectedBarcode);
37888
-
37889
- // open modal if item is loanable
37890
- const shouldShowModal = this.isItemLoanable(detectedBarcode);
37891
- if (shouldShowModal) {
37892
- this.toggleModal(true);
37893
- } else {
37894
- this.toggleModal(false);
37895
- }
37896
- }
37897
- };
37898
- this.itemStatus = item => ({
37899
- canCirculate: () => invenioConfig.ITEMS.canCirculateStatuses.includes(item.metadata.status),
37900
- isOnShelf: () => !item.metadata.circulation.state // on shelf if circulation.state doesn't exist
37901
- });
37902
- this.isItemLoanable = itemBarcode => {
37903
- const {
37904
- user,
37905
- item,
37906
- notifyResultMessage
37907
- } = this.props;
37908
- var resultMessage = `Book with barcode ${itemBarcode} not found.`;
37909
- if (!_isEmpty__default["default"](item)) {
37910
- if (this.itemStatus(item).canCirculate()) {
37911
- if (this.itemStatus(item).isOnShelf()) {
37912
- return true;
37913
- } else {
37914
- if (item.metadata.circulation.patron_pid === user.id.toString()) {
37915
- resultMessage = `You already loaned this book with barcode: ${itemBarcode}!`;
37916
- } else {
37917
- resultMessage = `Book with barcode: ${itemBarcode} is currently on loan!`;
37918
- }
37919
- }
37920
- } else {
37921
- var _item$metadata;
37922
- const status = _find__default["default"](invenioConfig.ITEMS.statuses, {
37923
- value: (_item$metadata = item.metadata) === null || _item$metadata === void 0 ? void 0 : _item$metadata.status
37924
- });
37925
- resultMessage = `Book with barcode: ${itemBarcode} is ${status === null || status === void 0 ? void 0 : status.text}!`;
37926
- }
37912
+ this.toggleModal(true);
37927
37913
  }
37928
- notifyResultMessage(resultMessage);
37929
- return false;
37930
37914
  };
37931
37915
  this.renderInstructions = () => {
37932
37916
  return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Header, {
@@ -37979,13 +37963,11 @@ class SelfCheckout$1 extends React__default["default"].Component {
37979
37963
  }), this.renderInstructions());
37980
37964
  }
37981
37965
  }
37982
- SelfCheckout$1.defaultProps = {
37983
- item: null
37984
- };
37985
37966
  var SelfCheckoutComponent = Overridable__default["default"].component('SelfCheckout', SelfCheckout$1);
37986
37967
 
37987
37968
  const mapDispatchToProps$9 = dispatch => ({
37988
37969
  selfCheckOutSearch: term => dispatch(selfCheckOutSearch(term)),
37970
+ selfCheckOut: term => dispatch(selfCheckOut(term)),
37989
37971
  notifyResultMessage: message => dispatch(notifyResultMessage(message))
37990
37972
  });
37991
37973
  const mapStateToProps$a = state => ({
@@ -39025,7 +39007,7 @@ class PatronCurrentLoans$1 extends React.Component {
39025
39007
  floated: "right"
39026
39008
  }, /*#__PURE__*/React__default["default"].createElement(PatronBulkExtendLoans, {
39027
39009
  patronPid: currentUser.id,
39028
- hidden: loans.total === 0,
39010
+ disabled: loans.total === 0,
39029
39011
  color: "orange"
39030
39012
  }))), /*#__PURE__*/React__default["default"].createElement(ILSItemPlaceholder, {
39031
39013
  fluid: true,