@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/cjs/index.js CHANGED
@@ -739,7 +739,7 @@ const RECORDS_CONFIG = {
739
739
  }
740
740
  },
741
741
  ITEMS: {
742
- identifiersToDisplayInFrontside: [],
742
+ identifiersToDisplay: [],
743
743
  circulationRestrictions: [{
744
744
  value: 'NO_RESTRICTION',
745
745
  text: 'No restriction (4 weeks)'
@@ -4287,6 +4287,26 @@ const vocabularyApi = {
4287
4287
  serializer: serializer$1
4288
4288
  };
4289
4289
 
4290
+ /**
4291
+ * Resolves identifier scheme keys (e.g. "CALL_NUMBER") to their
4292
+ * human-readable titles from the vocabulary API.
4293
+ *
4294
+ * @param {Array<string>} identifiers
4295
+ * @param {string} identifierScheme
4296
+ * @returns {Promise<Array<{key: string, text: string}>>}
4297
+ */
4298
+ const fetchIdentifierTitles = async (identifiers, identifierScheme) => {
4299
+ const query = vocabularyApi.query().withType(identifierScheme);
4300
+ const response = await vocabularyApi.list(query.qs());
4301
+ return identifiers.map(scheme => {
4302
+ const vocabEntry = response.data.hits.find(entry => entry.metadata.key === scheme);
4303
+ return {
4304
+ key: scheme,
4305
+ text: vocabEntry ? vocabEntry.metadata.text : scheme
4306
+ };
4307
+ });
4308
+ };
4309
+
4290
4310
  class ScrollingMenuItem$1 extends React.Component {
4291
4311
  constructor(props) {
4292
4312
  super(props);
@@ -6232,32 +6252,36 @@ class DocumentItemBody extends React.Component {
6232
6252
  items,
6233
6253
  shelfLink,
6234
6254
  documentDetails,
6235
- identifiersToDisplayInFrontside
6236
- } = this.props;
6237
- return items.map(item => /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Row, {
6238
- key: item.pid
6239
- }, /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6240
- "data-label": "Barcode",
6241
- className: "document-item-table-itemCell"
6242
- }, item.barcode), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6243
- "data-label": "Shelf",
6244
- className: "document-item-table-itemCell"
6245
- }, shelfLink !== null ? shelfLink(item, documentDetails) : _get__default["default"](item, 'shelf')), identifiersToDisplayInFrontside.map(identifier => {
6246
- var _item$identifiers, _item$identifiers$fin;
6247
- return /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6248
- key: identifier,
6249
- "data-label": identifier.text,
6255
+ identifiersToDisplay
6256
+ } = this.props;
6257
+ return items.map(item => {
6258
+ const itemIsAccessible = !_get__default["default"](item, 'internal_location.restricted');
6259
+ const shelfValue = shelfLink ? shelfLink(item, documentDetails) : _get__default["default"](item, 'shelf');
6260
+ return /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Row, {
6261
+ key: item.pid
6262
+ }, /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6263
+ "data-label": "Barcode",
6264
+ className: "document-item-table-itemCell"
6265
+ }, item.barcode), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6266
+ "data-label": "Shelf",
6250
6267
  className: "document-item-table-itemCell"
6251
- }, (_item$identifiers = item.identifiers) === null || _item$identifiers === void 0 ? void 0 : (_item$identifiers$fin = _item$identifiers.find(entry => {
6252
- return entry.scheme === identifier.key;
6253
- })) === null || _item$identifiers$fin === void 0 ? void 0 : _item$identifiers$fin.value);
6254
- }), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6255
- "data-label": "Status"
6256
- }, this.statusLabel(item)), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6257
- "data-label": "Medium"
6258
- }, getDisplayVal('ITEMS.mediums', item.medium)), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6259
- "data-label": "Restrictions"
6260
- }, getDisplayVal('ITEMS.circulationRestrictions', item.circulation_restriction))));
6268
+ }, itemIsAccessible ? shelfValue : /*#__PURE__*/React__default["default"].createElement("p", null, "Available on Request")), identifiersToDisplay.map(identifier => {
6269
+ var _item$identifiers, _item$identifiers$fin;
6270
+ return /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6271
+ key: identifier,
6272
+ "data-label": identifier.text,
6273
+ className: "document-item-table-itemCell"
6274
+ }, itemIsAccessible && ((_item$identifiers = item.identifiers) === null || _item$identifiers === void 0 ? void 0 : (_item$identifiers$fin = _item$identifiers.find(entry => {
6275
+ return entry.scheme === identifier.key;
6276
+ })) === null || _item$identifiers$fin === void 0 ? void 0 : _item$identifiers$fin.value));
6277
+ }), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6278
+ "data-label": "Status"
6279
+ }, this.statusLabel(item)), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6280
+ "data-label": "Medium"
6281
+ }, getDisplayVal('ITEMS.mediums', item.medium)), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Cell, {
6282
+ "data-label": "Restrictions"
6283
+ }, getDisplayVal('ITEMS.circulationRestrictions', item.circulation_restriction)));
6284
+ });
6261
6285
  }
