@inveniosoftware/react-invenio-app-ils 1.3.0 → 2.0.1

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
@@ -41,12 +41,12 @@ import _difference from 'lodash/difference';
41
41
  import _first from 'lodash/first';
42
42
  import ReactDOM from 'react-dom';
43
43
  import { omit } from 'lodash/object';
44
+ import _startCase from 'lodash/startCase';
44
45
  import _concat from 'lodash/concat';
45
46
  import { random } from 'lodash/number';
46
47
  import _truncate from 'lodash/truncate';
47
48
  import { TagCloud } from 'react-tagcloud';
48
49
  import { Html5Qrcode, Html5QrcodeSupportedFormats } from 'html5-qrcode';
49
- import _startCase from 'lodash/startCase';
50
50
  import PropTypes from 'prop-types';
51
51
  import { combineReducers, createStore, applyMiddleware } from 'redux';
52
52
  import { composeWithDevTools } from 'redux-devtools-extension';
@@ -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)'
@@ -2037,7 +2042,7 @@ const apiConfig = {
2037
2042
  const http = axios.create(apiConfig);
2038
2043
 
2039
2044
  // List used to specify whether to redirect to route `/errors` & prevent a redundant error notifation
2040
- const HTTP_STATUS_CODES_WITH_ERROR_PAGE = [404, 410, 429, 500];
2045
+ const HTTP_STATUS_CODES_WITH_ERROR_PAGE = [404, 410, 403, 429, 500];
2041
2046
  // The corresponding dedicated error page components exist in `@pages/frontsite/ErrorPafe`
2042
2047
  const URLS_NOT_TO_REDIRECT_IF_UNAUTHORIZED = ['/me', '/me/loans'];
2043
2048
  // CSRF possible errors
@@ -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,
@@ -6172,7 +6181,8 @@ class DocumentItemBody extends Component {
6172
6181
  const {
6173
6182
  items,
6174
6183
  shelfLink,
6175
- documentDetails
6184
+ documentDetails,
6185
+ identifiersToDisplayInFrontside
6176
6186
  } = this.props;
6177
6187
  return items.map(item => /*#__PURE__*/React.createElement(Table.Row, {
6178
6188
  key: item.pid
@@ -6182,7 +6192,16 @@ class DocumentItemBody extends Component {
6182
6192
  }, item.barcode), /*#__PURE__*/React.createElement(Table.Cell, {
6183
6193
  "data-label": "Shelf",
6184
6194
  className: "document-item-table-itemCell"
6185
- }, 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, {
6186
6205
  "data-label": "Status"
6187
6206
  }, this.statusLabel(item)), /*#__PURE__*/React.createElement(Table.Cell, {
6188
6207
  "data-label": "Medium"
@@ -7951,7 +7970,7 @@ const BannerCmp = _ref => {
7951
7970
  break;
7952
7971
  }
7953
7972
  return /*#__PURE__*/React.createElement(Overridable, {
7954
- id: "Banner.layout",
7973
+ id: "Banners.layout",
7955
7974
  message: message,
7956
7975
  category: category,
7957
7976
  colorProp: colorProp
@@ -7963,42 +7982,44 @@ const BannerCmp = _ref => {
7963
7982
  }
7964
7983
  })));
7965
7984
  };
7966
- class Banner$1 extends Component {
7985
+ class Banners$1 extends Component {
7967
7986
  componentDidMount() {
7968
7987
  const {
7969
- fetchBanner,
7970
- resetBanner
7988
+ fetchBanners,
7989
+ resetBanners
7971
7990
  } = this.props;
7972
- resetBanner();
7973
- fetchBanner();
7974
- this.intervalFetchBannerId = setInterval(fetchBanner, FETCH_BANNER_EVERY_SECS * 1000);
7991
+ resetBanners();
7992
+ fetchBanners();
7993
+ this.intervalfetchBannersId = setInterval(fetchBanners, FETCH_BANNER_EVERY_SECS * 1000);
7975
7994
  }
7976
7995
  componentWillUnmount() {
7977
- this.intervalFetchBannerId && clearInterval(this.intervalFetchBannerId);
7996
+ this.intervalfetchBannersId && clearInterval(this.intervalfetchBannersId);
7978
7997
  }
7979
7998
  render() {
7980
7999
  const {
7981
- banner,
8000
+ banners,
7982
8001
  children
7983
8002
  } = this.props;
7984
- 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);
7985
8006
  }
7986
8007
  }
7987
- Banner$1.defaultProps = {
7988
- banner: null,
8008
+ Banners$1.defaultProps = {
8009
+ banners: null,
7989
8010
  children: null
7990
8011
  };
7991
- var BannerComponent = Overridable.component('Banner', Banner$1);
8012
+ var BannerComponent = Overridable.component('Banners', Banners$1);
7992
8013
 
7993
- const BANNER_RESET = 'fetchBanner/RESET';
7994
- const BANNER_SUCCESS = 'fetchBanner/SUCCESS';
7995
- const BANNER_HAS_ERROR = 'fetchBanner/HAS_ERROR';
7996
- 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 = () => {
7997
8018
  return async dispatch => dispatch({
7998
8019
  type: BANNER_RESET
7999
8020
  });
8000
8021
  };
8001
- const fetchBanner = () => {
8022
+ const fetchBanners = () => {
8002
8023
  return async dispatch => {
8003
8024
  try {
8004
8025
  const response = await bannerApi.getActive();
@@ -8016,14 +8037,14 @@ const fetchBanner = () => {
8016
8037
  };
8017
8038
 
8018
8039
  const mapStateToProps$1D = state => ({
8019
- banner: state.banner.data,
8020
- error: state.banner.error
8040
+ banners: state.banners.data,
8041
+ error: state.banners.error
8021
8042
  });
8022
8043
  const mapDispatchToProps$1j = dispatch => ({
8023
- fetchBanner: () => dispatch(fetchBanner()),
8024
- resetBanner: () => dispatch(resetBanner())
8044
+ fetchBanners: () => dispatch(fetchBanners()),
8045
+ resetBanners: () => dispatch(resetBanners())
8025
8046
  });
8026
- const Banner = connect(mapStateToProps$1D, mapDispatchToProps$1j)(BannerComponent);
8047
+ const Banners = connect(mapStateToProps$1D, mapDispatchToProps$1j)(BannerComponent);
8027
8048
 
8028
8049
  const LoginWithLocalAccountLayout = _ref => {
8029
8050
  let {
@@ -8439,7 +8460,7 @@ class Login$1 extends Component {
8439
8460
  this.redirectIfAlreadyLoggedIn();
8440
8461
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Overridable, {
8441
8462
  id: "Login.extras"
8442
- }, /*#__PURE__*/React.createElement(Banner, null)), /*#__PURE__*/React.createElement(LoginLayout, Object.assign({
8463
+ }, /*#__PURE__*/React.createElement(Banners, null)), /*#__PURE__*/React.createElement(LoginLayout, Object.assign({
8443
8464
  hasError: hasError,
8444
8465
  errorHeader: errorHeader,
8445
8466
  errorMessage: errorMessage
@@ -8625,7 +8646,7 @@ function UnauthorizedComponent(props) {
8625
8646
  }, newProps), /*#__PURE__*/React.createElement(HttpError$1, newProps));
8626
8647
  }
8627
8648
  UnauthorizedComponent.defaultProps = defaultProps;
8628
- Overridable.component('Unauthorized', UnauthorizedComponent);
8649
+ const Unauthorized = Overridable.component('Unauthorized', UnauthorizedComponent);
8629
8650
  function ForbiddenComponent(props) {
8630
8651
  const {
8631
8652
  title = 'Access Forbidden',
@@ -8715,11 +8736,11 @@ class AdminMenu extends Component {
8715
8736
  className: "bo-menu bo-menu-footer"
8716
8737
  }, /*#__PURE__*/React.createElement(Menu.Item, null, /*#__PURE__*/React.createElement(Menu.Menu, null, /*#__PURE__*/React.createElement(Menu.Item, {
8717
8738
  as: "a",
8718
- href: `${invenioConfig.APP.INVENIO_UI_URL}/admin`,
8739
+ href: `${invenioConfig.APP.INVENIO_UI_URL}/administration`,
8719
8740
  target: "_blank"
8720
8741
  }, "Admin panel"), /*#__PURE__*/React.createElement(Menu.Item, {
8721
8742
  as: "a",
8722
- href: `${invenioConfig.APP.INVENIO_UI_URL}/admin/page`,
8743
+ href: `${invenioConfig.APP.INVENIO_UI_URL}/administration/pages`,
8723
8744
  target: "_blank"
8724
8745
  }, "Static pages"))))));
8725
8746
  }
@@ -13806,7 +13827,7 @@ class ESSelectorLoanRequest extends Component {
13806
13827
  placeholder: "Select delivery method",
13807
13828
  options: this.deliveryMethods,
13808
13829
  onChange: this.handleDeliveryMethodChange,
13809
- defaultValue: this.deliveryMethods[1].value,
13830
+ defaultValue: this.defaultDeliveryMethod,
13810
13831
  selection: true
13811
13832
  })) : null;
13812
13833
  };
@@ -13826,7 +13847,11 @@ class ESSelectorLoanRequest extends Component {
13826
13847
  value: key,
13827
13848
  text: invenioConfig.CIRCULATION.deliveryMethods[key].text
13828
13849
  })) : [];
13829
- 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;
13830
13855
  }
13831
13856
  render() {
13832
13857
  const {
@@ -27770,7 +27795,7 @@ class LoanActions$1 extends Component {
27770
27795
 
27771
27796
  // omit checkout because it must done in one of the available items
27772
27797
  if (!itemPid) {
27773
- actions = omit(actions, 'checkout');
27798
+ actions = omit(actions, ['checkout', 'self_checkout']);
27774
27799
  }
27775
27800
  return Object.keys(actions).map(action => {
27776
27801
  const cancelAction = function () {
@@ -27798,7 +27823,7 @@ class LoanActions$1 extends Component {
27798
27823
  onClick: loanAction,
27799
27824
  loading: isLoading,
27800
27825
  disabled: isLoading
27801
- }, capitalize(action)));
27826
+ }, _startCase(action)));
27802
27827
  });
27803
27828
  }
27804
27829
  render() {
@@ -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
@@ -37235,6 +37287,8 @@ class ErrorsPage extends Component {
37235
37287
  message: "The requested content has been removed.",
37236
37288
  icon: "compass outline"
37237
37289
  });
37290
+ } else if (params.errorCode === 403) {
37291
+ return /*#__PURE__*/React.createElement(Unauthorized, null);
37238
37292
  } else if (params.errorCode === 429) {
37239
37293
  return /*#__PURE__*/React.createElement(TooManyRequests, null);
37240
37294
  }
