@inveniosoftware/react-invenio-app-ils 2.1.0 → 2.2.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
@@ -697,7 +697,7 @@ const RECORDS_CONFIG = {
697
697
  }
698
698
  },
699
699
  ITEMS: {
700
- identifiersToDisplayInFrontside: [],
700
+ identifiersToDisplay: [],
701
701
  circulationRestrictions: [{
702
702
  value: 'NO_RESTRICTION',
703
703
  text: 'No restriction (4 weeks)'
@@ -4245,6 +4245,26 @@ const vocabularyApi = {
4245
4245
  serializer: serializer$1
4246
4246
  };
4247
4247
 
4248
+ /**
4249
+ * Resolves identifier scheme keys (e.g. "CALL_NUMBER") to their
4250
+ * human-readable titles from the vocabulary API.
4251
+ *
4252
+ * @param {Array<string>} identifiers
4253
+ * @param {string} identifierScheme
4254
+ * @returns {Promise<Array<{key: string, text: string}>>}
4255
+ */
4256
+ const fetchIdentifierTitles = async (identifiers, identifierScheme) => {
4257
+ const query = vocabularyApi.query().withType(identifierScheme);
4258
+ const response = await vocabularyApi.list(query.qs());
4259
+ return identifiers.map(scheme => {
4260
+ const vocabEntry = response.data.hits.find(entry => entry.metadata.key === scheme);
4261
+ return {
4262
+ key: scheme,
4263
+ text: vocabEntry ? vocabEntry.metadata.text : scheme
4264
+ };
4265
+ });
4266
+ };
4267
+
4248
4268
  class ScrollingMenuItem$1 extends Component {
4249
4269
  constructor(props) {
4250
4270
  super(props);
@@ -6190,32 +6210,36 @@ class DocumentItemBody extends Component {
6190
6210
  items,
6191
6211
  shelfLink,
6192
6212
  documentDetails,
6193
- identifiersToDisplayInFrontside
6194
- } = this.props;
6195
- return items.map(item => /*#__PURE__*/React.createElement(Table.Row, {
6196
- key: item.pid
6197
- }, /*#__PURE__*/React.createElement(Table.Cell, {
6198
- "data-label": "Barcode",
6199
- className: "document-item-table-itemCell"
6200
- }, item.barcode), /*#__PURE__*/React.createElement(Table.Cell, {
6201
- "data-label": "Shelf",
6202
- className: "document-item-table-itemCell"
6203
- }, shelfLink !== null ? shelfLink(item, documentDetails) : _get(item, 'shelf')), identifiersToDisplayInFrontside.map(identifier => {
6204
- var _item$identifiers, _item$identifiers$fin;
6205
- return /*#__PURE__*/React.createElement(Table.Cell, {
6206
- key: identifier,
6207
- "data-label": identifier.text,
6213
+ identifiersToDisplay
6214
+ } = this.props;
6215
+ return items.map(item => {
6216
+ const itemIsAccessible = !_get(item, 'internal_location.restricted');
6217
+ const shelfValue = shelfLink ? shelfLink(item, documentDetails) : _get(item, 'shelf');
6218
+ return /*#__PURE__*/React.createElement(Table.Row, {
6219
+ key: item.pid
6220
+ }, /*#__PURE__*/React.createElement(Table.Cell, {
6221
+ "data-label": "Barcode",
6222
+ className: "document-item-table-itemCell"
6223
+ }, item.barcode), /*#__PURE__*/React.createElement(Table.Cell, {
6224
+ "data-label": "Shelf",
6208
6225
  className: "document-item-table-itemCell"
6209
- }, (_item$identifiers = item.identifiers) === null || _item$identifiers === void 0 ? void 0 : (_item$identifiers$fin = _item$identifiers.find(entry => {
6210
- return entry.scheme === identifier.key;
6211
- })) === null || _item$identifiers$fin === void 0 ? void 0 : _item$identifiers$fin.value);
6212
- }), /*#__PURE__*/React.createElement(Table.Cell, {
6213
- "data-label": "Status"
6214
- }, this.statusLabel(item)), /*#__PURE__*/React.createElement(Table.Cell, {
6215
- "data-label": "Medium"
6216
- }, getDisplayVal('ITEMS.mediums', item.medium)), /*#__PURE__*/React.createElement(Table.Cell, {
6217
- "data-label": "Restrictions"
6218
- }, getDisplayVal('ITEMS.circulationRestrictions', item.circulation_restriction))));
6226
+ }, itemIsAccessible ? shelfValue : /*#__PURE__*/React.createElement("p", null, "Available on Request")), identifiersToDisplay.map(identifier => {
6227
+ var _item$identifiers, _item$identifiers$fin;
6228
+ return /*#__PURE__*/React.createElement(Table.Cell, {
6229
+ key: identifier,
6230
+ "data-label": identifier.text,
6231
+ className: "document-item-table-itemCell"
6232
+ }, itemIsAccessible && ((_item$identifiers = item.identifiers) === null || _item$identifiers === void 0 ? void 0 : (_item$identifiers$fin = _item$identifiers.find(entry => {
6233
+ return entry.scheme === identifier.key;
6234
+ })) === null || _item$identifiers$fin === void 0 ? void 0 : _item$identifiers$fin.value));
6235
+ }), /*#__PURE__*/React.createElement(Table.Cell, {
6236
+ "data-label": "Status"
6237
+ }, this.statusLabel(item)), /*#__PURE__*/React.createElement(Table.Cell, {
6238
+ "data-label": "Medium"
6239
+ }, getDisplayVal('ITEMS.mediums', item.medium)), /*#__PURE__*/React.createElement(Table.Cell, {
6240
+ "data-label": "Restrictions"
6241
+ }, getDisplayVal('ITEMS.circulationRestrictions', item.circulation_restriction)));
6242
+ });
6219
6243
  }
6220
6244
  }
6221
6245
  DocumentItemBody.defaultProps = {
@@ -27016,7 +27040,11 @@ class AvailableItems$1 extends Component {
27016
27040
  query: '',
27017
27041
  filteredData: null,
27018
27042
  modalOpen: false,
27019
- checkoutItem: null
27043
+ checkoutItem: null,
27044
+ identifiersToDisplay: invenioConfig.ITEMS.identifiersToDisplay.map(s => ({
27045
+ key: s,
27046
+ text: s
27047
+ }))
27020
27048
  };
27021
27049
  }
27022
27050
  componentDidMount() {
@@ -27025,6 +27053,25 @@ class AvailableItems$1 extends Component {
27025
27053
  loan
27026
27054
  } = this.props;
27027
27055
  fetchAvailableItems(loan.metadata.document_pid);
27056
+ this.loadIdentifierTitles();
27057
+ }
27058
+ componentWillUnmount() {
27059
+ if (this.cancellableFetchIdentifierTitles) {
27060
+ this.cancellableFetchIdentifierTitles.cancel();
27061
+ }
27062
+ }
27063
+ async loadIdentifierTitles() {
27064
+ this.cancellableFetchIdentifierTitles = withCancel(fetchIdentifierTitles(invenioConfig.ITEMS.identifiersToDisplay, invenioConfig.VOCABULARIES.item.identifier.scheme));
27065
+ try {
27066
+ let result = await this.cancellableFetchIdentifierTitles.promise;
27067
+ this.setState({
27068
+ identifiersToDisplay: result
27069
+ });
27070
+ } catch (error) {
27071
+ if (error !== 'UNMOUNTED') {
27072
+ console.error('Error fetching identifier titles for items.', error);
27073
+ }
27074
+ }
27028
27075
  }
27029
27076
  assignItemButton(item) {
27030
27077
  const {
@@ -27095,18 +27142,31 @@ class AvailableItems$1 extends Component {
27095
27142
  data
27096
27143
  } = this.props;
27097
27144
  const {
27098
- filteredData
27145
+ filteredData,
27146
+ identifiersToDisplay
27099
27147
  } = this.state;
27148
+ const identifierColumns = identifiersToDisplay.map(identifier => ({
27149
+ title: identifier.text,
27150
+ field: `metadata.identifiers`,
27151
+ formatter: _ref2 => {
27152
+ var _row$metadata$identif;
27153
+ let {
27154
+ row
27155
+ } = _ref2;
27156
+ const entry = (_row$metadata$identif = row.metadata.identifiers) === null || _row$metadata$identif === void 0 ? void 0 : _row$metadata$identif.find(id => id.scheme === identifier.key);
27157
+ return entry === null || entry === void 0 ? void 0 : entry.value;
27158
+ }
27159
+ }));
27100
27160
  const columns = [{
27101
27161
  title: 'PID',
27102
27162
  field: 'metadata.pid'
27103
27163
  }, {
27104
27164
  title: 'Barcode',
27105
27165
  field: 'metadata.barcode',
27106
- formatter: _ref2 => {
27166
+ formatter: _ref3 => {
27107
27167
  let {
27108
27168
  row
27109
- } = _ref2;
27169
+ } = _ref3;
27110
27170
  return /*#__PURE__*/React.createElement(Link$1, {
27111
27171
  to: BackOfficeRoutes.itemDetailsFor(row.metadata.pid)
27112
27172
  }, row.metadata.barcode);
@@ -27123,7 +27183,7 @@ class AvailableItems$1 extends Component {
27123
27183
  }, {
27124
27184
  title: 'Shelf',
27125
27185
  field: 'metadata.shelf'
27126
- }, {
27186
+ }, ...identifierColumns, {
27127
27187
  title: 'Actions',
27128
27188
  field: '',
27129
27189
  formatter: this.rowActionButton
@@ -28112,15 +28172,20 @@ const LoanDetails = connect(mapStateToProps$K, mapDispatchToProps$z)(LoanDetails
28112
28172
  class _SearchDateRange extends Component {
28113
28173
  constructor() {
28114
28174
  super(...arguments);
28115
- this.onDateChange = newFilter => {
28175
+ this.onDateChange = (field, value) => {
28116
28176
  const {
28117
28177
  currentQueryState,
28118
28178
  updateQueryState
28119
28179
  } = this.props;
28120
- const filters = currentQueryState.filters;
28121
- filters.push(newFilter);
28180
+ const updatedFilters = currentQueryState.filters.filter(_ref => {
28181
+ let [name] = _ref;
28182
+ return name !== field;
28183
+ });
28184
+ if (value !== '') {
28185
+ updatedFilters.push([field, value]);
28186
+ }
28122
28187
  return updateQueryState({
28123
- filters: filters
28188
+ filters: updatedFilters
28124
28189
  });
28125
28190
  };
28126
28191
  }
@@ -28132,8 +28197,8 @@ class _SearchDateRange extends Component {
28132
28197
  } = this.props;
28133
28198
  let fromDate = '';
28134
28199
  let toDate = '';
28135
- filters.forEach(_ref => {
28136
- let [name, value] = _ref;
28200
+ filters.forEach(_ref2 => {
28201
+ let [name, value] = _ref2;
28137
28202
  if (name === 'loans_from_date') fromDate = value;
28138
28203
  if (name === 'loans_to_date') toDate = value;
28139
28204
  });
@@ -28145,12 +28210,12 @@ class _SearchDateRange extends Component {
28145
28210
  maxDate: toDate,
28146
28211
  defaultValue: fromDate,
28147
28212
  placeholder: "From",
28148
- handleDateChange: value => this.onDateChange(['loans_from_date', value])
28213
+ handleDateChange: value => this.onDateChange('loans_from_date', value)
28149
28214
  })), /*#__PURE__*/React.createElement(Card.Content, null, /*#__PURE__*/React.createElement(DatePicker$1, {
28150
28215
  minDate: fromDate,
28151
28216
  defaultValue: toDate,
28152
28217
  placeholder: "To",
28153
- handleDateChange: value => this.onDateChange(['loans_to_date', value])
28218
+ handleDateChange: value => this.onDateChange('loans_to_date', value)
28154
28219
  })));
28155
28220
  }
28156
28221
  }
@@ -28261,6 +28326,11 @@ const schema$3 = () => {
28261
28326
  physical_location: {
28262
28327
  type: 'string',
28263
28328
  title: 'Physical location'
28329
+ },
28330
+ restricted: {
28331
+ type: 'boolean',
28332
+ title: 'Restricted access (not accessible to patrons)',
28333
+ default: false
28264
28334
  }
28265
28335
  }
28266
28336
  };
@@ -28281,6 +28351,8 @@ const uiSchema$3 = title => {
28281
28351
  }, {
28282
28352
  physical_location: 8,
28283
28353
  notes: 8
28354
+ }, {
28355
+ restricted: 8
28284
28356
  }],
28285
28357
  'custom:root': {
28286
28358
  'custom:formTitle': title
@@ -29350,6 +29422,16 @@ class InternalLocationList$1 extends Component {
29350
29422
  }, {
29351
29423
  title: 'Location e-mail',
29352
29424
  field: 'metadata.location.email'
29425
+ }, {
29426
+ title: 'Restricted access',
29427
+ formatter: _ref2 => {
29428
+ let {
29429
+ row
29430
+ } = _ref2;
29431
+ return row.metadata.restricted ? /*#__PURE__*/React.createElement("i", {
29432
+ className: "check icon"
29433
+ }) : null;
29434
+ }
29353
29435
  }, {
29354
29436
  title: 'Actions',
29355
29437
  field: '',
@@ -35386,21 +35468,6 @@ class DocumentStats extends Component {
35386
35468
  class DocumentItem extends Component {
35387
35469
  constructor(props) {
35388
35470
  super(props);
35389
- this.fetchIdentifiersToDisplayInFrontsideTitles = () => {
35390
- const query = vocabularyApi.query().withType(invenioConfig.VOCABULARIES.item.identifier.scheme);
35391
- vocabularyApi.list(query.qs()).then(response => {
35392
- const identifiersToDisplayInFrontside = this.state.identifiersToDisplayInFrontside.map(identifier => {
35393
- const vocabEntry = response.data.hits.find(entry => entry.metadata.key === identifier.key);
35394
- return {
35395
- ...identifier,
35396
- text: vocabEntry ? vocabEntry.metadata.text : identifier.text
35397
- };
35398
- });
35399
- this.setState({
35400
- identifiersToDisplayInFrontside
35401
- });
35402
- });
35403
- };
35404
35471
  this.toggleItems = () => {
35405
35472
  const {
35406
35473
  isShowingAll
@@ -35409,18 +35476,10 @@ class DocumentItem extends Component {
35409
35476
  isShowingAll: !isShowingAll
35410
35477
  });
35411
35478
  };
35412
- const _identifiersToDisplayInFrontside = invenioConfig.ITEMS.identifiersToDisplayInFrontside.map(identifier => ({
35413
- key: identifier,
35414
- text: identifier
35415
- }));
35416
35479
  this.state = {
35417
35480
  isShowingAll: false,
35418
- itemAmountLimit: 5,
35419
- identifiersToDisplayInFrontside: _identifiersToDisplayInFrontside
35481
+ itemAmountLimit: 5
35420
35482
  };
35421
- if (_identifiersToDisplayInFrontside.length > 0) {
35422
- this.fetchIdentifiersToDisplayInFrontsideTitles();
35423
- }
35424
35483
  }
35425
35484
  get moreItemsToLoad() {
35426
35485
  const {
@@ -35436,12 +35495,12 @@ class DocumentItem extends Component {
35436
35495
  internalLocationName,
35437
35496
  items,
35438
35497
  documentDetails,
35439
- showTitle
35498
+ showTitle,
35499
+ identifiersToDisplay
35440
35500
  } = this.props;
35441
35501
  const {
35442
35502
  isShowingAll,
35443
- itemAmountLimit,
35444
- identifiersToDisplayInFrontside
35503
+ itemAmountLimit
35445
35504
  } = this.state;
35446
35505
  const previewArrayOfItems = items.slice(0, itemAmountLimit);
35447
35506
  const completeArrayOfItems = items;
@@ -35459,14 +35518,14 @@ class DocumentItem extends Component {
35459
35518
  id: "DocumentDetails.DocumentItem.TableHeader"
35460
35519
  }, /*#__PURE__*/React.createElement(Table.Row, {
35461
35520
  "data-test": "header"
35462
- }, /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Barcode"), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Shelf"), identifiersToDisplayInFrontside.map(identifier => /*#__PURE__*/React.createElement(Table.HeaderCell, {
35521
+ }, /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Barcode"), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Shelf"), identifiersToDisplay.map(identifier => /*#__PURE__*/React.createElement(Table.HeaderCell, {
35463
35522
  key: identifier.key
35464
35523
  }, 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, {
35465
35524
  id: "DocumentDetails.DocumentItemTableBody"
35466
35525
  }, /*#__PURE__*/React.createElement(DocumentItemBody, {
35467
35526
  items: itemsToShow,
35468
35527
  documentDetails: documentDetails,
35469
- identifiersToDisplayInFrontside: identifiersToDisplayInFrontside
35528
+ identifiersToDisplay: identifiersToDisplay
35470
35529
  }))), this.moreItemsToLoad && /*#__PURE__*/React.createElement(Table.Footer, {
35471
35530
  fullWidth: true,
35472
35531
  "data-test": "footer",
@@ -35558,7 +35617,8 @@ class DocumentTabs extends Component {
35558
35617
  };
35559
35618
  this.createInternalLocationTables = locationsObject => {
35560
35619
  const {
35561
- activeInternalLocation
35620
+ activeInternalLocation,
35621
+ identifiersToDisplay
35562
35622
  } = this.state;
35563
35623
  const sortedInternalLocationEntries = this.sortedLocationEntries(Object.entries(locationsObject));
35564
35624
  if (activeInternalLocation) {
@@ -35572,7 +35632,8 @@ class DocumentTabs extends Component {
35572
35632
  internalLocationName: internalLocationName,
35573
35633
  items: items,
35574
35634
  documentDetails: this.documentDetails,
35575
- showTitle: activeInternalLocation !== internalLocationName
35635
+ showTitle: activeInternalLocation !== internalLocationName,
35636
+ identifiersToDisplay: identifiersToDisplay
35576
35637
  });
35577
35638
  }
35578
35639
  return sortedInternalLocationEntries.map(_ref6 => {
@@ -35583,7 +35644,8 @@ class DocumentTabs extends Component {
35583
35644
  internalLocationName: internalLocationName,
35584
35645
  items: items,
35585
35646
  documentDetails: this.documentDetails,
35586
- showTitle: activeInternalLocation !== internalLocationName
35647
+ showTitle: activeInternalLocation !== internalLocationName,
35648
+ identifiersToDisplay: identifiersToDisplay
35587
35649
  });
35588
35650
  });
35589
35651
  };
@@ -35607,9 +35669,34 @@ class DocumentTabs extends Component {
35607
35669
  const [firstLocationName] = this.locationEntries[0];
35608
35670
  const [_firstInternalLocationName] = this.firstInternalLocationEntry(firstLocationName);
35609
35671
  this.state = {
35610
- activeInternalLocation: _firstInternalLocationName
35672
+ activeInternalLocation: _firstInternalLocationName,
35673
+ identifiersToDisplay: invenioConfig.ITEMS.identifiersToDisplay.map(s => ({
35674
+ key: s,
35675
+ text: s
35676
+ }))
35611
35677
  };
35612
35678
  }
35679
+ componentDidMount() {
35680
+ this.loadIdentifierTitles();
35681
+ }
35682
+ componentWillUnmount() {
35683
+ if (this.cancellableFetchIdentifierTitles) {
35684
+ this.cancellableFetchIdentifierTitles.cancel();
35685
+ }
35686
+ }
35687
+ async loadIdentifierTitles() {
35688
+ this.cancellableFetchIdentifierTitles = withCancel(fetchIdentifierTitles(invenioConfig.ITEMS.identifiersToDisplay, invenioConfig.VOCABULARIES.item.identifier.scheme));
35689
+ try {
35690
+ let result = await this.cancellableFetchIdentifierTitles.promise;
35691
+ this.setState({
35692
+ identifiersToDisplay: result
35693
+ });
35694
+ } catch (error) {
35695
+ if (error !== 'UNMOUNTED') {
35696
+ console.error('Error fetching identifier titles for items.', error);
35697
+ }
35698
+ }
35699
+ }
35613
35700
  get locations() {
35614
35701
  const {
35615
35702
  locationsObject