@inveniosoftware/react-invenio-app-ils 2.0.2 → 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 +331 -89
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +331 -89
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -697,7 +697,7 @@ const RECORDS_CONFIG = {
|
|
|
697
697
|
}
|
|
698
698
|
},
|
|
699
699
|
ITEMS: {
|
|
700
|
-
|
|
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);
|
|
@@ -4317,6 +4337,14 @@ const prettyPrintBooleanValue = value => {
|
|
|
4317
4337
|
const screenIsWiderThan = pixels => {
|
|
4318
4338
|
return window.matchMedia(`(max-width: ${pixels}px)`).matches ? false : true;
|
|
4319
4339
|
};
|
|
4340
|
+
const isPrivilegedUser = () => {
|
|
4341
|
+
const roles = _get(sessionManager, 'user.roles', []);
|
|
4342
|
+
return roles.includes('admin') || roles.includes('librarian');
|
|
4343
|
+
};
|
|
4344
|
+
const isDocumentOverbooked = async documentPid => {
|
|
4345
|
+
const response = await documentApi.get(documentPid);
|
|
4346
|
+
return _get(response, 'data.metadata.circulation.overbooked', false);
|
|
4347
|
+
};
|
|
4320
4348
|
|
|
4321
4349
|
class MetadataTable extends Component {
|
|
4322
4350
|
renderRows() {
|
|
@@ -6182,32 +6210,36 @@ class DocumentItemBody extends Component {
|
|
|
6182
6210
|
items,
|
|
6183
6211
|
shelfLink,
|
|
6184
6212
|
documentDetails,
|
|
6185
|
-
|
|
6186
|
-
} = this.props;
|
|
6187
|
-
return items.map(item =>
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
return /*#__PURE__*/React.createElement(Table.Cell, {
|
|
6198
|
-
key: identifier,
|
|
6199
|
-
"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",
|
|
6200
6225
|
className: "document-item-table-itemCell"
|
|
6201
|
-
},
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
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
|
+
});
|
|
6211
6243
|
}
|
|
6212
6244
|
}
|
|
6213
6245
|
DocumentItemBody.defaultProps = {
|
|
@@ -27008,7 +27040,11 @@ class AvailableItems$1 extends Component {
|
|
|
27008
27040
|
query: '',
|
|
27009
27041
|
filteredData: null,
|
|
27010
27042
|
modalOpen: false,
|
|
27011
|
-
checkoutItem: null
|
|
27043
|
+
checkoutItem: null,
|
|
27044
|
+
identifiersToDisplay: invenioConfig.ITEMS.identifiersToDisplay.map(s => ({
|
|
27045
|
+
key: s,
|
|
27046
|
+
text: s
|
|
27047
|
+
}))
|
|
27012
27048
|
};
|
|
27013
27049
|
}
|
|
27014
27050
|
componentDidMount() {
|
|
@@ -27017,6 +27053,25 @@ class AvailableItems$1 extends Component {
|
|
|
27017
27053
|
loan
|
|
27018
27054
|
} = this.props;
|
|
27019
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
|
+
}
|
|
27020
27075
|
}
|
|
27021
27076
|
assignItemButton(item) {
|
|
27022
27077
|
const {
|
|
@@ -27087,18 +27142,31 @@ class AvailableItems$1 extends Component {
|
|
|
27087
27142
|
data
|
|
27088
27143
|
} = this.props;
|
|
27089
27144
|
const {
|
|
27090
|
-
filteredData
|
|
27145
|
+
filteredData,
|
|
27146
|
+
identifiersToDisplay
|
|
27091
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
|
+
}));
|
|
27092
27160
|
const columns = [{
|
|
27093
27161
|
title: 'PID',
|
|
27094
27162
|
field: 'metadata.pid'
|
|
27095
27163
|
}, {
|
|
27096
27164
|
title: 'Barcode',
|
|
27097
27165
|
field: 'metadata.barcode',
|
|
27098
|
-
formatter:
|
|
27166
|
+
formatter: _ref3 => {
|
|
27099
27167
|
let {
|
|
27100
27168
|
row
|
|
27101
|
-
} =
|
|
27169
|
+
} = _ref3;
|
|
27102
27170
|
return /*#__PURE__*/React.createElement(Link$1, {
|
|
27103
27171
|
to: BackOfficeRoutes.itemDetailsFor(row.metadata.pid)
|
|
27104
27172
|
}, row.metadata.barcode);
|
|
@@ -27115,7 +27183,7 @@ class AvailableItems$1 extends Component {
|
|
|
27115
27183
|
}, {
|
|
27116
27184
|
title: 'Shelf',
|
|
27117
27185
|
field: 'metadata.shelf'
|
|
27118
|
-
}, {
|
|
27186
|
+
}, ...identifierColumns, {
|
|
27119
27187
|
title: 'Actions',
|
|
27120
27188
|
field: '',
|
|
27121
27189
|
formatter: this.rowActionButton
|
|
@@ -28104,15 +28172,20 @@ const LoanDetails = connect(mapStateToProps$K, mapDispatchToProps$z)(LoanDetails
|
|
|
28104
28172
|
class _SearchDateRange extends Component {
|
|
28105
28173
|
constructor() {
|
|
28106
28174
|
super(...arguments);
|
|
28107
|
-
this.onDateChange =
|
|
28175
|
+
this.onDateChange = (field, value) => {
|
|
28108
28176
|
const {
|
|
28109
28177
|
currentQueryState,
|
|
28110
28178
|
updateQueryState
|
|
28111
28179
|
} = this.props;
|
|
28112
|
-
const
|
|
28113
|
-
|
|
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
|
+
}
|
|
28114
28187
|
return updateQueryState({
|
|
28115
|
-
filters:
|
|
28188
|
+
filters: updatedFilters
|
|
28116
28189
|
});
|
|
28117
28190
|
};
|
|
28118
28191
|
}
|
|
@@ -28124,8 +28197,8 @@ class _SearchDateRange extends Component {
|
|
|
28124
28197
|
} = this.props;
|
|
28125
28198
|
let fromDate = '';
|
|
28126
28199
|
let toDate = '';
|
|
28127
|
-
filters.forEach(
|
|
28128
|
-
let [name, value] =
|
|
28200
|
+
filters.forEach(_ref2 => {
|
|
28201
|
+
let [name, value] = _ref2;
|
|
28129
28202
|
if (name === 'loans_from_date') fromDate = value;
|
|
28130
28203
|
if (name === 'loans_to_date') toDate = value;
|
|
28131
28204
|
});
|
|
@@ -28137,12 +28210,12 @@ class _SearchDateRange extends Component {
|
|
|
28137
28210
|
maxDate: toDate,
|
|
28138
28211
|
defaultValue: fromDate,
|
|
28139
28212
|
placeholder: "From",
|
|
28140
|
-
handleDateChange: value => this.onDateChange(
|
|
28213
|
+
handleDateChange: value => this.onDateChange('loans_from_date', value)
|
|
28141
28214
|
})), /*#__PURE__*/React.createElement(Card.Content, null, /*#__PURE__*/React.createElement(DatePicker$1, {
|
|
28142
28215
|
minDate: fromDate,
|
|
28143
28216
|
defaultValue: toDate,
|
|
28144
28217
|
placeholder: "To",
|
|
28145
|
-
handleDateChange: value => this.onDateChange(
|
|
28218
|
+
handleDateChange: value => this.onDateChange('loans_to_date', value)
|
|
28146
28219
|
})));
|
|
28147
28220
|
}
|
|
28148
28221
|
}
|
|
@@ -28253,6 +28326,11 @@ const schema$3 = () => {
|
|
|
28253
28326
|
physical_location: {
|
|
28254
28327
|
type: 'string',
|
|
28255
28328
|
title: 'Physical location'
|
|
28329
|
+
},
|
|
28330
|
+
restricted: {
|
|
28331
|
+
type: 'boolean',
|
|
28332
|
+
title: 'Restricted access (not accessible to patrons)',
|
|
28333
|
+
default: false
|
|
28256
28334
|
}
|
|
28257
28335
|
}
|
|
28258
28336
|
};
|
|
@@ -28273,6 +28351,8 @@ const uiSchema$3 = title => {
|
|
|
28273
28351
|
}, {
|
|
28274
28352
|
physical_location: 8,
|
|
28275
28353
|
notes: 8
|
|
28354
|
+
}, {
|
|
28355
|
+
restricted: 8
|
|
28276
28356
|
}],
|
|
28277
28357
|
'custom:root': {
|
|
28278
28358
|
'custom:formTitle': title
|
|
@@ -29342,6 +29422,16 @@ class InternalLocationList$1 extends Component {
|
|
|
29342
29422
|
}, {
|
|
29343
29423
|
title: 'Location e-mail',
|
|
29344
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
|
+
}
|
|
29345
29435
|
}, {
|
|
29346
29436
|
title: 'Actions',
|
|
29347
29437
|
field: '',
|
|
@@ -29505,19 +29595,108 @@ const mapDispatchToProps$v = dispatch => ({
|
|
|
29505
29595
|
});
|
|
29506
29596
|
const LocationList = connect(mapStateToProps$G, mapDispatchToProps$v)(LocationList$1);
|
|
29507
29597
|
|
|
29598
|
+
const OverbookedConfirmModal = _ref => {
|
|
29599
|
+
let {
|
|
29600
|
+
open,
|
|
29601
|
+
onClose,
|
|
29602
|
+
onConfirm,
|
|
29603
|
+
overbookedDocuments
|
|
29604
|
+
} = _ref;
|
|
29605
|
+
const isMultiple = overbookedDocuments.length > 1;
|
|
29606
|
+
return /*#__PURE__*/React.createElement(Modal, {
|
|
29607
|
+
size: "small",
|
|
29608
|
+
open: open,
|
|
29609
|
+
onClose: onClose
|
|
29610
|
+
}, /*#__PURE__*/React.createElement(Modal.Header, null, "Item in high demand!"), /*#__PURE__*/React.createElement(Modal.Content, null, overbookedDocuments.map((doc, index) => /*#__PURE__*/React.createElement("p", {
|
|
29611
|
+
key: doc.loanRequestId || doc.title || index
|
|
29612
|
+
}, "There is another patron waiting for \"", /*#__PURE__*/React.createElement("strong", null, doc.title), "\"", ' ', doc.loanRequestId && /*#__PURE__*/React.createElement(React.Fragment, null, "(", /*#__PURE__*/React.createElement("a", {
|
|
29613
|
+
href: `/backoffice/loans/${doc.loanRequestId}`
|
|
29614
|
+
}, "See loan request"), ")"), ".")), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("strong", null, "Do you still want to extend your ", isMultiple ? 'loans' : 'loan', "?"))), /*#__PURE__*/React.createElement(Modal.Actions, null, /*#__PURE__*/React.createElement(Button, {
|
|
29615
|
+
secondary: true,
|
|
29616
|
+
onClick: onClose
|
|
29617
|
+
}, "Cancel"), /*#__PURE__*/React.createElement(Button, {
|
|
29618
|
+
primary: true,
|
|
29619
|
+
onClick: onConfirm
|
|
29620
|
+
}, "Extend")));
|
|
29621
|
+
};
|
|
29622
|
+
|
|
29508
29623
|
class PatronBulkExtendLoans$1 extends Component {
|
|
29509
29624
|
constructor() {
|
|
29510
29625
|
super(...arguments);
|
|
29511
29626
|
this.state = {
|
|
29512
|
-
open: false
|
|
29627
|
+
open: false,
|
|
29628
|
+
showOverbookedConfirm: false,
|
|
29629
|
+
overbookedDocuments: [],
|
|
29630
|
+
isChecking: false
|
|
29631
|
+
};
|
|
29632
|
+
this.open = async () => {
|
|
29633
|
+
this.setState({
|
|
29634
|
+
open: true
|
|
29635
|
+
});
|
|
29636
|
+
if (!isPrivilegedUser()) return;
|
|
29637
|
+
this.setState({
|
|
29638
|
+
isChecking: true
|
|
29639
|
+
});
|
|
29640
|
+
try {
|
|
29641
|
+
const {
|
|
29642
|
+
patronPid
|
|
29643
|
+
} = this.props;
|
|
29644
|
+
// Get all active loans for the patron
|
|
29645
|
+
const query = loanApi.query().withPatronPid(patronPid).withState(invenioConfig.CIRCULATION.loanActiveStates).withSize(invenioConfig.APP.PATRON_PROFILE_MAX_RESULTS_SIZE).sortByNewest().qs();
|
|
29646
|
+
const response = await loanApi.list(query);
|
|
29647
|
+
const loans = response.data.hits;
|
|
29648
|
+
const checks = loans.map(async loan => {
|
|
29649
|
+
const documentPid = _get(loan, 'metadata.document.pid');
|
|
29650
|
+
const isOverbooked = await isDocumentOverbooked(documentPid);
|
|
29651
|
+
if (isOverbooked) {
|
|
29652
|
+
return {
|
|
29653
|
+
title: loan.metadata.document.title,
|
|
29654
|
+
loanRequestId: loan.id
|
|
29655
|
+
};
|
|
29656
|
+
}
|
|
29657
|
+
return null;
|
|
29658
|
+
});
|
|
29659
|
+
const results = await Promise.all(checks);
|
|
29660
|
+
const overbookedDocuments = results.filter(Boolean);
|
|
29661
|
+
this.setState({
|
|
29662
|
+
overbookedDocuments,
|
|
29663
|
+
isChecking: false
|
|
29664
|
+
});
|
|
29665
|
+
} catch (error) {
|
|
29666
|
+
console.error('Failed to fetch overbooked documents', error);
|
|
29667
|
+
this.setState({
|
|
29668
|
+
isChecking: false
|
|
29669
|
+
});
|
|
29670
|
+
}
|
|
29671
|
+
};
|
|
29672
|
+
this.close = () => {
|
|
29673
|
+
this.setState({
|
|
29674
|
+
open: false,
|
|
29675
|
+
showOverbookedConfirm: false,
|
|
29676
|
+
overbookedDocuments: []
|
|
29677
|
+
});
|
|
29513
29678
|
};
|
|
29514
|
-
this.open = () => this.setState({
|
|
29515
|
-
open: true
|
|
29516
|
-
});
|
|
29517
|
-
this.close = () => this.setState({
|
|
29518
|
-
open: false
|
|
29519
|
-
});
|
|
29520
29679
|
this.handleSubmitExtend = () => {
|
|
29680
|
+
const {
|
|
29681
|
+
bulkLoanExtension,
|
|
29682
|
+
patronPid
|
|
29683
|
+
} = this.props;
|
|
29684
|
+
const {
|
|
29685
|
+
overbookedDocuments
|
|
29686
|
+
} = this.state;
|
|
29687
|
+
|
|
29688
|
+
// If the user is privileged and there are overbooked docs
|
|
29689
|
+
if (isPrivilegedUser() && overbookedDocuments.length > 0) {
|
|
29690
|
+
this.setState({
|
|
29691
|
+
showOverbookedConfirm: true
|
|
29692
|
+
});
|
|
29693
|
+
return;
|
|
29694
|
+
}
|
|
29695
|
+
// Otherwise extend directly
|
|
29696
|
+
bulkLoanExtension(patronPid);
|
|
29697
|
+
this.close();
|
|
29698
|
+
};
|
|
29699
|
+
this.confirmBulkExtension = () => {
|
|
29521
29700
|
const {
|
|
29522
29701
|
bulkLoanExtension,
|
|
29523
29702
|
patronPid
|
|
@@ -29528,16 +29707,26 @@ class PatronBulkExtendLoans$1 extends Component {
|
|
|
29528
29707
|
}
|
|
29529
29708
|
render() {
|
|
29530
29709
|
const {
|
|
29531
|
-
patronPid,
|
|
29532
|
-
bulkLoanExtension,
|
|
29533
29710
|
isLoading,
|
|
29534
29711
|
disabled,
|
|
29712
|
+
patronPid,
|
|
29713
|
+
bulkLoanExtension,
|
|
29535
29714
|
...uiProps
|
|
29536
29715
|
} = this.props;
|
|
29537
29716
|
const {
|
|
29538
|
-
open
|
|
29717
|
+
open,
|
|
29718
|
+
showOverbookedConfirm,
|
|
29719
|
+
overbookedDocuments,
|
|
29720
|
+
isChecking
|
|
29539
29721
|
} = this.state;
|
|
29540
|
-
return /*#__PURE__*/React.createElement(
|
|
29722
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(OverbookedConfirmModal, {
|
|
29723
|
+
open: showOverbookedConfirm,
|
|
29724
|
+
onClose: () => this.setState({
|
|
29725
|
+
showOverbookedConfirm: false
|
|
29726
|
+
}),
|
|
29727
|
+
onConfirm: this.confirmBulkExtension,
|
|
29728
|
+
overbookedDocuments: overbookedDocuments
|
|
29729
|
+
}), /*#__PURE__*/React.createElement(Modal, {
|
|
29541
29730
|
open: open,
|
|
29542
29731
|
onClose: this.close,
|
|
29543
29732
|
onOpen: this.open,
|
|
@@ -29557,8 +29746,9 @@ class PatronBulkExtendLoans$1 extends Component {
|
|
|
29557
29746
|
onClick: this.close
|
|
29558
29747
|
}, "Cancel"), /*#__PURE__*/React.createElement(Button, {
|
|
29559
29748
|
onClick: this.handleSubmitExtend,
|
|
29560
|
-
primary: true
|
|
29561
|
-
|
|
29749
|
+
primary: true,
|
|
29750
|
+
loading: isChecking
|
|
29751
|
+
}, "Extend the loans"))));
|
|
29562
29752
|
}
|
|
29563
29753
|
}
|
|
29564
29754
|
PatronBulkExtendLoans$1.defaultProps = {
|
|
@@ -35278,21 +35468,6 @@ class DocumentStats extends Component {
|
|
|
35278
35468
|
class DocumentItem extends Component {
|
|
35279
35469
|
constructor(props) {
|
|
35280
35470
|
super(props);
|
|
35281
|
-
this.fetchIdentifiersToDisplayInFrontsideTitles = () => {
|
|
35282
|
-
const query = vocabularyApi.query().withType(invenioConfig.VOCABULARIES.item.identifier.scheme);
|
|
35283
|
-
vocabularyApi.list(query.qs()).then(response => {
|
|
35284
|
-
const identifiersToDisplayInFrontside = this.state.identifiersToDisplayInFrontside.map(identifier => {
|
|
35285
|
-
const vocabEntry = response.data.hits.find(entry => entry.metadata.key === identifier.key);
|
|
35286
|
-
return {
|
|
35287
|
-
...identifier,
|
|
35288
|
-
text: vocabEntry ? vocabEntry.metadata.text : identifier.text
|
|
35289
|
-
};
|
|
35290
|
-
});
|
|
35291
|
-
this.setState({
|
|
35292
|
-
identifiersToDisplayInFrontside
|
|
35293
|
-
});
|
|
35294
|
-
});
|
|
35295
|
-
};
|
|
35296
35471
|
this.toggleItems = () => {
|
|
35297
35472
|
const {
|
|
35298
35473
|
isShowingAll
|
|
@@ -35301,18 +35476,10 @@ class DocumentItem extends Component {
|
|
|
35301
35476
|
isShowingAll: !isShowingAll
|
|
35302
35477
|
});
|
|
35303
35478
|
};
|
|
35304
|
-
const _identifiersToDisplayInFrontside = invenioConfig.ITEMS.identifiersToDisplayInFrontside.map(identifier => ({
|
|
35305
|
-
key: identifier,
|
|
35306
|
-
text: identifier
|
|
35307
|
-
}));
|
|
35308
35479
|
this.state = {
|
|
35309
35480
|
isShowingAll: false,
|
|
35310
|
-
itemAmountLimit: 5
|
|
35311
|
-
identifiersToDisplayInFrontside: _identifiersToDisplayInFrontside
|
|
35481
|
+
itemAmountLimit: 5
|
|
35312
35482
|
};
|
|
35313
|
-
if (_identifiersToDisplayInFrontside.length > 0) {
|
|
35314
|
-
this.fetchIdentifiersToDisplayInFrontsideTitles();
|
|
35315
|
-
}
|
|
35316
35483
|
}
|
|
35317
35484
|
get moreItemsToLoad() {
|
|
35318
35485
|
const {
|
|
@@ -35328,12 +35495,12 @@ class DocumentItem extends Component {
|
|
|
35328
35495
|
internalLocationName,
|
|
35329
35496
|
items,
|
|
35330
35497
|
documentDetails,
|
|
35331
|
-
showTitle
|
|
35498
|
+
showTitle,
|
|
35499
|
+
identifiersToDisplay
|
|
35332
35500
|
} = this.props;
|
|
35333
35501
|
const {
|
|
35334
35502
|
isShowingAll,
|
|
35335
|
-
itemAmountLimit
|
|
35336
|
-
identifiersToDisplayInFrontside
|
|
35503
|
+
itemAmountLimit
|
|
35337
35504
|
} = this.state;
|
|
35338
35505
|
const previewArrayOfItems = items.slice(0, itemAmountLimit);
|
|
35339
35506
|
const completeArrayOfItems = items;
|
|
@@ -35351,14 +35518,14 @@ class DocumentItem extends Component {
|
|
|
35351
35518
|
id: "DocumentDetails.DocumentItem.TableHeader"
|
|
35352
35519
|
}, /*#__PURE__*/React.createElement(Table.Row, {
|
|
35353
35520
|
"data-test": "header"
|
|
35354
|
-
}, /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Barcode"), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Shelf"),
|
|
35521
|
+
}, /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Barcode"), /*#__PURE__*/React.createElement(Table.HeaderCell, null, "Shelf"), identifiersToDisplay.map(identifier => /*#__PURE__*/React.createElement(Table.HeaderCell, {
|
|
35355
35522
|
key: identifier.key
|
|
35356
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, {
|
|
35357
35524
|
id: "DocumentDetails.DocumentItemTableBody"
|
|
35358
35525
|
}, /*#__PURE__*/React.createElement(DocumentItemBody, {
|
|
35359
35526
|
items: itemsToShow,
|
|
35360
35527
|
documentDetails: documentDetails,
|
|
35361
|
-
|
|
35528
|
+
identifiersToDisplay: identifiersToDisplay
|
|
35362
35529
|
}))), this.moreItemsToLoad && /*#__PURE__*/React.createElement(Table.Footer, {
|
|
35363
35530
|
fullWidth: true,
|
|
35364
35531
|
"data-test": "footer",
|
|
@@ -35450,7 +35617,8 @@ class DocumentTabs extends Component {
|
|
|
35450
35617
|
};
|
|
35451
35618
|
this.createInternalLocationTables = locationsObject => {
|
|
35452
35619
|
const {
|
|
35453
|
-
activeInternalLocation
|
|
35620
|
+
activeInternalLocation,
|
|
35621
|
+
identifiersToDisplay
|
|
35454
35622
|
} = this.state;
|
|
35455
35623
|
const sortedInternalLocationEntries = this.sortedLocationEntries(Object.entries(locationsObject));
|
|
35456
35624
|
if (activeInternalLocation) {
|
|
@@ -35464,7 +35632,8 @@ class DocumentTabs extends Component {
|
|
|
35464
35632
|
internalLocationName: internalLocationName,
|
|
35465
35633
|
items: items,
|
|
35466
35634
|
documentDetails: this.documentDetails,
|
|
35467
|
-
showTitle: activeInternalLocation !== internalLocationName
|
|
35635
|
+
showTitle: activeInternalLocation !== internalLocationName,
|
|
35636
|
+
identifiersToDisplay: identifiersToDisplay
|
|
35468
35637
|
});
|
|
35469
35638
|
}
|
|
35470
35639
|
return sortedInternalLocationEntries.map(_ref6 => {
|
|
@@ -35475,7 +35644,8 @@ class DocumentTabs extends Component {
|
|
|
35475
35644
|
internalLocationName: internalLocationName,
|
|
35476
35645
|
items: items,
|
|
35477
35646
|
documentDetails: this.documentDetails,
|
|
35478
|
-
showTitle: activeInternalLocation !== internalLocationName
|
|
35647
|
+
showTitle: activeInternalLocation !== internalLocationName,
|
|
35648
|
+
identifiersToDisplay: identifiersToDisplay
|
|
35479
35649
|
});
|
|
35480
35650
|
});
|
|
35481
35651
|
};
|
|
@@ -35499,9 +35669,34 @@ class DocumentTabs extends Component {
|
|
|
35499
35669
|
const [firstLocationName] = this.locationEntries[0];
|
|
35500
35670
|
const [_firstInternalLocationName] = this.firstInternalLocationEntry(firstLocationName);
|
|
35501
35671
|
this.state = {
|
|
35502
|
-
activeInternalLocation: _firstInternalLocationName
|
|
35672
|
+
activeInternalLocation: _firstInternalLocationName,
|
|
35673
|
+
identifiersToDisplay: invenioConfig.ITEMS.identifiersToDisplay.map(s => ({
|
|
35674
|
+
key: s,
|
|
35675
|
+
text: s
|
|
35676
|
+
}))
|
|
35503
35677
|
};
|
|
35504
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
|
+
}
|
|
35505
35700
|
get locations() {
|
|
35506
35701
|
const {
|
|
35507
35702
|
locationsObject
|
|
@@ -38906,6 +39101,36 @@ class LoanExtendButton extends Component {
|
|
|
38906
39101
|
constructor(props) {
|
|
38907
39102
|
super(props);
|
|
38908
39103
|
this.triggerExtension = async () => {
|
|
39104
|
+
const {
|
|
39105
|
+
loan,
|
|
39106
|
+
onError
|
|
39107
|
+
} = this.props;
|
|
39108
|
+
const isUserPrivileged = isPrivilegedUser();
|
|
39109
|
+
if (isUserPrivileged) {
|
|
39110
|
+
this.setState({
|
|
39111
|
+
isLoading: true
|
|
39112
|
+
});
|
|
39113
|
+
try {
|
|
39114
|
+
const documentPid = _get(loan, 'metadata.document.pid');
|
|
39115
|
+
const isOverbooked = await isDocumentOverbooked(documentPid);
|
|
39116
|
+
if (isOverbooked) {
|
|
39117
|
+
this.setState({
|
|
39118
|
+
isLoading: false,
|
|
39119
|
+
showOverbookedConfirm: true
|
|
39120
|
+
});
|
|
39121
|
+
return;
|
|
39122
|
+
}
|
|
39123
|
+
} catch (error) {
|
|
39124
|
+
onError('Something went wrong while checking if the literature is overbooked.', error);
|
|
39125
|
+
this.setState({
|
|
39126
|
+
isLoading: false
|
|
39127
|
+
});
|
|
39128
|
+
return;
|
|
39129
|
+
}
|
|
39130
|
+
}
|
|
39131
|
+
await this.performExtension();
|
|
39132
|
+
};
|
|
39133
|
+
this.performExtension = async () => {
|
|
38909
39134
|
const {
|
|
38910
39135
|
loan,
|
|
38911
39136
|
onSuccess,
|
|
@@ -38923,7 +39148,8 @@ class LoanExtendButton extends Component {
|
|
|
38923
39148
|
this.cancellableExtendLoan = withCancel(this.extendLoan(extendUrl, document.pid, patronPid));
|
|
38924
39149
|
const response = await this.cancellableExtendLoan.promise;
|
|
38925
39150
|
this.setState({
|
|
38926
|
-
isLoading: false
|
|
39151
|
+
isLoading: false,
|
|
39152
|
+
showOverbookedConfirm: false
|
|
38927
39153
|
});
|
|
38928
39154
|
const documentTitle = document.title;
|
|
38929
39155
|
onSuccess(INFO_MESSAGES.SUCCESS(documentTitle, DateTime.fromISO(response.data.metadata.end_date)));
|
|
@@ -38934,6 +39160,11 @@ class LoanExtendButton extends Component {
|
|
|
38934
39160
|
onError(error.response.data.message);
|
|
38935
39161
|
}
|
|
38936
39162
|
};
|
|
39163
|
+
this.hideOverbookedConfirm = () => {
|
|
39164
|
+
this.setState({
|
|
39165
|
+
showOverbookedConfirm: false
|
|
39166
|
+
});
|
|
39167
|
+
};
|
|
38937
39168
|
this.validate = loan => {
|
|
38938
39169
|
const hasExtendAction = _has(loan, 'availableActions.extend');
|
|
38939
39170
|
if (!hasExtendAction) return {
|
|
@@ -38961,7 +39192,8 @@ class LoanExtendButton extends Component {
|
|
|
38961
39192
|
};
|
|
38962
39193
|
};
|
|
38963
39194
|
this.state = {
|
|
38964
|
-
isLoading: false
|
|
39195
|
+
isLoading: false,
|
|
39196
|
+
showOverbookedConfirm: false
|
|
38965
39197
|
};
|
|
38966
39198
|
}
|
|
38967
39199
|
componentWillUnmount() {
|
|
@@ -38980,11 +39212,21 @@ class LoanExtendButton extends Component {
|
|
|
38980
39212
|
loan
|
|
38981
39213
|
} = this.props;
|
|
38982
39214
|
const {
|
|
38983
|
-
isLoading
|
|
39215
|
+
isLoading,
|
|
39216
|
+
showOverbookedConfirm
|
|
38984
39217
|
} = this.state;
|
|
38985
39218
|
const validation = this.validate(loan);
|
|
38986
39219
|
const isDisabled = !validation.isValid;
|
|
38987
|
-
|
|
39220
|
+
const overbookedDocuments = [{
|
|
39221
|
+
title: _get(loan, 'metadata.document.title', 'Unknown title'),
|
|
39222
|
+
loanRequestId: loan.id
|
|
39223
|
+
}];
|
|
39224
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, showOverbookedConfirm && /*#__PURE__*/React.createElement(OverbookedConfirmModal, {
|
|
39225
|
+
open: showOverbookedConfirm,
|
|
39226
|
+
onClose: this.hideOverbookedConfirm,
|
|
39227
|
+
onConfirm: this.performExtension,
|
|
39228
|
+
overbookedDocuments: overbookedDocuments
|
|
39229
|
+
}), isDisabled && /*#__PURE__*/React.createElement(Popup, {
|
|
38988
39230
|
content: validation.msg,
|
|
38989
39231
|
trigger: /*#__PURE__*/React.createElement(Icon, {
|
|
38990
39232
|
name: "info"
|