@inveniosoftware/react-invenio-app-ils 1.2.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/esm/index.js CHANGED
@@ -2414,7 +2414,7 @@ const serializer$9 = {
2414
2414
  };
2415
2415
 
2416
2416
  const documentRequestURL = '/document-requests/';
2417
- const apiPaths$2 = {
2417
+ const apiPaths$3 = {
2418
2418
  accept: `${documentRequestURL}:docReqPid/accept`,
2419
2419
  item: `${documentRequestURL}:docReqPid`,
2420
2420
  list: documentRequestURL,
@@ -2423,12 +2423,12 @@ const apiPaths$2 = {
2423
2423
  provider: `${documentRequestURL}:docReqPid/provider`
2424
2424
  };
2425
2425
  const create$8 = async data => {
2426
- const response = await http.post(apiPaths$2.list, data);
2426
+ const response = await http.post(apiPaths$3.list, data);
2427
2427
  response.data = serializer$9.fromJSON(response.data);
2428
2428
  return response;
2429
2429
  };
2430
2430
  const update$8 = async (docRequestPid, data) => {
2431
- const path = generatePath(apiPaths$2.item, {
2431
+ const path = generatePath(apiPaths$3.item, {
2432
2432
  docReqPid: docRequestPid
2433
2433
  });
2434
2434
  const response = await http.put(path, data);
@@ -2436,7 +2436,7 @@ const update$8 = async (docRequestPid, data) => {
2436
2436
  return response;
2437
2437
  };
2438
2438
  const get$c = async docRequestPid => {
2439
- const path = generatePath(apiPaths$2.item, {
2439
+ const path = generatePath(apiPaths$3.item, {
2440
2440
  docReqPid: docRequestPid
2441
2441
  });
2442
2442
  const response = await http.get(path);
@@ -2444,7 +2444,7 @@ const get$c = async docRequestPid => {
2444
2444
  return response;
2445
2445
  };
2446
2446
  const del$8 = async docRequestPid => {
2447
- const path = generatePath(apiPaths$2.item, {
2447
+ const path = generatePath(apiPaths$3.item, {
2448
2448
  docReqPid: docRequestPid
2449
2449
  });
2450
2450
  const response = await http.delete(path);
@@ -2456,19 +2456,19 @@ const performAction = async (urlPath, data) => {
2456
2456
  return response;
2457
2457
  };
2458
2458
  const accept = async docRequestPid => {
2459
- const urlPath = generatePath(apiPaths$2.accept, {
2459
+ const urlPath = generatePath(apiPaths$3.accept, {
2460
2460
  docReqPid: docRequestPid
2461
2461
  });
2462
2462
  return performAction(urlPath);
2463
2463
  };
2464
2464
  const addDocument$1 = async (docReqPid, data) => {
2465
- const url = generatePath(apiPaths$2.document, {
2465
+ const url = generatePath(apiPaths$3.document, {
2466
2466
  docReqPid: docReqPid
2467
2467
  });
2468
2468
  return await http.post(url, data);
2469
2469
  };
2470
2470
  const removeDocument$1 = async (docReqPid, data) => {
2471
- const url = generatePath(apiPaths$2.document, {
2471
+ const url = generatePath(apiPaths$3.document, {
2472
2472
  docReqPid: docReqPid
2473
2473
  });
2474
2474
  // https://github.com/axios/axios/issues/897#issuecomment-343715381
@@ -2477,19 +2477,19 @@ const removeDocument$1 = async (docReqPid, data) => {
2477
2477
  });
2478
2478
  };
2479
2479
  const addProvider$1 = async (docReqPid, data) => {
2480
- const url = generatePath(apiPaths$2.provider, {
2480
+ const url = generatePath(apiPaths$3.provider, {
2481
2481
  docReqPid: docReqPid
2482
2482
  });
2483
2483
  return await http.post(url, data);
2484
2484
  };
2485
2485
  const removeProvider$1 = async docReqPid => {
2486
- const url = generatePath(apiPaths$2.provider, {
2486
+ const url = generatePath(apiPaths$3.provider, {
2487
2487
  docReqPid: docReqPid
2488
2488
  });
2489
2489
  return await http.delete(url);
2490
2490
  };
2491
2491
  const decline = async (docRequestPid, data) => {
2492
- const urlPath = generatePath(apiPaths$2.decline, {
2492
+ const urlPath = generatePath(apiPaths$3.decline, {
2493
2493
  docReqPid: docRequestPid
2494
2494
  });
2495
2495
  return performAction(urlPath, data);
@@ -3409,7 +3409,7 @@ const serializer$4 = {
3409
3409
  fromJSON: serializeResponse$3
3410
3410
  };
3411
3411
 
3412
- const apiPaths$1 = {
3412
+ const apiPaths$2 = {
3413
3413
  checkout: '/circulation/loans/checkout',
3414
3414
  selfCheckout: '/circulation/loans/self-checkout',
3415
3415
  notificationOverdue: '/circulation/loans/:loanPid/notification-overdue',
@@ -3421,7 +3421,7 @@ const apiPaths$1 = {
3421
3421
  bulkExtend: '/circulation/bulk-extend'
3422
3422
  };
3423
3423
  const get$7 = async loanPid => {
3424
- const path = generatePath(apiPaths$1.item, {
3424
+ const path = generatePath(apiPaths$2.item, {
3425
3425
  loanPid: loanPid
3426
3426
  });
3427
3427
  const response = await http.get(path);
@@ -3474,7 +3474,7 @@ const doRequest = async function (documentPid, patronPid) {
3474
3474
  method: deliveryMethod
3475
3475
  };
3476
3476
  }
3477
- const response = await http.post(apiPaths$1.request, payload);
3477
+ const response = await http.post(apiPaths$2.request, payload);
3478
3478
  response.data = serializer$4.fromJSON(response.data);
3479
3479
  return response;
3480
3480
  };
@@ -3501,12 +3501,12 @@ const doCheckout = async function (documentPid, itemPid, patronPid) {
3501
3501
  if (force) {
3502
3502
  payload.force = true;
3503
3503
  }
3504
- const response = await http.post(apiPaths$1.checkout, payload);
3504
+ const response = await http.post(apiPaths$2.checkout, payload);
3505
3505
  response.data = serializer$4.fromJSON(response.data);
3506
3506
  return response;
3507
3507
  };
3508
3508
  const doSelfCheckoutSearchItem = async barcode => {
3509
- const response = await http.get(`${apiPaths$1.selfCheckout}?barcode=${barcode}`);
3509
+ const response = await http.get(`${apiPaths$2.selfCheckout}?barcode=${barcode}`);
3510
3510
  response.data = serializer$4.fromJSON(response.data);
3511
3511
  return response;
3512
3512
  };
@@ -3519,12 +3519,12 @@ const doSelfCheckout = async (documentPid, itemPid, patronPid) => {
3519
3519
  transaction_location_pid: `${currentUser.locationPid}`,
3520
3520
  transaction_user_pid: `${currentUser.id}`
3521
3521
  };
3522
- const response = await http.post(apiPaths$1.selfCheckout, payload);
3522
+ const response = await http.post(apiPaths$2.selfCheckout, payload);
3523
3523
  response.data = serializer$4.fromJSON(response.data);
3524
3524
  return response;
3525
3525
  };
3526
3526
  const assignItemToLoan$1 = async (itemPid, loanPid) => {
3527
- const path = generatePath(apiPaths$1.replaceItem, {
3527
+ const path = generatePath(apiPaths$2.replaceItem, {
3528
3528
  loanPid: loanPid
3529
3529
  });
3530
3530
  const payload = {
@@ -3538,7 +3538,7 @@ const bulkExtendLoans = async patronPid => {
3538
3538
  const payload = {
3539
3539
  patron_pid: patronPid
3540
3540
  };
3541
- const response = await http.post(apiPaths$1.bulkExtend, payload);
3541
+ const response = await http.post(apiPaths$2.bulkExtend, payload);
3542
3542
  return response;
3543
3543
  };
3544
3544
  class QueryBuilder$4 {
@@ -3652,19 +3652,19 @@ const queryBuilder$4 = () => {
3652
3652
  return new QueryBuilder$4();
3653
3653
  };
3654
3654
  const list$7 = async query => {
3655
- const response = await http.get(`${apiPaths$1.list}?q=${query}`);
3655
+ const response = await http.get(`${apiPaths$2.list}?q=${query}`);
3656
3656
  response.data.total = getSearchTotal(response.data.hits);
3657
3657
  response.data.hits = response.data.hits.hits.map(hit => serializer$4.fromJSON(hit));
3658
3658
  return response;
3659
3659
  };
3660
3660
  const sendOverdueLoansNotificationReminder$1 = async payload => {
3661
- const path = generatePath(apiPaths$1.notificationOverdue, {
3661
+ const path = generatePath(apiPaths$2.notificationOverdue, {
3662
3662
  loanPid: payload.loanPid
3663
3663
  });
3664
3664
  return await http.post(path, payload);
3665
3665
  };
3666
3666
  const count$2 = async query => {
3667
- const response = await http.get(`${apiPaths$1.list}?q=${query}`);
3667
+ const response = await http.get(`${apiPaths$2.list}?q=${query}`);
3668
3668
  response.data = getSearchTotal(response.data.hits);
3669
3669
  return response;
3670
3670
  };
@@ -3688,13 +3688,13 @@ const updateDates = async function (loanPid) {
3688
3688
  if (requestExpireDate) {
3689
3689
  payload.request_expire_date = requestExpireDate;
3690
3690
  }
3691
- const path = generatePath(apiPaths$1.updateDates, {
3691
+ const path = generatePath(apiPaths$2.updateDates, {
3692
3692
  loanPid: loanPid
3693
3693
  });
3694
3694
  return await http.post(path, payload);
3695
3695
  };
3696
3696
  const loanApi = {
3697
- searchBaseURL: `${apiConfig.baseURL}${apiPaths$1.list}`,
3697
+ searchBaseURL: `${apiConfig.baseURL}${apiPaths$2.list}`,
3698
3698
  assignItemToLoan: assignItemToLoan$1,
3699
3699
  query: queryBuilder$4,
3700
3700
  list: list$7,
@@ -3743,12 +3743,25 @@ function serializeLocationResponse(hit) {
3743
3743
  }
3744
3744
  return result;
3745
3745
  }
3746
+ function serializeLocationClosurePeriodsResponse(hit) {
3747
+ let result = [];
3748
+ if (!_isEmpty(hit)) {
3749
+ result = hit.closure_periods.map(period => ({
3750
+ start: new DateTime.fromISO(period.start),
3751
+ end: new DateTime.fromISO(period.end)
3752
+ }));
3753
+ }
3754
+ return result;
3755
+ }
3746
3756
  const internalLocationSerializer = {
3747
3757
  fromJSON: serializeInternalLocationResponse
3748
3758
  };
3749
3759
  const locationSerializer = {
3750
3760
  fromJSON: serializeLocationResponse
3751
3761
  };
3762
+ const locationClosurePeriodsSerializer = {
3763
+ fromJSON: serializeLocationClosurePeriodsResponse
3764
+ };
3752
3765
 
3753
3766
  const internalLocationURL = '/internal-locations/';
3754
3767
  const get$6 = async internalLocationPid => {
@@ -3789,6 +3802,9 @@ const internalLocationApi = {
3789
3802
  };
3790
3803
 
3791
3804
  const locationURL = '/locations/';
3805
+ const apiPaths$1 = {
3806
+ closure_periods: `/closure_periods/`
3807
+ };
3792
3808
  const get$5 = async locationPid => {
3793
3809
  const response = await http.get(`${locationURL}${locationPid}`);
3794
3810
  response.data = locationSerializer.fromJSON(response.data);
@@ -3815,13 +3831,19 @@ const list$5 = async function () {
3815
3831
  response.data.hits = response.data.hits.hits.map(hit => locationSerializer.fromJSON(hit));
3816
3832
  return response;
3817
3833
  };
3834
+ const getClosurePeriods = async (locationPid, year) => {
3835
+ const response = await http.get(`${locationURL}${locationPid}${apiPaths$1.closure_periods}${year}`);
3836
+ response.data = locationClosurePeriodsSerializer.fromJSON(response.data);
3837
+ return response;
3838
+ };
3818
3839
  const locationApi = {
3819
3840
  list: list$5,
3820
3841
  get: get$5,
3821
3842
  delete: del$2,
3822
3843
  create: create$2,
3823
3844
  update: update$2,
3824
- url: locationURL
3845
+ url: locationURL,
3846
+ getClosurePeriods: getClosurePeriods
3825
3847
  };
3826
3848
 
3827
3849
  function serializeResponse$2(hit) {
@@ -13123,102 +13145,70 @@ var DatePicker$1 = Overridable.component('DatePicker', DatePicker);
13123
13145
  class LocationDatePicker extends Component {
13124
13146
  constructor(props) {
13125
13147
  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) {
13148
+ this.fetchData = () => {
13149
+ this.fetchLocationClosurePeriods();
13150
+ };
13151
+ this.fetchLocationClosurePeriods = async () => {
13152
+ const {
13153
+ locationPid
13154
+ } = this.props;
13155
+ if (!locationPid) {
13138
13156
  this.setState({
13139
13157
  isLoading: false,
13140
- error: error
13158
+ disabledDates: [],
13159
+ error: {
13160
+ message: 'Location PID is missing.'
13161
+ }
13141
13162
  });
13163
+ return;
13142
13164
  }
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
13165
+ this.setState({
13166
+ isLoading: true,
13167
+ error: null
13168
+ });
13169
+ const currentYear = DateTime.now().year;
13170
+ const yearsToFetch = [currentYear - 1, currentYear, currentYear + 1];
13171
+ try {
13172
+ const promises = yearsToFetch.map(year => {
13173
+ const cancellable = withCancel(locationApi.getClosurePeriods(locationPid, year));
13174
+ this.cancellableFetches.push(cancellable);
13175
+ return cancellable.promise;
13152
13176
  });
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;
13177
+ const responses = await Promise.all(promises);
13178
+ const disabledDateRanges = responses.flatMap(response => response.data);
13179
+ const disabledDates = disabledDateRanges.flatMap(dateRange => {
13180
+ const dates = [];
13181
+ let currentDate = DateTime.fromISO(dateRange.start);
13182
+ const endDate = DateTime.fromISO(dateRange.end);
13183
+ while (currentDate <= endDate) {
13184
+ dates.push(currentDate.toISODate());
13185
+ currentDate = currentDate.plus({
13186
+ days: 1
13187
+ });
13166
13188
  }
13189
+ return dates;
13167
13190
  });
13168
- if (!isOpen) {
13169
- disabled.push(dateISO);
13170
- }
13171
- date = date.plus({
13172
- days: 1
13191
+ this.setState({
13192
+ disabledDates: disabledDates,
13193
+ isLoading: false
13173
13194
  });
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
13195
+ } catch (fetchError) {
13196
+ console.error('LocationDatePicker: Failed to fetch closure periods.', fetchError);
13197
+ this.setState({
13198
+ isLoading: false,
13199
+ error: fetchError
13190
13200
  });
13191
13201
  }
13192
13202
  };
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
13203
  this.state = {
13218
- data: {},
13204
+ disabledDates: [],
13219
13205
  isLoading: false,
13220
- error: {}
13206
+ error: null
13221
13207
  };
13208
+ this.cancellableFetches = [];
13209
+ }
13210
+ componentWillUnmount() {
13211
+ this.cancellableFetches.forEach(cancellable => cancellable.cancel());
13222
13212
  }
13223
13213
  render() {
13224
13214
  const {
@@ -13230,12 +13220,18 @@ class LocationDatePicker extends Component {
13230
13220
  ...otherProps
13231
13221
  } = this.props;
13232
13222
  const {
13233
- isLoading
13223
+ disabledDates,
13224
+ isLoading,
13225
+ error
13234
13226
  } = this.state;
13227
+ if (error) {
13228
+ console.error(error);
13229
+ return null;
13230
+ }
13235
13231
  return /*#__PURE__*/React.createElement(DatePicker$1, Object.assign({}, otherProps, {
13236
13232
  minDate: minDate,
13237
13233
  maxDate: maxDate,
13238
- disable: this.listDisabled(),
13234
+ disable: disabledDates,
13239
13235
  handleDateChange: handleDateChange,
13240
13236
  loading: isLoading,
13241
13237
  fetchData: this.fetchData,
@@ -13247,7 +13243,9 @@ class LocationDatePicker extends Component {
13247
13243
  }
13248
13244
  LocationDatePicker.defaultProps = {
13249
13245
  defaultValue: '',
13250
- locationPid: null
13246
+ locationPid: null,
13247
+ minDate: null,
13248
+ maxDate: null
13251
13249
  };
13252
13250
 
13253
13251
  const serializeError = error => ({
@@ -15734,9 +15732,8 @@ class ExistingRelations extends Component {
15734
15732
  const {
15735
15733
  activePage
15736
15734
  } = this.state;
15737
- const activeRows = rows.slice((activePage - 1) * showMaxRows, activePage * showMaxRows);
15738
15735
  return /*#__PURE__*/React.createElement(ResultsTable, {
15739
- data: activeRows,
15736
+ data: rows,
15740
15737
  columns: columns,
15741
15738
  totalHitsCount: rows.length,
15742
15739
  showMaxRows: showMaxRows,
@@ -27240,16 +27237,18 @@ class LoanUpdateDates$1 extends Component {
27240
27237
  }), warning && this.renderWarning(warning), /*#__PURE__*/React.createElement(Form, null, /*#__PURE__*/React.createElement(Form.Group, null, /*#__PURE__*/React.createElement(Form.Field, {
27241
27238
  inline: true,
27242
27239
  required: true
27243
- }, /*#__PURE__*/React.createElement("label", null, startLabel), /*#__PURE__*/React.createElement(DatePicker$1, {
27240
+ }, /*#__PURE__*/React.createElement("label", null, startLabel), /*#__PURE__*/React.createElement(LocationDatePicker, {
27244
27241
  maxDate: active ? this.today() : null,
27245
27242
  defaultValue: active ? startDate : requestStartDate,
27243
+ locationPid: sessionManager.user.locationPid,
27246
27244
  placeholder: startLabel,
27247
27245
  handleDateChange: value => this.handleStartDateChange(value)
27248
27246
  })), /*#__PURE__*/React.createElement(Form.Field, {
27249
27247
  inline: true,
27250
27248
  required: true
27251
- }, /*#__PURE__*/React.createElement("label", null, endLabel), /*#__PURE__*/React.createElement(DatePicker$1, {
27249
+ }, /*#__PURE__*/React.createElement("label", null, endLabel), /*#__PURE__*/React.createElement(LocationDatePicker, {
27252
27250
  defaultValue: active ? endDate : requestExpireDate,
27251
+ locationPid: sessionManager.user.locationPid,
27253
27252
  placeholder: endLabel,
27254
27253
  handleDateChange: value => this.handleEndDateChange(value)
27255
27254
  }))), hint && this.renderHint(hint))), /*#__PURE__*/React.createElement(Modal.Actions, {
@@ -29387,7 +29386,7 @@ class PatronBulkExtendLoans$1 extends Component {
29387
29386
  patronPid,
29388
29387
  bulkLoanExtension,
29389
29388
  isLoading,
29390
- hidden,
29389
+ disabled,
29391
29390
  ...uiProps
29392
29391
  } = this.props;
29393
29392
  const {
@@ -29397,12 +29396,13 @@ class PatronBulkExtendLoans$1 extends Component {
29397
29396
  open: open,
29398
29397
  onClose: this.close,
29399
29398
  onOpen: this.open,
29400
- trigger: !hidden && /*#__PURE__*/React.createElement(Button, Object.assign({
29399
+ trigger: /*#__PURE__*/React.createElement(Button, Object.assign({
29401
29400
  labelPosition: "left",
29402
29401
  fluid: true,
29403
29402
  icon: true,
29404
29403
  primary: true,
29405
- loading: isLoading
29404
+ loading: isLoading,
29405
+ disabled: disabled
29406
29406
  }, uiProps), /*#__PURE__*/React.createElement(Icon, {
29407
29407
  name: "refresh"
29408
29408
  }), "Extend all loans")
@@ -29418,7 +29418,7 @@ class PatronBulkExtendLoans$1 extends Component {
29418
29418
  }
29419
29419
  PatronBulkExtendLoans$1.defaultProps = {
29420
29420
  isLoading: false,
29421
- hidden: true
29421
+ disabled: true
29422
29422
  };
29423
29423
 
29424
29424
  const IS_LOADING$l = 'fetchPatronCurrentLoans/IS_LOADING';
@@ -30951,7 +30951,7 @@ class PatronDetails$1 extends Component {
30951
30951
  offset: 150
30952
30952
  }, /*#__PURE__*/React.createElement(PatronBulkExtendLoans, {
30953
30953
  patronPid: currentPatronPid,
30954
- hidden: currentLoans.total === 0,
30954
+ disabled: currentLoans.total === 0,
30955
30955
  fluid: true,
30956
30956
  color: "blue"
30957
30957
  }), /*#__PURE__*/React.createElement(Divider, {
@@ -38965,7 +38965,7 @@ class PatronCurrentLoans$1 extends Component {
38965
38965
  floated: "right"
38966
38966
  }, /*#__PURE__*/React.createElement(PatronBulkExtendLoans, {
38967
38967
  patronPid: currentUser.id,
38968
- hidden: loans.total === 0,
38968
+ disabled: loans.total === 0,
38969
38969
  color: "orange"
38970
38970
  }))), /*#__PURE__*/React.createElement(ILSItemPlaceholder, {
38971
38971
  fluid: true,