'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.searchName = undefined;

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _reactIntl = require('react-intl');

var _get = require('lodash/get');

var _get2 = _interopRequireDefault(_get);

var _immutable = require('immutable');

var _immutable2 = _interopRequireDefault(_immutable);

var _qs = require('qs');

var _qs2 = _interopRequireDefault(_qs);

var _CheckboxInput = require('cspace-input/lib/components/CheckboxInput');

var _CheckboxInput2 = _interopRequireDefault(_CheckboxInput);

var _ErrorPage = require('./ErrorPage');

var _ErrorPage2 = _interopRequireDefault(_ErrorPage);

var _RelateButton = require('../record/RelateButton');

var _RelateButton2 = _interopRequireDefault(_RelateButton);

var _SearchResultTitleBar = require('../search/SearchResultTitleBar');

var _SearchResultTitleBar2 = _interopRequireDefault(_SearchResultTitleBar);

var _Pager = require('../search/Pager');

var _Pager2 = _interopRequireDefault(_Pager);

var _SearchResultSummary = require('../search/SearchResultSummary');

var _SearchResultSummary2 = _interopRequireDefault(_SearchResultSummary);

var _SelectBar = require('../search/SelectBar');

var _SelectBar2 = _interopRequireDefault(_SelectBar);

var _SearchResultTableContainer = require('../../containers/search/SearchResultTableContainer');

var _SearchResultTableContainer2 = _interopRequireDefault(_SearchResultTableContainer);

var _SearchToRelateModalContainer = require('../../containers/search/SearchToRelateModalContainer');

var _SearchToRelateModalContainer2 = _interopRequireDefault(_SearchToRelateModalContainer);

var _permissionHelpers = require('../../helpers/permissionHelpers');

var _searchHelpers = require('../../helpers/searchHelpers');

var _configHelpers = require('../../helpers/configHelpers');

var _SearchResultPage = require('../../../styles/cspace-ui/SearchResultPage.css');

var _SearchResultPage2 = _interopRequireDefault(_SearchResultPage);

var _PageBody = require('../../../styles/cspace-ui/PageBody.css');

var _PageBody2 = _interopRequireDefault(_PageBody);

var _SearchResultSidebar = require('../../../styles/cspace-ui/SearchResultSidebar.css');

var _SearchResultSidebar2 = _interopRequireDefault(_SearchResultSidebar);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var searchName = exports.searchName = 'searchResultPage';
// FIXME: Make default page size configurable
var defaultPageSize = 20;

var stopPropagation = function stopPropagation(event) {
  event.stopPropagation();
};

var messages = (0, _reactIntl.defineMessages)({
  relate: {
    'id': 'searchResultPage.relate',
    'defaultMessage': 'Relate\u2026'
  }
});

var propTypes = {
  history: _propTypes2.default.object,
  location: _propTypes2.default.object,
  match: _propTypes2.default.object,
  perms: _propTypes2.default.instanceOf(_immutable2.default.Map),
  preferredPageSize: _propTypes2.default.number,
  search: _propTypes2.default.func,
  selectedItems: _propTypes2.default.instanceOf(_immutable2.default.Map),
  setPreferredPageSize: _propTypes2.default.func,
  setSearchPageAdvanced: _propTypes2.default.func,
  setSearchPageKeyword: _propTypes2.default.func,
  setAllItemsSelected: _propTypes2.default.func,
  onItemSelectChange: _propTypes2.default.func
};

var contextTypes = {
  config: _propTypes2.default.object.isRequired
};