6262
6286
  }
6263
6287
  DocumentItemBody.defaultProps = {
@@ -27058,7 +27082,11 @@ class AvailableItems$1 extends React.Component {
27058
27082
  query: '',
27059
27083
  filteredData: null,
27060
27084
  modalOpen: false,
27061
- checkoutItem: null
27085
+ checkoutItem: null,
27086
+ identifiersToDisplay: invenioConfig.ITEMS.identifiersToDisplay.map(s => ({
27087
+ key: s,
27088
+ text: s
27089
+ }))
27062
27090
  };
27063
27091
  }
27064
27092
  componentDidMount() {
@@ -27067,6 +27095,25 @@ class AvailableItems$1 extends React.Component {
27067
27095
  loan
27068
27096
  } = this.props;
27069
27097
  fetchAvailableItems(loan.metadata.document_pid);
27098
+ this.loadIdentifierTitles();
27099
+ }
27100
+ componentWillUnmount() {
27101
+ if (this.cancellableFetchIdentifierTitles) {
27102
+ this.cancellableFetchIdentifierTitles.cancel();
27103
+ }
27104
+ }
27105
+ async loadIdentifierTitles() {
27106
+ this.cancellableFetchIdentifierTitles = withCancel(fetchIdentifierTitles(invenioConfig.ITEMS.identifiersToDisplay, invenioConfig.VOCABULARIES.item.identifier.scheme));
27107
+ try {
27108
+ let result = await this.cancellableFetchIdentifierTitles.promise;
27109
+ this.setState({
27110
+ identifiersToDisplay: result
27111
+ });
27112
+ } catch (error) {
27113
+ if (error !== 'UNMOUNTED') {
27114
+ console.error('Error fetching identifier titles for items.', error);
27115
+ }
27116
+ }
27070
27117
  }