@@ -40747,7 +40801,7 @@ class FrontSite extends Component {
40747
40801
  className: "fs-content"
40748
40802
  }, /*#__PURE__*/React.createElement(Overridable, {
40749
40803
  id: "FrontSite.extras"
40750
- }, /*#__PURE__*/React.createElement(Banner, null)), /*#__PURE__*/React.createElement(Switch, null, /*#__PURE__*/React.createElement(Route, {
40804
+ }, /*#__PURE__*/React.createElement(Banners, null)), /*#__PURE__*/React.createElement(Switch, null, /*#__PURE__*/React.createElement(Route, {
40751
40805
  exact: true,
40752
40806
  path: FrontSiteRoutes.home,
40753
40807
  render: props => /*#__PURE__*/React.createElement(Home$1, Object.assign({}, props, this.props))
@@ -40889,7 +40943,7 @@ const initialState$N = {
40889
40943
  data: {},
40890
40944
  error: {}
40891
40945
  };
40892
- const fetchBannerReducer = function () {
40946
+ const fetchBannersReducer = function () {
40893
40947
  let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState$N;
40894
40948
  let action = arguments.length > 1 ? arguments[1] : undefined;
40895
40949
  switch (action.type) {
@@ -43096,7 +43150,7 @@ function createILSReducer(asyncReducers) {
43096
43150
  borrowingRequestLoanExtension: borrowingRequestLoanExtensionReducer,
43097
43151
  itemsCheckIn: itemsCheckInReducer,
43098
43152
  checkOut: checkOutReducer,
43099
- banner: fetchBannerReducer,
43153
+ banners: fetchBannersReducer,
43100
43154
  bulkLoanExtend: patronBulkExtendLoans,
43101
43155
  ...asyncReducers
43102
43156
  });