UNPKG

cspace-ui

Version:
286 lines (274 loc) 12.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _reactIntl = require("react-intl"); var _reactRouterDom = require("react-router-dom"); var _immutable = _interopRequireDefault(require("immutable")); var _SearchResultItemLink = _interopRequireDefault(require("./SearchResultItemLink")); var _searchHelpers = require("../../helpers/searchHelpers"); var _SearchResultTraverser = _interopRequireDefault(require("../../../styles/cspace-ui/SearchResultTraverser.css")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } const messages = (0, _reactIntl.defineMessages)({ result: { "id": "searchResultTraverser.result", "defaultMessage": "Search result {current, number} of {total, number}" }, resultPending: { "id": "searchResultTraverser.resultPending", "defaultMessage": "Search result \u2026 of \u2026" }, prev: { "id": "searchResultTraverser.prev", "defaultMessage": "Previous" }, next: { "id": "searchResultTraverser.next", "defaultMessage": "Next" } }); const propTypes = { config: _propTypes.default.shape({ listTypes: _propTypes.default.object }), csid: _propTypes.default.string, searchName: _propTypes.default.string, searchDescriptor: _propTypes.default.instanceOf(_immutable.default.Map), searchState: _propTypes.default.instanceOf(_immutable.default.Map), nextPageSearchDescriptor: _propTypes.default.instanceOf(_immutable.default.Map), nextPageSearchState: _propTypes.default.instanceOf(_immutable.default.Map), prevPageSearchDescriptor: _propTypes.default.instanceOf(_immutable.default.Map), prevPageSearchState: _propTypes.default.instanceOf(_immutable.default.Map), // eslint-disable-next-line react/forbid-prop-types originSearchPageState: _propTypes.default.object, search: _propTypes.default.func }; class SearchResultTraverser extends _react.Component { componentDidMount() { this.initiateSearch(); } componentDidUpdate() { this.initiateSearch(); } initiateSearch() { const { config, csid, searchDescriptor, searchState, nextPageSearchDescriptor, nextPageSearchState, prevPageSearchDescriptor, prevPageSearchState, searchName, search } = this.props; if (search) { if (searchDescriptor && !searchState) { // We have a search descriptor, but it's not associated with any state. This happens when // navigating to a record from a search, and reloading -- the search descriptor is // maintained in history state, but the search state is gone, since the app has been // reloaded. Initiate the search. search(config, searchName, searchDescriptor, (0, _searchHelpers.getListType)(config, searchDescriptor)); } if (searchState && !searchState.get('isPending') && searchState.get('result')) { const listType = (0, _searchHelpers.getListType)(config, searchDescriptor); const listTypeConfig = config.listTypes[listType]; const { listNodeName, itemNodeName } = listTypeConfig; const indexesByCsid = searchState.get('indexesByCsid'); const index = indexesByCsid.get(csid); const result = searchState.get('result'); const list = result.get(listNodeName); const totalItems = list.get('totalItems'); const pageNum = list.get('pageNum'); const pageSize = list.get('pageSize'); const currentNum = pageNum * pageSize + index + 1; const prevIndex = index - 1; const nextIndex = index + 1; let items = list.get(itemNodeName); if (items && !_immutable.default.List.isList(items)) { items = _immutable.default.List.of(items); } if (!prevPageSearchState && prevIndex < 0 && currentNum > 1 && prevPageSearchDescriptor) { // The previous page has not been retrieved, and we're on the first item of the current // page. Initiate the search for the previous page. search(config, searchName, prevPageSearchDescriptor, (0, _searchHelpers.getListType)(config, prevPageSearchDescriptor)); } if (!nextPageSearchState && nextIndex > items.size - 1 && currentNum < totalItems && nextPageSearchDescriptor) { // The next page has not been retrieved, and we're on the last item of the current page. // Initiate the search for the next page. search(config, searchName, nextPageSearchDescriptor, (0, _searchHelpers.getListType)(config, nextPageSearchDescriptor)); } } } } renderPrevLink(items, index, currentNum, totalItems, locationState) { const { config, searchName, prevPageSearchState, prevPageSearchDescriptor } = this.props; const prevIndex = index - 1; if (prevIndex >= 0) { return /*#__PURE__*/_react.default.createElement(_SearchResultItemLink.default, { rel: "prev", config: config, item: items.get(prevIndex), message: messages.prev, state: locationState }); } if (prevPageSearchState && !prevPageSearchState.get('isPending') && prevPageSearchState.get('result')) { // We're at the beginning of the current page, but we have data for the previous page. Link // to the last item in its results. const listType = (0, _searchHelpers.getListType)(config, prevPageSearchDescriptor); const listTypeConfig = config.listTypes[listType]; const { listNodeName, itemNodeName } = listTypeConfig; let prevPageItems = prevPageSearchState.getIn(['result', listNodeName, itemNodeName]); if (prevPageItems && !_immutable.default.List.isList(prevPageItems)) { prevPageItems = _immutable.default.List.of(prevPageItems); } return /*#__PURE__*/_react.default.createElement(_SearchResultItemLink.default, { rel: "prev", config: config, item: prevPageItems.last(), message: messages.prev, state: { searchName, searchDescriptor: prevPageSearchDescriptor.toJS() } }); } if (currentNum > 1) { // We don't have data for the previous page, but there is one. Show a placeholder link. return /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, messages.prev); } // We're on the first item of all pages. Show a placeholder link. return /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, messages.prev); } renderNextLink(items, index, currentNum, totalItems, locationState) { const { config, searchName, nextPageSearchState, nextPageSearchDescriptor } = this.props; const nextIndex = index + 1; if (nextIndex <= items.size - 1) { return /*#__PURE__*/_react.default.createElement(_SearchResultItemLink.default, { rel: "next", config: config, item: items.get(nextIndex), message: messages.next, state: locationState }); } if (nextPageSearchState && !nextPageSearchState.get('isPending') && nextPageSearchState.get('result')) { // We're at the end of the current page, but we have data for the next page. Link to the // first item in its results. const listType = (0, _searchHelpers.getListType)(config, nextPageSearchDescriptor); const listTypeConfig = config.listTypes[listType]; const { listNodeName, itemNodeName } = listTypeConfig; let nextPageItems = nextPageSearchState.getIn(['result', listNodeName, itemNodeName]); if (nextPageItems && !_immutable.default.List.isList(nextPageItems)) { nextPageItems = _immutable.default.List.of(nextPageItems); } return /*#__PURE__*/_react.default.createElement(_SearchResultItemLink.default, { rel: "next", config: config, item: nextPageItems.first(), message: messages.next, state: { searchName, searchDescriptor: nextPageSearchDescriptor.toJS() } }); } if (currentNum < totalItems) { // We don't have data for the next page, but there is one. Show a placeholder link. return /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, messages.next); } // We're on the last item of all pages. Show a placeholder link. return /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, messages.next); } render() { const { config, csid, searchDescriptor, searchName, searchState, originSearchPageState } = this.props; if (!searchDescriptor) { return null; } let resultMessage; let prevLink; let nextLink; if (!searchState || searchState.get('isPending') || searchState.get('error')) { resultMessage = /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, messages.resultPending); } else { const listType = (0, _searchHelpers.getListType)(config, searchDescriptor); const listTypeConfig = config.listTypes[listType]; const { listNodeName, itemNodeName } = listTypeConfig; const indexesByCsid = searchState.get('indexesByCsid'); const index = indexesByCsid.get(csid); const result = searchState.get('result'); const list = result.get(listNodeName); const totalItems = list.get('totalItems'); const pageNum = list.get('pageNum'); const pageSize = list.get('pageSize'); const currentNum = pageNum * pageSize + index + 1; resultMessage = /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, _extends({}, messages.result, { values: { current: currentNum, total: totalItems } })); let items = result.getIn([listNodeName, itemNodeName]); if (items && !_immutable.default.List.isList(items)) { items = _immutable.default.List.of(items); } const locationState = { searchName, searchDescriptor: searchDescriptor.toJS(), originSearchPage: originSearchPageState }; prevLink = this.renderPrevLink(items, index, currentNum, totalItems, locationState); nextLink = this.renderNextLink(items, index, currentNum, totalItems, locationState); } const searchLocation = Object.assign((0, _searchHelpers.searchDescriptorToLocation)(searchDescriptor), { state: { originSearchPage: originSearchPageState } }); return /*#__PURE__*/_react.default.createElement("nav", { className: _SearchResultTraverser.default.common }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactRouterDom.Link, { rel: "search", to: searchLocation }, resultMessage)), /*#__PURE__*/_react.default.createElement("div", null, prevLink, prevLink && nextLink ? ' | ' : null, nextLink)); } } exports.default = SearchResultTraverser; SearchResultTraverser.propTypes = propTypes;