27071
27118
  assignItemButton(item) {
27072
27119
  const {
@@ -27137,18 +27184,31 @@ class AvailableItems$1 extends React.Component {
27137
27184
  data
27138
27185
  } = this.props;
27139
27186
  const {
27140
- filteredData
27187
+ filteredData,
27188
+ identifiersToDisplay
27141
27189
  } = this.state;
27190
+ const identifierColumns = identifiersToDisplay.map(identifier => ({
27191
+ title: identifier.text,
27192
+ field: `metadata.identifiers`,
27193
+ formatter: _ref2 => {
27194
+ var _row$metadata$identif;
27195
+ let {
27196
+ row
27197
+ } = _ref2;
27198
+ 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);
27199
+ return entry === null || entry === void 0 ? void 0 : entry.value;
27200
+ }
27201
+ }));
27142
27202
  const columns = [{
27143
27203
  title: 'PID',
27144
27204
  field: 'metadata.pid'
27145
27205
  }, {
27146
27206
  title: 'Barcode',
27147
27207
  field: 'metadata.barcode',
27148
- formatter: _ref2 => {
27208
+ formatter: _ref3 => {
27149
27209
  let {
27150
27210
  row
27151
- } = _ref2;
27211
+ } = _ref3;
27152
27212
  return /*#__PURE__*/React__default["default"].createElement(reactRouterDom.Link, {
27153
27213
  to: BackOfficeRoutes.itemDetailsFor(row.metadata.pid)
27154
27214
  }, row.metadata.barcode);
@@ -27165,7 +27225,7 @@ class AvailableItems$1 extends React.Component {
27165
27225
  }, {
27166
27226
  title: 'Shelf',
27167
27227
  field: 'metadata.shelf'
27168
- }, {
27228
+ }, ...identifierColumns, {
27169
27229
  title: 'Actions',
27170
27230
  field: '',
27171
27231
  formatter: this.rowActionButton
@@ -28154,15 +28214,20 @@ const LoanDetails = reactRedux.connect(mapStateToProps$K, mapDispatchToProps$z)(
28154
28214
  class _SearchDateRange extends React.Component {
28155
28215
  constructor() {
28156
28216
  super(...arguments);
28157
- this.onDateChange = newFilter => {
28217
+ this.onDateChange = (field, value) => {
28158
28218
  const {
28159
28219
  currentQueryState,
28160
28220
  updateQueryState
28161
28221
  } = this.props;
28162
- const filters = currentQueryState.filters;
28163
- filters.push(newFilter);
28222
+ const updatedFilters = currentQueryState.filters.filter(_ref => {
28223
+ let [name] = _ref;
28224
+ return name !== field;
28225
+ });
28226
+ if (value !== '') {
28227
+ updatedFilters.push([field, value]);
28228
+ }
28164
28229
  return updateQueryState({
28165
- filters: filters
28230
+ filters: updatedFilters
28166
28231
  });
28167
28232
  };
28168
28233
  }
@@ -28174,8 +28239,8 @@ class _SearchDateRange extends React.Component {
28174
28239
  } = this.props;
28175
28240
  let fromDate = '';
28176
28241
  let toDate = '';
28177
- filters.forEach(_ref => {
28178
- let [name, value] = _ref;
28242
+ filters.forEach(_ref2 => {
28243
+ let [name, value] = _ref2;
28179
28244
  if (name === 'loans_from_date') fromDate = value;
28180
28245
  if (name === 'loans_to_date') toDate = value;
28181
28246
  });
@@ -28187,12 +28252,12 @@ class _SearchDateRange extends React.Component {
28187
28252
  maxDate: toDate,
28188
28253
  defaultValue: fromDate,
28189
28254
  placeholder: "From",
28190
- handleDateChange: value => this.onDateChange(['loans_from_date', value])
28255
+ handleDateChange: value => this.onDateChange('loans_from_date', value)
28191
28256
  })), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Card.Content, null, /*#__PURE__*/React__default["default"].createElement(DatePicker$1, {
28192
28257
  minDate: fromDate,
28193
28258
  defaultValue: toDate,
28194
28259
  placeholder: "To",
28195
- handleDateChange: value => this.onDateChange(['loans_to_date', value])
28260
+ handleDateChange: value => this.onDateChange('loans_to_date', value)
28196
28261
  })));
28197
28262
  }
28198
28263
  }
@@ -28303,6 +28368,11 @@ const schema$3 = () => {
28303
28368
  physical_location: {
28304
28369
  type: 'string',
28305
28370
  title: 'Physical location'
28371
+ },
28372
+ restricted: {
28373
+ type: 'boolean',
28374
+ title: 'Restricted access (not accessible to patrons)',
28375
+ default: false
28306
28376
  }
28307
28377
  }
28308
28378
  };
@@ -28323,6 +28393,8 @@ const uiSchema$3 = title => {
28323
28393
  }, {
28324
28394
  physical_location: 8,
28325
28395
  notes: 8
28396
+ }, {
28397
+ restricted: 8
28326
28398
  }],
28327
28399
  'custom:root': {
28328
28400
  'custom:formTitle': title
@@ -29392,6 +29464,16 @@ class InternalLocationList$1 extends React.Component {
29392
29464
  }, {
29393
29465
  title: 'Location e-mail',
29394
29466
  field: 'metadata.location.email'
29467
+ }, {
29468
+ title: 'Restricted access',
29469
+ formatter: _ref2 => {
29470
+ let {
29471
+ row
29472
+ } = _ref2;
29473
+ return row.metadata.restricted ? /*#__PURE__*/React__default["default"].createElement("i", {
29474
+ className: "check icon"
29475
+ }) : null;
29476
+ }
29395
29477
  }, {
29396
29478
  title: 'Actions',
29397
29479
  field: '',
@@ -35428,21 +35510,6 @@ class DocumentStats extends React.Component {
35428
35510
  class DocumentItem extends React.Component {
35429
35511
  constructor(props) {
35430
35512
  super(props);
35431
- this.fetchIdentifiersToDisplayInFrontsideTitles = () => {
35432
- const query = vocabularyApi.query().withType(invenioConfig.VOCABULARIES.item.identifier.scheme);
35433
- vocabularyApi.list(query.qs()).then(response => {
35434
- const identifiersToDisplayInFrontside = this.state.identifiersToDisplayInFrontside.map(identifier => {
35435
- const vocabEntry = response.data.hits.find(entry => entry.metadata.key === identifier.key);
35436
- return {
35437
- ...identifier,
35438
- text: vocabEntry ? vocabEntry.metadata.text : identifier.text
35439
- };
35440
- });
35441
- this.setState({
35442
- identifiersToDisplayInFrontside
35443
- });
35444
- });
35445
- };
35446
35513
  this.toggleItems = () => {
35447
35514
  const {
35448
35515
  isShowingAll
@@ -35451,18 +35518,10 @@ class DocumentItem extends React.Component {
35451
35518
  isShowingAll: !isShowingAll
35452
35519
  });
35453
35520
  };
35454
- const _identifiersToDisplayInFrontside = invenioConfig.ITEMS.identifiersToDisplayInFrontside.map(identifier => ({
35455
- key: identifier,
35456
- text: identifier
35457
- }));
35458
35521
  this.state = {
35459
35522
  isShowingAll: false,
35460
- itemAmountLimit: 5,
35461
- identifiersToDisplayInFrontside: _identifiersToDisplayInFrontside
35523
+ itemAmountLimit: 5
35462
35524
  };
35463
- if (_identifiersToDisplayInFrontside.length > 0) {
35464
- this.fetchIdentifiersToDisplayInFrontsideTitles();
35465
- }
35466
35525
  }
35467
35526
  get moreItemsToLoad() {
35468
35527
  const {
@@ -35478,12 +35537,12 @@ class DocumentItem extends React.Component {
35478
35537
  internalLocationName,
35479
35538
  items,
35480
35539
  documentDetails,
35481
- showTitle
35540
+ showTitle,
35541
+ identifiersToDisplay
35482
35542
  } = this.props;
35483
35543
  const {
35484
35544
  isShowingAll,
35485
- itemAmountLimit,
35486
- identifiersToDisplayInFrontside
35545
+ itemAmountLimit
35487
35546
  } = this.state;
35488
35547
  const previewArrayOfItems = items.slice(0, itemAmountLimit);
35489
35548
  const completeArrayOfItems = items;
@@ -35501,14 +35560,14 @@ class DocumentItem extends React.Component {
35501
35560
  id: "DocumentDetails.DocumentItem.TableHeader"
35502
35561
  }, /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Row, {
35503
35562
  "data-test": "header"
35504
- }, /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.HeaderCell, null, "Barcode"), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.HeaderCell, null, "Shelf"), identifiersToDisplayInFrontside.map(identifier => /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.HeaderCell, {
35563
+ }, /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.HeaderCell, null, "Barcode"), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.HeaderCell, null, "Shelf"), identifiersToDisplay.map(identifier => /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.HeaderCell, {
35505
35564
  key: identifier.key
35506
35565
  }, identifier.text)), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.HeaderCell, null, "Status"), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.HeaderCell, null, "Medium"), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.HeaderCell, null, "Loan restriction")))), /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Body, null, /*#__PURE__*/React__default["default"].createElement(Overridable__default["default"], {
35507
35566
  id: "DocumentDetails.DocumentItemTableBody"
35508
35567
  }, /*#__PURE__*/React__default["default"].createElement(DocumentItemBody, {
35509
35568
  items: itemsToShow,
35510
35569
  documentDetails: documentDetails,
35511
- identifiersToDisplayInFrontside: identifiersToDisplayInFrontside
35570
+ identifiersToDisplay: identifiersToDisplay
35512
35571
  }))), this.moreItemsToLoad && /*#__PURE__*/React__default["default"].createElement(semanticUiReact.Table.Footer, {
35513
35572
  fullWidth: true,
35514
35573
  "data-test": "footer",
@@ -35600,7 +35659,8 @@ class DocumentTabs extends React.Component {
35600
35659
  };
35601
35660
  this.createInternalLocationTables = locationsObject => {
35602
35661
  const {
35603
- activeInternalLocation
35662
+ activeInternalLocation,
35663
+ identifiersToDisplay
35604
35664
  } = this.state;
35605
35665
  const sortedInternalLocationEntries = this.sortedLocationEntries(Object.entries(locationsObject));
35606
35666
  if (activeInternalLocation) {
@@ -35614,7 +35674,8 @@ class DocumentTabs extends React.Component {
35614
35674
  internalLocationName: internalLocationName,
35615
35675
  items: items,
35616
35676
  documentDetails: this.documentDetails,
35617
- showTitle: activeInternalLocation !== internalLocationName
35677
+ showTitle: activeInternalLocation !== internalLocationName,
35678
+ identifiersToDisplay: identifiersToDisplay
35618
35679
  });
35619
35680
  }
35620
35681
  return sortedInternalLocationEntries.map(_ref6 => {
@@ -35625,7 +35686,8 @@ class DocumentTabs extends React.Component {
35625
35686
  internalLocationName: internalLocationName,
35626
35687
  items: items,
35627
35688
  documentDetails: this.documentDetails,
35628
- showTitle: activeInternalLocation !== internalLocationName
35689
+ showTitle: activeInternalLocation !== internalLocationName,
35690
+ identifiersToDisplay: identifiersToDisplay
35629
35691
  });
35630
35692
  });
35631
35693
  };
