@inveniosoftware/react-invenio-app-ils 1.2.0 → 2.0.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/esm/index.js CHANGED
@@ -389,6 +389,10 @@ const RECORDS_CONFIG = {
389
389
  },
390
390
  CIRCULATION: {
391
391
  deliveryMethods: {
392
+ 'NOT-SPECIFIED': {
393
+ text: 'Not Specified',
394
+ iconClass: 'question circle outline'
395
+ },
392
396
  PICKUP: {
393
397
  text: 'Pick it up at the library desk',
394
398
  iconClass: 'warehouse'
@@ -693,6 +697,7 @@ const RECORDS_CONFIG = {
693
697
  }
694
698
  },
695
699
  ITEMS: {
700
+ identifiersToDisplayInFrontside: [],
696
701
  circulationRestrictions: [{
697
702
  value: 'NO_RESTRICTION',
698
703
  text: 'No restriction (4 weeks)'
@@ -2351,11 +2356,15 @@ const orderApi = {
2351
2356
  const bannerURL = '/banners/';
2352
2357
  const getActive = async () => {
2353
2358
  const URLPath = window.location.pathname;
2354
- return await http.get(`${bannerURL}active`, {
2359
+ const response = await http.get(`${bannerURL}`, {
2355
2360
  params: {
2356
- url_path: URLPath
2361
+ url_path: URLPath,
2362
+ active: true
2357
2363
  }
2358
2364
  });
2365
+ response.data.total = getSearchTotal(response.data.hits);
2366
+ response.data.hits = response.data.hits.hits;
2367
+ return response;
2359
2368
  };
2360
2369
  const bannerApi = {
2361
2370
  getActive: getActive,
@@ -2414,7 +2423,7 @@ const serializer$9 = {
2414
2423
  };
2415
2424
 
2416
2425
  const documentRequestURL = '/document-requests/';
2417
- const apiPaths$2 = {
2426
+ const apiPaths$3 = {
2418
2427
  accept: `${documentRequestURL}:docReqPid/accept`,
2419
2428
  item: `${documentRequestURL}:docReqPid`,
2420
2429
  list: documentRequestURL,
@@ -2423,12 +2432,12 @@ const apiPaths$2 = {
2423
2432
  provider: `${documentRequestURL}:docReqPid/provider`
2424
2433
  };
2425
2434
  const create$8 = async data => {
2426
- const response = await http.post(apiPaths$2.list, data);
2435
+ const response = await http.post(apiPaths$3.list, data);
2427
2436
  response.data = serializer$9.fromJSON(response.data);
2428
2437
  return response;
2429
2438
  };
2430
2439
  const update$8 = async (docRequestPid, data) => {
2431
- const path = generatePath(apiPaths$2.item, {
2440
+ const path = generatePath(apiPaths$3.item, {
2432
2441
  docReqPid: docRequestPid
2433
2442
  });
2434
2443
  const response = await http.put(path, data);
@@ -2436,7 +2445,7 @@ const update$8 = async (docRequestPid, data) => {
2436
2445
  return response;
2437
2446
  };
2438
2447
  const get$c = async docRequestPid => {
2439
- const path = generatePath(apiPaths$2.item, {
2448
+ const path = generatePath(apiPaths$3.item, {
2440
2449
  docReqPid: docRequestPid
2441
2450
  });
2442
2451
  const response = await http.get(path);
@@ -2444,7 +2453,7 @@ const get$c = async docRequestPid => {
2444
2453
  return response;
2445
2454
  };
2446
2455
  const del$8 = async docRequestPid => {
2447
- const path = generatePath(apiPaths$2.item, {
2456
+ const path = generatePath(apiPaths$3.item, {
2448
2457
  docReqPid: docRequestPid
2449
2458
  });
2450
2459
  const response = await http.delete(path);
@@ -2456,19 +2465,19 @@ const performAction = async (urlPath, data) => {
2456
2465
  return response;
2457
2466
  };
2458
2467
  const accept = async docRequestPid => {
2459
- const urlPath = generatePath(apiPaths$2.accept, {
2468
+ const urlPath = generatePath(apiPaths$3.accept, {
2460
2469
  docReqPid: docRequestPid
2461
2470
  });
2462
2471
  return performAction(urlPath);
2463
2472
  };
2464
2473
  const addDocument$1 = async (docReqPid, data) => {
2465
- const url = generatePath(apiPaths$2.document, {
2474
+ const url = generatePath(apiPaths$3.document, {
2466
2475
  docReqPid: docReqPid
2467
2476
  });
2468
2477
  return await http.post(url, data);
2469
2478
  };
2470
2479
  const removeDocument$1 = async (docReqPid, data) => {
2471
- const url = generatePath(apiPaths$2.document, {
2480
+ const url = generatePath(apiPaths$3.document, {
2472
2481
  docReqPid: docReqPid
2473
2482
  });
2474
2483
  // https://github.com/axios/axios/issues/897#issuecomment-343715381
@@ -2477,19 +2486,19 @@ const removeDocument$1 = async (docReqPid, data) => {
2477
2486
  });
2478
2487
  };
2479
2488
  const addProvider$1 = async (docReqPid, data) => {
2480
- const url = generatePath(apiPaths$2.provider, {
2489
+ const url = generatePath(apiPaths$3.provider, {
2481
2490
  docReqPid: docReqPid
2482
2491
  });
2483
2492
  return await http.post(url, data);
2484
2493
  };
2485
2494
  const removeProvider$1 = async docReqPid => {
2486
- const url = generatePath(apiPaths$2.provider, {
2495
+ const url = generatePath(apiPaths$3.provider, {
2487
2496
  docReqPid: docReqPid
2488
2497
  });
2489
2498
  return await http.delete(url);
2490
2499
  };
2491
2500
  const decline = async (docRequestPid, data) => {
2492
- const urlPath = generatePath(apiPaths$2.decline, {
2501
+ const urlPath = generatePath(apiPaths$3.decline, {
2493
2502
  docReqPid: docRequestPid
2494
2503
  });
2495
2504
  return performAction(urlPath, data);
@@ -3409,7 +3418,7 @@ const serializer$4 = {
3409
3418
  fromJSON: serializeResponse$3
3410
3419
  };
3411
3420
 
3412
- const apiPaths$1 = {
3421
+ const apiPaths$2 = {
3413
3422
  checkout: '/circulation/loans/checkout',
3414
3423
  selfCheckout: '/circulation/loans/self-checkout',
3415
3424
  notificationOverdue: '/circulation/loans/:loanPid/notification-overdue',
@@ -3421,7 +3430,7 @@ const apiPaths$1 = {
3421
3430
  bulkExtend: '/circulation/bulk-extend'
3422
3431
  };
3423
3432
  const get$7 = async loanPid => {
3424
- const path = generatePath(apiPaths$1.item, {
3433
+ const path = generatePath(apiPaths$2.item, {
3425
3434
  loanPid: loanPid
3426
3435
  });
3427
3436
  const response = await http.get(path);
@@ -3474,7 +3483,7 @@ const doRequest = async function (documentPid, patronPid) {
3474
3483
  method: deliveryMethod
3475
3484
  };
3476
3485
  }
3477
- const response = await http.post(apiPaths$1.request, payload);
3486
+ const response = await http.post(apiPaths$2.request, payload);
3478
3487
  response.data = serializer$4.fromJSON(response.data);
3479
3488
  return response;
3480
3489
  };
@@ -3501,12 +3510,12 @@ const doCheckout = async function (documentPid, itemPid, patronPid) {
3501
3510
  if (force) {
3502
3511
  payload.force = true;
3503
3512
  }
3504
- const response = await http.post(apiPaths$1.checkout, payload);
3513
+ const response = await http.post(apiPaths$2.checkout, payload);
3505
3514
  response.data = serializer$4.fromJSON(response.data);
3506
3515
  return response;
3507
3516
  };
3508
3517
  const doSelfCheckoutSearchItem = async barcode => {
3509
- const response = await http.get(`${apiPaths$1.selfCheckout}?barcode=${barcode}`);
3518
+ const response = await http.get(`${apiPaths$2.selfCheckout}?barcode=${barcode}`);
3510
3519
  response.data = serializer$4.fromJSON(response.data);
3511
3520
  return response;
3512
3521
  };
@@ -3519,12 +3528,12 @@ const doSelfCheckout = async (documentPid, itemPid, patronPid) => {
3519
3528
  transaction_location_pid: `${currentUser.locationPid}`,
3520
3529
  transaction_user_pid: `${currentUser.id}`
3521
3530
  };
3522
- const response = await http.post(apiPaths$1.selfCheckout, payload);
3531
+ const response = await http.post(apiPaths$2.selfCheckout, payload);
3523
3532
  response.data = serializer$4.fromJSON(response.data);
3524
3533
  return response;
3525
3534
  };
3526
3535
  const assignItemToLoan$1 = async (itemPid, loanPid) => {
3527
- const path = generatePath(apiPaths$1.replaceItem, {
3536
+ const path = generatePath(apiPaths$2.replaceItem, {
3528
3537
  loanPid: loanPid
3529
3538
  });
3530
3539
  const payload = {
@@ -3538,7 +3547,7 @@ const bulkExtendLoans = async patronPid => {
3538
3547
  const payload = {
3539
3548
  patron_pid: patronPid
3540
3549
  };
3541
- const response = await http.post(apiPaths$1.bulkExtend, payload);
3550
+ const response = await http.post(apiPaths$2.bulkExtend, payload);
3542
3551
  return response;
3543
3552
  };
3544
3553
  class QueryBuilder$4 {
@@ -3652,19 +3661,19 @@ const queryBuilder$4 = () => {
3652
3661
  return new QueryBuilder$4();
3653
3662
  };
3654
3663
  const list$7 = async query => {
3655
- const response = await http.get(`${apiPaths$1.list}?q=${query}`);
3664
+ const response = await http.get(`${apiPaths$2.list}?q=${query}`);
3656
3665
  response.data.total = getSearchTotal(response.data.hits);
3657
3666
  response.data.hits = response.data.hits.hits.map(hit => serializer$4.fromJSON(hit));
3658
3667
  return response;
3659
3668
  };
3660
3669
  const sendOverdueLoansNotificationReminder$1 = async payload => {
3661
- const path = generatePath(apiPaths$1.notificationOverdue, {
3670
+ const path = generatePath(apiPaths$2.notificationOverdue, {
3662
3671
  loanPid: payload.loanPid
3663
3672
  });
3664
3673
  return await http.post(path, payload);
3665
3674
  };
3666
3675
  const count$2 = async query => {
3667
- const response = await http.get(`${apiPaths$1.list}?q=${query}`);
3676
+ const response = await http.get(`${apiPaths$2.list}?q=${query}`);
3668
3677
  response.data = getSearchTotal(response.data.hits);
3669
3678
  return response;
3670
3679
  };
@@ -3688,13 +3697,13 @@ const updateDates = async function (loanPid) {
3688
3697
  if (requestExpireDate) {
3689
3698
  payload.request_expire_date = requestExpireDate;
3690
3699
  }
3691
- const path = generatePath(apiPaths$1.updateDates, {
3700
+ const path = generatePath(apiPaths$2.updateDates, {
3692
3701
  loanPid: loanPid
3693
3702
  });
3694
3703
  return await http.post(path, payload);
3695
3704
  };
3696
3705
  const loanApi = {
3697
- searchBaseURL: `${apiConfig.baseURL}${apiPaths$1.list}`,
3706
+ searchBaseURL: `${apiConfig.baseURL}${apiPaths$2.list}`,
3698
3707
  assignItemToLoan: assignItemToLoan$1,
3699
3708
  query: queryBuilder$4,
3700
3709
  list: list$7,
@@ -3743,12 +3752,25 @@ function serializeLocationResponse(hit) {
3743
3752
  }
3744
3753
  return result;
3745
3754
  }
3755
+ function serializeLocationClosurePeriodsResponse(hit) {
3756
+ let result = [];
3757
+ if (!_isEmpty(hit)) {
3758
+ result = hit.closure_periods.map(period => ({
3759
+ start: new DateTime.fromISO(period.start),
3760
+ end: new DateTime.fromISO(period.end)
3761
+ }));
3762
+ }
3763
+ return result;
3764
+ }
3746
3765
  const internalLocationSerializer = {
3747
3766
  fromJSON: serializeInternalLocationResponse
3748
3767
  };
3749
3768
  const locationSerializer = {
3750
3769
  fromJSON: serializeLocationResponse
3751
3770
  };
3771
+ const locationClosurePeriodsSerializer = {
3772
+ fromJSON: serializeLocationClosurePeriodsResponse
3773
+ };
3752
3774
 
3753
3775
  const internalLocationURL = '/internal-locations/';
3754
3776
  const get$6 = async internalLocationPid => {
@@ -3789,6 +3811,9 @@ const internalLocationApi = {
3789
3811
  };
3790
3812
 
3791
3813
  const locationURL = '/locations/';
3814
+ const apiPaths$1 = {
3815
+ closure_periods: `/closure_periods/`
3816
+ };
3792
3817
  const get$5 = async locationPid => {
3793
3818
  const response = await http.get(`${locationURL}${locationPid}`);
3794
3819
  response.data = locationSerializer.fromJSON(response.data);
@@ -3815,13 +3840,19 @@ const list$5 = async function () {
3815
3840
  response.data.hits = response.data.hits.hits.map(hit => locationSerializer.fromJSON(hit));
3816
3841
  return response;
3817
3842
  };
3843
+ const getClosurePeriods = async (locationPid, year) => {
3844
+ const response = await http.get(`${locationURL}${locationPid}${apiPaths$1.closure_periods}${year}`);
3845
+ response.data = locationClosurePeriodsSerializer.fromJSON(response.data);
3846
+ return response;
3847
+ };
3818
3848
  const locationApi = {
3819
3849
  list: list$5,
3820
3850
  get: get$5,
3821
3851
  delete: del$2,
3822
3852
  create: create$2,
3823
3853
  update: update$2,
3824
- url: locationURL
3854
+ url: locationURL,
3855
+ getClosurePeriods: getClosurePeriods
3825
3856
  };
3826
3857
 
3827
3858
  function serializeResponse$2(hit) {
@@ -6150,7 +6181,8 @@ class DocumentItemBody extends Component {
6150
6181
  const {
6151
6182
  items,
6152
6183
  shelfLink,
6153
- documentDetails
6184
+ documentDetails,
6185
+ identifiersToDisplayInFrontside
6154
6186
  } = this.props;
6155
6187
  return items.map(item => /*#__PURE__*/React.createElement(Table.Row, {
6156
6188
  key: item.pid
@@ -6160,7 +6192,16 @@ class DocumentItemBody extends Component {
6160
6192
  }, item.barcode), /*#__PURE__*/React.createElement(Table.Cell, {
6161
6193
  "data-label": "Shelf",
6162
6194
  className: "document-item-table-itemCell"
6163
- }, shelfLink !== null ? shelfLink(item, documentDetails) : _get(item, 'shelf')), /*#__PURE__*/React.createElement(Table.Cell, {
6195
+ }, shelfLink !== null ? shelfLink(item, documentDetails) : _get(item, 'shelf')), identifiersToDisplayInFrontside.map(identifier => {
6196
+ var _item$identifiers, _item$identifiers$fin;
6197
+ return /*#__PURE__*/React.createElement(Table.Cell, {
6198
+ key: identifier,
6199
+ "data-label": identifier.text,
6200
+ className: "document-item-table-itemCell"
6201
+ }, (_item$identifiers = item.identifiers) === null || _item$identifiers === void 0 ? void 0 : (_item$identifiers$fin = _item$identifiers.find(entry => {
6202
+ return entry.scheme === identifier.key;
6203
+ })) === null || _item$identifiers$fin === void 0 ? void 0 : _item$identifiers$fin.value);
6204
+ }), /*#__PURE__*/React.createElement(Table.Cell, {
6164
6205
  "data-label": "Status"
6165
6206
  }, this.statusLabel(item)), /*#__PURE__*/React.createElement(Table.Cell, {
6166
6207
  "data-label": "Medium"
@@ -7929,7 +7970,7 @@ const BannerCmp = _ref => {
7929
7970
  break;
7930
7971
  }
7931
7972
  return /*#__PURE__*/React.createElement(Overridable, {
7932
- id: "Banner.layout",
7973
+ id: "Banners.layout",
7933
7974
  message: message,
7934
7975
  category: category,
7935
7976
  colorProp: colorProp
@@ -7941,42 +7982,44 @@ const BannerCmp = _ref => {
7941
7982
  }
7942
7983
  })));
7943
7984
  };
7944
- class Banner$1 extends Component {
7985
+ class Banners$1 extends Component {
7945
7986
  componentDidMount() {
7946
7987
  const {
7947
- fetchBanner,
7948
- resetBanner
7988
+ fetchBanners,
7989
+ resetBanners
7949
7990
  } = this.props;
7950
- resetBanner();
7951
- fetchBanner();
7952
- this.intervalFetchBannerId = setInterval(fetchBanner, FETCH_BANNER_EVERY_SECS * 1000);
7991
+ resetBanners();
7992
+ fetchBanners();
7993
+ this.intervalfetchBannersId = setInterval(fetchBanners, FETCH_BANNER_EVERY_SECS * 1000);
7953
7994
  }
7954
7995
  componentWillUnmount() {
7955
- this.intervalFetchBannerId && clearInterval(this.intervalFetchBannerId);
7996
+ this.intervalfetchBannersId && clearInterval(this.intervalfetchBannersId);
7956
7997
  }
7957
7998
  render() {
7958
7999
  const {
7959
- banner,
8000
+ banners,
7960
8001
  children
7961
8002
  } = this.props;
7962
- return /*#__PURE__*/React.createElement(React.Fragment, null, !_isEmpty(banner) ? /*#__PURE__*/React.createElement(BannerCmp, banner) : null, " ", children);
8003
+ return /*#__PURE__*/React.createElement(React.Fragment, null, !_isEmpty(banners) ? banners.hits.map(banner => /*#__PURE__*/React.createElement(BannerCmp, Object.assign({
8004
+ key: banner.id
8005
+ }, banner))) : null, ' ', children);
7963
8006
  }
7964
8007
  }
7965
- Banner$1.defaultProps = {
7966
- banner: null,
8008
+ Banners$1.defaultProps = {
8009
+ banners: null,
7967
8010
  children: null
7968
8011
  };
7969
- var BannerComponent = Overridable.component('Banner', Banner$1);
8012
+ var BannerComponent = Overridable.component('Banners', Banners$1);
7970
8013
 
7971
- const BANNER_RESET = 'fetchBanner/RESET';
7972
- const BANNER_SUCCESS = 'fetchBanner/SUCCESS';
7973
- const BANNER_HAS_ERROR = 'fetchBanner/HAS_ERROR';
7974
- const resetBanner = () => {
8014
+ const BANNER_RESET = 'fetchBanners/RESET';
8015
+ const BANNER_SUCCESS = 'fetchBanners/SUCCESS';
8016
+ const BANNER_HAS_ERROR = 'fetchBanners/HAS_ERROR';
8017
+ const resetBanners = () => {
7975
8018
  return async dispatch => dispatch({
7976
8019
  type: BANNER_RESET
7977
8020
  });
7978
8021
  };
7979
- const fetchBanner = () => {
8022
+ const fetchBanners = () => {
7980
8023
  return async dispatch => {
7981
8024
  try {
7982
8025
  const response = await bannerApi.getActive();
@@ -7994,14 +8037,14 @@ const fetchBanner = () => {
7994
8037
  };
7995
8038
 
7996
8039
  const mapStateToProps$1D = state => ({
7997
- banner: state.banner.data,
7998
- error: state.banner.error
8040
+ banners: state.banners.data,
8041
+ error: state.banners.error
7999
8042
  });
8000
8043
  const mapDispatchToProps$1j = dispatch => ({
8001
- fetchBanner: () => dispatch(fetchBanner()),
8002
- resetBanner: () => dispatch(resetBanner())
8044
+ fetchBanners: () => dispatch(fetchBanners()),
8045
+ resetBanners: () => dispatch(resetBanners())
8003
8046
  });
8004
- const Banner = connect(mapStateToProps$1D, mapDispatchToProps$1j)(BannerComponent);
8047
+ const Banners = connect(mapStateToProps$1D, mapDispatchToProps$1j)(BannerComponent);
8005
8048
 
8006
8049
  const LoginWithLocalAccountLayout = _ref => {
8007
8050
  let {
@@ -8417,7 +8460,7 @@ class Login$1 extends Component {
8417
8460
  this.redirectIfAlreadyLoggedIn();
8418
8461
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Overridable, {
8419
8462
  id: "Login.extras"
8420
- }, /*#__PURE__*/React.createElement(Banner, null)), /*#__PURE__*/React.createElement(LoginLayout, Object.assign({
8463
+ }, /*#__PURE__*/React.createElement(Banners, null)), /*#__PURE__*/React.createElement(LoginLayout, Object.assign({
8421
8464
  hasError: hasError,
8422
8465
  errorHeader: errorHeader,
8423
8466
  errorMessage: errorMessage
@@ -8693,11 +8736,11 @@ class AdminMenu extends Component {
8693
8736
  className: "bo-menu bo-menu-footer"
8694
8737
  }, /*#__PURE__*/React.createElement(Menu.Item, null, /*#__PURE__*/React.createElement(Menu.Menu, null, /*#__PURE__*/React.createElement(Menu.Item, {
8695
8738
  as: "a",
8696
- href: `${invenioConfig.APP.INVENIO_UI_URL}/admin`,
8739
+ href: `${invenioConfig.APP.INVENIO_UI_URL}/administration`,
8697
8740
  target: "_blank"
8698
8741
  }, "Admin panel"), /*#__PURE__*/React.createElement(Menu.Item, {
8699
8742
  as: "a",
8700
- href: `${invenioConfig.APP.INVENIO_UI_URL}/admin/page`,
8743
+ href: `${invenioConfig.APP.INVENIO_UI_URL}/administration/pages`,
8701
8744
  target: "_blank"
8702
8745
  }, "Static pages"))))));
8703
8746
  }
@@ -13123,102 +13166,70 @@ var DatePicker$1 = Overridable.component('DatePicker', DatePicker);
13123
13166
  class LocationDatePicker extends Component {
13124
13167
  constructor(props) {
13125
13168
  super(props);
13126
- this.fetchLocation = async locationPid => {
13127
- this.setState({
13128
- isLoading: true
13129
- });
13130
- try {
13131
- const response = await locationApi.get(locationPid);
13132
- this.setState({
13133
- data: response.data,
13134
- isLoading: false,
13135
- error: {}
13136
- });
13137
- } catch (error) {
13169
+ this.fetchData = () => {
13170
+ this.fetchLocationClosurePeriods();
13171
+ };
13172
+ this.fetchLocationClosurePeriods = async () => {
13173
+ const {
13174
+ locationPid
13175
+ } = this.props;
13176
+ if (!locationPid) {
13138
13177
  this.setState({
13139
13178
  isLoading: false,
13140
- error: error
13179
+ disabledDates: [],
13180
+ error: {
13181
+ message: 'Location PID is missing.'
13182
+ }
13141
13183
  });
13184
+ return;
13142
13185
  }
13143
- };
13144
- this.disableAllDates = (minDate, maxDate, disabled) => {
13145
- let date = DateTime.fromISO(minDate);
13146
- const dateMax = DateTime.fromISO(maxDate);
13147
- while (date <= dateMax) {
13148
- const dateISO = date.toISODate();
13149
- disabled.push(dateISO);
13150
- date = date.plus({
13151
- days: 1
13186
+ this.setState({
13187
+ isLoading: true,
13188
+ error: null
13189
+ });
13190
+ const currentYear = DateTime.now().year;
13191
+ const yearsToFetch = [currentYear - 1, currentYear, currentYear + 1];
13192
+ try {
13193
+ const promises = yearsToFetch.map(year => {
13194
+ const cancellable = withCancel(locationApi.getClosurePeriods(locationPid, year));
13195
+ this.cancellableFetches.push(cancellable);
13196
+ return cancellable.promise;
13152
13197
  });
13153
- }
13154
- };
13155
- this.disableClosures = (maxDate, minDate, data, disabled) => {
13156
- const weekdays = data.metadata.opening_weekdays,
13157
- exceptions = data.metadata.opening_exceptions;
13158
- let date = DateTime.fromISO(minDate);
13159
- const dateMax = DateTime.fromISO(maxDate);
13160
- while (date <= dateMax) {
13161
- const dateISO = date.toISODate();
13162
- let isOpen = weekdays[date.weekday - 1].is_open;
13163
- exceptions.forEach(exception => {
13164
- if (exception.start_date <= dateISO && dateISO <= exception.end_date) {
13165
- isOpen = exception.is_open;
13198
+ const responses = await Promise.all(promises);
13199
+ const disabledDateRanges = responses.flatMap(response => response.data);
13200
+ const disabledDates = disabledDateRanges.flatMap(dateRange => {
13201
+ const dates = [];
13202
+ let currentDate = DateTime.fromISO(dateRange.start);
13203
+ const endDate = DateTime.fromISO(dateRange.end);
13204
+ while (currentDate <= endDate) {
13205
+ dates.push(currentDate.toISODate());
13206
+ currentDate = currentDate.plus({
13207
+ days: 1
13208
+ });
13166
13209
  }
13210
+ return dates;
13167
13211
  });
13168
- if (!isOpen) {
13169
- disabled.push(dateISO);
13170
- }
13171
- date = date.plus({
13172
- days: 1
13212
+ this.setState({
13213
+ disabledDates: disabledDates,
13214
+ isLoading: false
13173
13215
  });
13174
- }
13175
-
13176
- // Disable recent X days including current date as set in the config
13177
- date = DateTime.fromISO(minDate);
13178
- let workingDaysToOffset = invenioConfig.CIRCULATION.requestStartOffset;
13179
- let i = 0;
13180
- while (workingDaysToOffset > 0) {
13181
- const dateISO = date.toISODate();
13182
- if (dateISO === disabled[i]) {
13183
- i++;
13184
- } else {
13185
- disabled.push(dateISO);
13186
- workingDaysToOffset--;
13187
- }
13188
- date = date.plus({
13189
- days: 1
13216
+ } catch (fetchError) {
13217
+ console.error('LocationDatePicker: Failed to fetch closure periods.', fetchError);
13218
+ this.setState({
13219
+ isLoading: false,
13220
+ error: fetchError
13190
13221
  });
13191
13222
  }
13192
13223
  };
13193
- this.listDisabled = () => {
13194
- const {
13195
- minDate,
13196
- maxDate
13197
- } = this.props;
13198
- const {
13199
- isLoading,
13200
- error,
13201
- data
13202
- } = this.state;
13203
- const disabled = [];
13204
- if (isLoading) {
13205
- this.disableAllDates(minDate, maxDate, disabled);
13206
- } else if (!error.response && !_isEmpty(data)) {
13207
- this.disableClosures(maxDate, minDate, data, disabled);
13208
- }
13209
- return disabled;
13210
- };
13211
- this.fetchData = () => {
13212
- const {
13213
- locationPid
13214
- } = this.props;
13215
- this.fetchLocation(locationPid);
13216
- };
13217
13224
  this.state = {
13218
- data: {},
13225
+ disabledDates: [],
13219
13226
  isLoading: false,
13220
- error: {}
13227
+ error: null
13221
13228
  };
13229
+ this.cancellableFetches = [];
13230
+ }
13231
+ componentWillUnmount() {
13232
+ this.cancellableFetches.forEach(cancellable => cancellable.cancel());
13222
13233
  }
13223
13234
  render() {
13224
13235
  const {
@@ -13230,12 +13241,18 @@ class LocationDatePicker extends Component {
13230
13241
  ...otherProps
13231
13242
  } = this.props;
13232
13243
  const {
13233
- isLoading
13244
+ disabledDates,
13245
+ isLoading,
13246
+ error
13234
13247
  } = this.state;
13248
+ if (error) {
13249
+ console.error(error);
13250
+ return null;
13251
+ }
13235
13252
  return /*#__PURE__*/React.createElement(DatePicker$1, Object.assign({}, otherProps, {
13236
13253
  minDate: minDate,
13237
13254
  maxDate: maxDate,
13238
- disable: this.listDisabled(),
13255
+ disable: disabledDates,
13239
13256
  handleDateChange: handleDateChange,
13240
13257
  loading: isLoading,
13241
13258
  fetchData: this.fetchData,
@@ -13247,7 +13264,9 @@ class LocationDatePicker extends Component {
13247
13264
  }
13248
13265
  LocationDatePicker.defaultProps = {
13249
13266
  defaultValue: '',
13250
- locationPid: null
13267
+ locationPid: null,
13268
+ minDate: null,
13269
+ maxDate: null
13251
13270
  };
13252
13271
 
13253
13272
  const serializeError = error => ({
@@ -13808,7 +13827,7 @@ class ESSelectorLoanRequest extends Component {
13808
13827
  placeholder: "Select delivery method",
13809
13828
  options: this.deliveryMethods,
13810
13829
  onChange: this.handleDeliveryMethodChange,
13811
- defaultValue: this.deliveryMethods[1].value,
13830
+ defaultValue: this.defaultDeliveryMethod,
13812
13831
  selection: true
13813
13832
  })) : null;
13814
13833
  };
@@ -13828,7 +13847,11 @@ class ESSelectorLoanRequest extends Component {
13828
13847
  value: key,
13829
13848
  text: invenioConfig.CIRCULATION.deliveryMethods[key].text
13830
13849
  })) : [];
13831
- this.state['deliveryMethod'] = this.withDeliveryMethod ? this.deliveryMethods[1].value : null;
13850
+ this.defaultDeliveryMethod = null;
13851
+ if (this.withDeliveryMethod) {
13852
+ this.defaultDeliveryMethod = this.deliveryMethods.some(method => method.value === 'NOT-SPECIFIED') ? 'NOT-SPECIFIED' : this.deliveryMethods[0].value;
13853
+ }
13854
+ this.state['deliveryMethod'] = this.defaultDeliveryMethod;
13832
13855
  }
13833
13856
  render() {
13834
13857
  const {
@@ -15734,9 +15757,8 @@ class ExistingRelations extends Component {
15734
15757
  const {
15735
15758
  activePage
15736
15759
  } = this.state;
15737
- const activeRows = rows.slice((activePage - 1) * showMaxRows, activePage * showMaxRows);
15738
15760
  return /*#__PURE__*/React.createElement(ResultsTable, {
15739
- data: activeRows,
15761
+ data: rows,
15740
15762
  columns: columns,
15741
15763
  totalHitsCount: rows.length,
15742
15764
  showMaxRows: showMaxRows,
@@ -27240,16 +27262,18 @@ class LoanUpdateDates$1 extends Component {
27240
27262
  }), warning && this.renderWarning(warning), /*#__PURE__*/React.createElement(Form, null, /*#__PURE__*/React.createElement(Form.Group, null, /*#__PURE__*/React.createElement(Form.Field, {
27241
27263
  inline: true,
27242
27264
  required: true
27243
- }, /*#__PURE__*/React.createElement("label", null, startLabel), /*#__PURE__*/React.createElement(DatePicker$1, {
27265
+ }, /*#__PURE__*/React.createElement("label", null, startLabel), /*#__PURE__*/React.createElement(LocationDatePicker, {
27244
27266
  maxDate: active ? this.today() : null,
27245
27267
  defaultValue: active ? startDate : requestStartDate,
27268
+ locationPid: sessionManager.user.locationPid,
27246
27269
  placeholder: startLabel,
27247
27270
  handleDateChange: value => this.handleStartDateChange(value)
27248
27271
  })), /*#__PURE__*/React.createElement(Form.Field, {
27249
27272
  inline: true,
27250
27273
  required: true
27251
- }, /*#__PURE__*/React.createElement("label", null, endLabel), /*#__PURE__*/React.createElement(DatePicker$1, {
27274
+ }, /*#__PURE__*/React.createElement("label", null, endLabel), /*#__PURE__*/React.createElement(LocationDatePicker, {
27252
27275
  defaultValue: active ? endDate : requestExpireDate,
27276
+ locationPid: sessionManager.user.locationPid,
27253
27277
  placeholder: endLabel,
27254
27278
  handleDateChange: value => this.handleEndDateChange(value)
27255
27279
  }))), hint && this.renderHint(hint))), /*#__PURE__*/React.createElement(Modal.Actions, {
@@ -29387,7 +29411,7 @@ class PatronBulkExtendLoans$1 extends Component {
29387
29411
  patronPid,
29388
29412
  bulkLoanExtension,
29389
29413
  isLoading,
29390
- hidden,
29414
+ disabled,
29391
29415
  ...uiProps
29392
29416
  } = this.props;
29393
29417
  const {
@@ -29397,12 +29421,13 @@ class PatronBulkExtendLoans$1 extends Component {
29397
29421
  open: open,
29398
29422
  onClose: this.close,
29399
29423
  onOpen: this.open,
29400
- trigger: !hidden && /*#__PURE__*/React.createElement(Button, Object.assign({
29424
+ trigger: /*#__PURE__*/React.createElement(Button, Object.assign({
29401
29425
  labelPosition: "left",
29402
29426
  fluid: true,
29403
29427
  icon: true,
29404
29428
  primary: true,
29405
- loading: isLoading
29429
+ loading: isLoading,
29430
+ disabled: disabled
29406
29431
  }, uiProps), /*#__PURE__*/React.createElement(Icon, {
29407
29432
  name: "refresh"
29408
29433
  }), "Extend all loans")
@@ -29418,7 +29443,7 @@ class PatronBulkExtendLoans$1 extends Component {
29418
29443
  }
29419
29444
  PatronBulkExtendLoans$1.defaultProps = {
29420
29445
  isLoading: false,
29421
- hidden: true
29446
+ disabled: true
29422
29447
  };
29423
29448
 
29424
29449
  const IS_LOADING$l = 'fetchPatronCurrentLoans/IS_LOADING';
@@ -30951,7 +30976,7 @@ class PatronDetails$1 extends Component {
30951
30976
  offset: 150
30952
30977
  }, /*#__PURE__*/React.createElement(PatronBulkExtendLoans, {
30953
30978
  patronPid: currentPatronPid,
30954
- hidden: currentLoans.total === 0,
30979
+ disabled: currentLoans.total === 0,
30955
30980
  fluid: true,
30956
30981
  color: "blue"
30957
30982
  }), /*#__PURE__*/React.createElement(Divider, {
@@ -34646,7 +34671,7 @@ class BackOffice extends Component {
34646
34671
  } = this.props;
34647
34672
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Overridable, {
34648
34673
  id: "BackOffice.extras"
34649
- }, /*#__PURE__*/React.createElement(Banner, null)), /*#__PURE__*/React.createElement("div", {
34674
+ }, /*#__PURE__*/React.createElement(Banners, null)), /*#__PURE__*/React.createElement("div", {
34650
34675
  className: "backoffice"
34651
34676
  }, /*#__PURE__*/React.createElement("div", {
34652
34677
  className: "bo-sidebar"
@@ -35088,6 +35113,21 @@ class DocumentStats extends Component {
35088
35113
  class DocumentItem extends Component {
35089
35114
  constructor(props) {
35090
35115
  super(props);
35116
+ this.fetchIdentifiersToDisplayInFrontsideTitles = () => {
35117
+ const query = vocabularyApi.query().withType(invenioConfig.VOCABULARIES.item.identifier.scheme);
35118
+ vocabularyApi.list(query.qs()).then(response => {
35119
+ const identifiersToDisplayInFrontside = this.state.identifiersToDisplayInFrontside.map(identifier => {
35120
+ const vocabEntry = response.data.hits.find(entry => entry.metadata.key === identifier.key);
35121
+ return {
35122
+ ...identifier,
35123
+ text: vocabEntry ? vocabEntry.metadata.text : identifier.text
35124
+ };
35125
+ });
35126
+ this.setState({
35127
+ identifiersToDisplayInFrontside
35128
+ });
35129
+ });
35130
+ };
35091
35131
  this.toggleItems = () => {
35092
35132
  const {
35093
35133
  isShowingAll
@@ -35096,10 +35136,18 @@ class DocumentItem extends Component {
35096
35136
  isShowingAll: !isShowingAll
35097
35137
  });
35098
35138
  };
35139
+ const _identifiersToDisplayInFrontside = invenioConfig.ITEMS.identifiersToDisplayInFrontside.map(identifier => ({
35140
+ key: identifier,
35141
+ text: identifier
35142
+ }));
35099
35143
  this.state = {
35100
35144
  isShowingAll: false,
35101
- itemAmountLimit: 5
35145
+ itemAmountLimit: 5,
35146
+ identifiersToDisplayInFrontside: _identifiersToDisplayInFrontside
35102
35147
  };
35148
+ if (_identifiersToDisplayInFrontside.length > 0) {
35149
+ this.fetchIdentifiersToDisplayInFrontsideTitles();
35150
+ }
35103
35151
  }
35104
35152
  get moreItemsToLoad() {
35105
35153
  const {
@@ -35119,7 +35167,8 @@ class DocumentItem extends Component {
35119
35167
  } = this.props;
35120
35168
  const {
35121
35169
  isShowingAll,
35122
- itemAmountLimit
35170
+ itemAmountLimit,
35171
+ identifiersToDisplayInFrontside
35123
35172
  } = this.state;
35124
35173
  const previewArrayOfItems = items.slice(0, itemAmountLimit);
35125
35174
  const completeArrayOfItems = items;
@@ -35137,11 +35186,14 @@ class DocumentItem extends Component {
35137
35186
  id: "DocumentDetails.DocumentItem.TableHeader"
35138
35187
  }, /*#__PURE__*/React.createElement(Table.Row, {
35139
35188
  "data-test": "header"
35140
- }, /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Barcode"), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Shelf"), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Status"), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Medium"), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Loan restriction")))), /*#__PURE__*/React.createElement(Table.Body, null, /*#__PURE__*/React.createElement(Overridable, {
35189
+ }, /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Barcode"), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Shelf"), identifiersToDisplayInFrontside.map(identifier => /*#__PURE__*/React.createElement(Table.HeaderCell, {
35190
+ key: identifier.key
35191
+ }, identifier.text)), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Status"), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Medium"), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Loan restriction")))), /*#__PURE__*/React.createElement(Table.Body, null, /*#__PURE__*/React.createElement(Overridable, {
35141
35192
  id: "DocumentDetails.DocumentItemTableBody"
35142
35193
  }, /*#__PURE__*/React.createElement(DocumentItemBody, {
35143
35194
  items: itemsToShow,
35144
- documentDetails: documentDetails
35195
+ documentDetails: documentDetails,
35196
+ identifiersToDisplayInFrontside: identifiersToDisplayInFrontside
35145
35197
  }))), this.moreItemsToLoad && /*#__PURE__*/React.createElement(Table.Footer, {
35146
35198
  fullWidth: true,
35147
35199
  "data-test": "footer",
@@ -36468,7 +36520,7 @@ class LoanRequestForm$1 extends Component {
36468
36520
 
36469
36521
  // init delivery method
36470
36522
  this.withDeliveryMethod = !_isEmpty(invenioConfig.CIRCULATION.deliveryMethods);
36471
- this.deliveryMethods = this.withDeliveryMethod ? Object.keys(invenioConfig.CIRCULATION.deliveryMethods).map(key => ({
36523
+ this.deliveryMethods = this.withDeliveryMethod ? Object.keys(invenioConfig.CIRCULATION.deliveryMethods).filter(method => method !== 'NOT-SPECIFIED').map(key => ({
36472
36524
  key: key,
36473
36525
  value: key,
36474
36526
  text: invenioConfig.CIRCULATION.deliveryMethods[key].text
@@ -38965,7 +39017,7 @@ class PatronCurrentLoans$1 extends Component {
38965
39017
  floated: "right"
38966
39018
  }, /*#__PURE__*/React.createElement(PatronBulkExtendLoans, {
38967
39019
  patronPid: currentUser.id,
38968
- hidden: loans.total === 0,
39020
+ disabled: loans.total === 0,
38969
39021
  color: "orange"
38970
39022
  }))), /*#__PURE__*/React.createElement(ILSItemPlaceholder, {
38971
39023
  fluid: true,
@@ -40747,7 +40799,7 @@ class FrontSite extends Component {
40747
40799
  className: "fs-content"
40748
40800
  }, /*#__PURE__*/React.createElement(Overridable, {
40749
40801
  id: "FrontSite.extras"
40750
- }, /*#__PURE__*/React.createElement(Banner, null)), /*#__PURE__*/React.createElement(Switch, null, /*#__PURE__*/React.createElement(Route, {
40802
+ }, /*#__PURE__*/React.createElement(Banners, null)), /*#__PURE__*/React.createElement(Switch, null, /*#__PURE__*/React.createElement(Route, {
40751
40803
  exact: true,
40752
40804
  path: FrontSiteRoutes.home,
40753
40805
  render: props => /*#__PURE__*/React.createElement(Home$1, Object.assign({}, props, this.props))
@@ -40889,7 +40941,7 @@ const initialState$N = {
40889
40941
  data: {},
40890
40942
  error: {}
40891
40943
  };
40892
- const fetchBannerReducer = function () {
40944
+ const fetchBannersReducer = function () {
40893
40945
  let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState$N;
40894
40946
  let action = arguments.length > 1 ? arguments[1] : undefined;
40895
40947
  switch (action.type) {
@@ -43096,7 +43148,7 @@ function createILSReducer(asyncReducers) {
43096
43148
  borrowingRequestLoanExtension: borrowingRequestLoanExtensionReducer,
43097
43149
  itemsCheckIn: itemsCheckInReducer,
43098
43150
  checkOut: checkOutReducer,
43099
- banner: fetchBannerReducer,
43151
+ banners: fetchBannersReducer,
43100
43152
  bulkLoanExtend: patronBulkExtendLoans,
43101
43153
  ...asyncReducers
43102
43154
  });