var SearchResultPage = function (_Component) {
  _inherits(SearchResultPage, _Component);

  function SearchResultPage() {
    _classCallCheck(this, SearchResultPage);

    var _this = _possibleConstructorReturn(this, (SearchResultPage.__proto__ || Object.getPrototypeOf(SearchResultPage)).call(this));

    _this.getSearchToRelateSubjects = _this.getSearchToRelateSubjects.bind(_this);
    _this.handleCheckboxCommit = _this.handleCheckboxCommit.bind(_this);
    _this.handleEditSearchLinkClick = _this.handleEditSearchLinkClick.bind(_this);
    _this.handleModalCancelButtonClick = _this.handleModalCancelButtonClick.bind(_this);
    _this.handleModalCloseButtonClick = _this.handleModalCloseButtonClick.bind(_this);
    _this.handlePageChange = _this.handlePageChange.bind(_this);
    _this.handlePageSizeChange = _this.handlePageSizeChange.bind(_this);
    _this.handleRelateButtonClick = _this.handleRelateButtonClick.bind(_this);
    _this.handleRelationsCreated = _this.handleRelationsCreated.bind(_this);
    _this.handleSortChange = _this.handleSortChange.bind(_this);
    _this.renderCheckbox = _this.renderCheckbox.bind(_this);
    _this.renderFooter = _this.renderFooter.bind(_this);
    _this.renderHeader = _this.renderHeader.bind(_this);
    _this.shouldShowCheckbox = _this.shouldShowCheckbox.bind(_this);

    _this.state = {
      isSearchToRelateModalOpen: false
    };
    return _this;
  }

  _createClass(SearchResultPage, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      if (!this.normalizeQuery()) {
        var _props = this.props,
            location = _props.location,
            setPreferredPageSize = _props.setPreferredPageSize;


        if (setPreferredPageSize) {
          var search = location.search;


          var query = _qs2.default.parse(search.substring(1));

          setPreferredPageSize(parseInt(query.size, 10));
        }

        this.search();
      }
    }
  }, {
    key: 'componentDidUpdate',
    value: function componentDidUpdate(prevProps) {
      var _props2 = this.props,
          location = _props2.location,
          match = _props2.match,
          perms = _props2.perms;
      var prevLocation = prevProps.location,
          prevMatch = prevProps.match,
          prevPerms = prevProps.perms;
      var params = match.params;
      var prevParams = prevMatch.params;


      if (perms !== prevPerms || params.recordType !== prevParams.recordType || params.vocabulary !== prevParams.vocabulary || params.csid !== prevParams.csid || params.subresource !== prevParams.subresource || location.search !== prevLocation.search) {
        if (!this.normalizeQuery()) {
          var setPreferredPageSize = this.props.setPreferredPageSize;


          if (setPreferredPageSize) {
            var search = location.search;


            var query = _qs2.default.parse(search.substring(1));

            setPreferredPageSize(parseInt(query.size, 10));
          }

          this.search();
        }
      }
    }
  }, {
    key: 'getListType',
    value: function getListType(searchDescriptor) {
      var config = this.context.config;


      return (0, _searchHelpers.getListType)(config, searchDescriptor);
    }
  }, {
    key: 'getSearchDescriptor',
    value: function getSearchDescriptor() {
      // FIXME: Make the search descriptor consistently an Immutable. Currently only the advanced
      // search condition is an Immutable. The whole search descriptor gets converted to an Immutable
      // when stored in the Redux store, but components expect it to be an object (except for the
      // advanced search condition, which is always Immutable). This is confusing.

      // FIXME: Refactor this into a wrapper component that calculates the search descriptor from
      // location and params, and passes it into a child. This will eliminate the multiple calls to
      // this method from the various render methods in this class.

      var _props3 = this.props,
          location = _props3.location,
          match = _props3.match;
      var params = match.params;
      var search = location.search;


      var query = _qs2.default.parse(search.substring(1));

      var searchQuery = Object.assign({}, query, {
        p: parseInt(query.p, 10) - 1,
        size: parseInt(query.size, 10)
      });

      var advancedSearchCondition = query.as;

      if (advancedSearchCondition) {
        searchQuery.as = JSON.parse(advancedSearchCondition);
      }

      var searchDescriptor = {
        searchQuery: searchQuery
      };

      ['recordType', 'vocabulary', 'csid', 'subresource'].forEach(function (param) {
        var value = params[param];

        if (typeof value !== 'undefined') {
          searchDescriptor[param] = value;
        }
      });

      return _immutable2.default.fromJS(searchDescriptor);
    }
  }, {
    key: 'getSearchToRelateSubjects',
    value: function getSearchToRelateSubjects() {
      var selectedItems = this.props.selectedItems;
      var config = this.context.config;


      if (!selectedItems) {
        return null;
      }

      var searchDescriptor = this.getSearchDescriptor();

      var recordType = searchDescriptor.get('recordType');
      var serviceType = (0, _get2.default)(config, ['recordTypes', recordType, 'serviceConfig', 'serviceType']);
      var itemRecordType = serviceType === 'utility' ? undefined : recordType;

      return selectedItems.valueSeq().map(function (item) {
        return {
          csid: item.get('csid'),
          recordType: itemRecordType || (0, _configHelpers.getRecordTypeNameByServiceObjectName)(config, item.get('docType'))
        };
      }).toJS();
    }
  }, {
    key: 'isResultRelatable',
    value: function isResultRelatable(searchDescriptor) {
      var config = this.context.config;


      var recordType = searchDescriptor.get('recordType');
      var subresource = searchDescriptor.get('subresource');

      var serviceType = (0, _get2.default)(config, ['recordTypes', recordType, 'serviceConfig', 'serviceType']);

      return subresource !== 'terms' && (serviceType === 'procedure' || serviceType === 'object' || recordType === 'procedure' || recordType === 'object');
    }
  }, {
    key: 'closeModal',
    value: function closeModal() {
      this.setState({
        isSearchToRelateModalOpen: false
      });
    }
  }, {
    key: 'normalizeQuery',
    value: function normalizeQuery() {
      var _props4 = this.props,
          history = _props4.history,
          location = _props4.location,
          preferredPageSize = _props4.preferredPageSize;
      var search = location.search;


      var query = _qs2.default.parse(search.substring(1));

      if (history) {
        var normalizedQueryParams = {};

        var pageSize = parseInt(query.size, 10);

        if (isNaN(pageSize) || pageSize < 1) {
          var normalizedPageSize = preferredPageSize || defaultPageSize;

          normalizedQueryParams.size = normalizedPageSize.toString();
        } else if (pageSize > 2500) {
          // Services layer max is 2500
          normalizedQueryParams.size = '2500';
        } else if (pageSize.toString() !== query.size) {
          normalizedQueryParams.size = pageSize.toString();
        }

        var pageNum = parseInt(query.p, 10);

        if (isNaN(pageNum) || pageNum < 1) {
          normalizedQueryParams.p = '1';
        } else if (pageNum.toString() !== query.p) {
          normalizedQueryParams.p = pageNum.toString();
        }

        if (Object.keys(normalizedQueryParams).length > 0) {
          var newQuery = Object.assign({}, query, normalizedQueryParams);
          var queryString = _qs2.default.stringify(newQuery);

          history.replace({
            pathname: location.pathname,
            search: '?' + queryString
          });

          return true;
        }
      }

      return false;
    }
  }, {
    key: 'shouldShowCheckbox',
    value: function shouldShowCheckbox(item) {
      return item.get('workflowState') !== 'locked' && (0, _permissionHelpers.canRelate)((0, _configHelpers.getRecordTypeNameByUri)(this.context.config, item.get('uri')), this.props.perms);
    }
  }, {
    key: 'handleCheckboxCommit',
    value: function handleCheckboxCommit(path, value) {
      var index = parseInt(path[0], 10);
      var selected = value;

      var onItemSelectChange = this.props.onItemSelectChange;
      var config = this.context.config;


      if (onItemSelectChange) {
        var searchDescriptor = this.getSearchDescriptor();
        var listType = this.getListType(searchDescriptor);

        onItemSelectChange(config, searchName, searchDescriptor, listType, index, selected);
      }
    }
  }, {
    key: 'handleEditSearchLinkClick',
    value: function handleEditSearchLinkClick() {
      // Transfer this search descriptor's search criteria to advanced search.

      var _props5 = this.props,
          setSearchPageAdvanced = _props5.setSearchPageAdvanced,
          setSearchPageKeyword = _props5.setSearchPageKeyword;


      if (setSearchPageKeyword || setSearchPageAdvanced) {
        var searchDescriptor = this.getSearchDescriptor();
        var searchQuery = searchDescriptor.get('searchQuery');

        if (setSearchPageKeyword) {
          setSearchPageKeyword(searchQuery.get('kw'));
        }

        if (setSearchPageAdvanced) {
          setSearchPageAdvanced(searchQuery.get('as'));
        }
      }
    }
  }, {
    key: 'handleModalCancelButtonClick',
    value: function handleModalCancelButtonClick() {
      this.closeModal();
    }
  }, {
    key: 'handleModalCloseButtonClick',
    value: function handleModalCloseButtonClick() {
      this.closeModal();
    }
  }, {
    key: 'handlePageChange',
    value: function handlePageChange(pageNum) {
      var _props6 = this.props,
          history = _props6.history,
          location = _props6.location;


      if (history) {
        var search = location.search;


        var query = _qs2.default.parse(search.substring(1));

        query.p = (pageNum + 1).toString();

        var queryString = _qs2.default.stringify(query);

        history.push({
          pathname: location.pathname,
          search: '?' + queryString
        });
      }
    }
  }, {
    key: 'handlePageSizeChange',
    value: function handlePageSizeChange(pageSize) {
      var _props7 = this.props,
          history = _props7.history,
          location = _props7.location,
          setPreferredPageSize = _props7.setPreferredPageSize;


      if (setPreferredPageSize) {
        setPreferredPageSize(pageSize);
      }

      if (history) {
        var search = location.search;


        var query = _qs2.default.parse(search.substring(1));

        query.p = '1';
        query.size = pageSize.toString();

        var queryString = _qs2.default.stringify(query);

        history.push({
          pathname: location.pathname,
          search: '?' + queryString
        });
      }
    }
  }, {
    key: 'handleRelateButtonClick',
    value: function handleRelateButtonClick() {
      this.setState({
        isSearchToRelateModalOpen: true
      });
    }
  }, {
    key: 'handleRelationsCreated',
    value: function handleRelationsCreated() {
      this.closeModal();
    }
  }, {
    key: 'handleSortChange',
    value: function handleSortChange(sort) {
      var _props8 = this.props,
          history = _props8.history,
          location = _props8.location;


      if (history) {
        var search = location.search;


        var query = _qs2.default.parse(search.substring(1));

        query.sort = sort;

        var queryString = _qs2.default.stringify(query);

        history.push({
          pathname: location.pathname,
          search: '?' + queryString
        });
      }
    }
  }, {
    key: 'search',
    value: function search() {
      var search = this.props.search;
      var config = this.context.config;


      var searchDescriptor = this.getSearchDescriptor();
      var listType = this.getListType(searchDescriptor);

      if (search) {
        search(config, searchName, searchDescriptor, listType);
      }
    }
  }, {
    key: 'renderCheckbox',
    value: function renderCheckbox(_ref) {
      var rowData = _ref.rowData,
          rowIndex = _ref.rowIndex;
      var selectedItems = this.props.selectedItems;


      if (this.shouldShowCheckbox(rowData)) {
        var itemCsid = rowData.get('csid');
        var selected = selectedItems ? selectedItems.has(itemCsid) : false;

        return _react2.default.createElement(_CheckboxInput2.default, {
          embedded: true,
          name: '' + rowIndex,
          value: selected,
          onCommit: this.handleCheckboxCommit

          // Prevent clicking on the checkbox from selecting the record.
          , onClick: stopPropagation
        });
      }

      return null;
    }
  }, {
    key: 'renderHeader',
    value: function renderHeader(_ref2) {
      var searchError = _ref2.searchError,
          searchResult = _ref2.searchResult;
      var _props9 = this.props,
          selectedItems = _props9.selectedItems,
          setAllItemsSelected = _props9.setAllItemsSelected;
      var config = this.context.config;


      var searchDescriptor = this.getSearchDescriptor();
      var listType = this.getListType(searchDescriptor);

      var selectBar = void 0;

      if (!searchError && this.isResultRelatable(searchDescriptor)) {
        var selectedCount = selectedItems ? selectedItems.size : 0;

        var relateButton = _react2.default.createElement(_RelateButton2.default, {
          disabled: selectedCount < 1,
          key: 'relate',
          label: _react2.default.createElement(_reactIntl.FormattedMessage, messages.relate),
          name: 'relate',
          onClick: this.handleRelateButtonClick
        });

        selectBar = _react2.default.createElement(_SelectBar2.default, {
          buttons: [relateButton],
          config: config,
          listType: listType,
          searchDescriptor: searchDescriptor,
          searchName: searchName,
          searchResult: searchResult,
          selectedItems: selectedItems,
          setAllItemsSelected: setAllItemsSelected,
          showCheckboxFilter: this.shouldShowCheckbox
        });
      }

      return _react2.default.createElement(
        'header',
        null,
        _react2.default.createElement(_SearchResultSummary2.default, {
          config: config,
          listType: listType,
          searchDescriptor: searchDescriptor,
          searchError: searchError,
          searchResult: searchResult,
          onEditSearchLinkClick: this.handleEditSearchLinkClick,
          onPageSizeChange: this.handlePageSizeChange
        }),
        selectBar
      );
    }
  }, {
    key: 'renderFooter',
    value: function renderFooter(_ref3) {
      var searchResult = _ref3.searchResult;

      if (searchResult) {
        var config = this.context.config;


        var searchDescriptor = this.getSearchDescriptor();
        var listType = this.getListType(searchDescriptor);
        var listTypeConfig = config.listTypes[listType];
        var listNodeName = listTypeConfig.listNodeName;


        var list = searchResult.get(listNodeName);

        var totalItems = parseInt(list.get('totalItems'), 10);
        var pageNum = parseInt(list.get('pageNum'), 10);
        var pageSize = parseInt(list.get('pageSize'), 10);
        var lastPage = Math.max(0, isNaN(totalItems) ? 0 : Math.ceil(totalItems / pageSize) - 1);

        return _react2.default.createElement(
          'footer',
          null,
          _react2.default.createElement(_Pager2.default, {
            currentPage: pageNum,
            lastPage: lastPage,
            pageSize: pageSize,
            onPageChange: this.handlePageChange,
            onPageSizeChange: this.handlePageSizeChange
          })
        );
      }

      return null;
    }
  }, {
    key: 'render',
    value: function render() {
      var history = this.props.history;
      var config = this.context.config;
      var isSearchToRelateModalOpen = this.state.isSearchToRelateModalOpen;


      var searchDescriptor = this.getSearchDescriptor();
      var listType = this.getListType(searchDescriptor);

      var recordType = searchDescriptor.get('recordType');
      var vocabulary = searchDescriptor.get('vocabulary');
      var csid = searchDescriptor.get('csid');
      var subresource = searchDescriptor.get('subresource');

      var validation = (0, _configHelpers.validateLocation)(config, { recordType: recordType, vocabulary: vocabulary, csid: csid, subresource: subresource });

      if (validation.error) {
        return _react2.default.createElement(_ErrorPage2.default, { error: validation.error });
      }

      var isResultRelatable = this.isResultRelatable(searchDescriptor);

      var searchToRelateModal = void 0;

      if (isResultRelatable) {
        searchToRelateModal = _react2.default.createElement(_SearchToRelateModalContainer2.default, {
          allowedServiceTypes: ['object', 'procedure'],
          subjects: this.getSearchToRelateSubjects,
          config: config,
          isOpen: isSearchToRelateModalOpen,
          defaultRecordTypeValue: 'collectionobject',
          onCancelButtonClick: this.handleModalCancelButtonClick,
          onCloseButtonClick: this.handleModalCloseButtonClick,
          onRelationsCreated: this.handleRelationsCreated
        });
      }

      return _react2.default.createElement(
        'div',
        { className: _SearchResultPage2.default.common },
        _react2.default.createElement(_SearchResultTitleBar2.default, {
          config: config,
          searchDescriptor: searchDescriptor,
          searchName: searchName,
          updateDocumentTitle: true
        }),
        _react2.default.createElement(
          'div',
          { className: _PageBody2.default.common },
          _react2.default.createElement(_SearchResultTableContainer2.default, {
            config: config,
            history: history,
            listType: listType,
            searchName: searchName,
            searchDescriptor: searchDescriptor,
            recordType: recordType,
            showCheckboxColumn: isResultRelatable,
            renderCheckbox: this.renderCheckbox,
            renderHeader: this.renderHeader,
            renderFooter: this.renderFooter,
            onSortChange: this.handleSortChange
          }),
          _react2.default.createElement('div', { className: _SearchResultSidebar2.default.common })
        ),
        searchToRelateModal
      );
    }
  }]);

  return SearchResultPage;
}(_react.Component);

exports.default = SearchResultPage;


SearchResultPage.propTypes = propTypes;
SearchResultPage.contextTypes = contextTypes;