@@ -35649,9 +35711,34 @@ class DocumentTabs extends React.Component {
35649
35711
  const [firstLocationName] = this.locationEntries[0];
35650
35712
  const [_firstInternalLocationName] = this.firstInternalLocationEntry(firstLocationName);
35651
35713
  this.state = {
35652
- activeInternalLocation: _firstInternalLocationName
35714
+ activeInternalLocation: _firstInternalLocationName,
35715
+ identifiersToDisplay: invenioConfig.ITEMS.identifiersToDisplay.map(s => ({
35716
+ key: s,
35717
+ text: s
35718
+ }))
35653
35719
  };
35654
35720
  }
35721
+ componentDidMount() {
35722
+ this.loadIdentifierTitles();
35723
+ }
35724
+ componentWillUnmount() {
35725
+ if (this.cancellableFetchIdentifierTitles) {
35726
+ this.cancellableFetchIdentifierTitles.cancel();
35727
+ }
35728
+ }
35729
+ async loadIdentifierTitles() {
35730
+ this.cancellableFetchIdentifierTitles = withCancel(fetchIdentifierTitles(invenioConfig.ITEMS.identifiersToDisplay, invenioConfig.VOCABULARIES.item.identifier.scheme));
35731
+ try {
35732
+ let result = await this.cancellableFetchIdentifierTitles.promise;
35733
+ this.setState({
35734
+ identifiersToDisplay: result
35735
+ });
35736
+ } catch (error) {
35737
+ if (error !== 'UNMOUNTED') {
35738
+ console.error('Error fetching identifier titles for items.', error);
35739
+ }
35740
+ }
35741
+ }
35655
35742
  get locations() {
35656
35743
  const {
35657
35744
  locationsObject