text: "use strict";
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.default = void 0;
  
  var _isEqual2 = _interopRequireDefault(require("lodash/isEqual"));
  
  var _react = _interopRequireDefault(require("react"));
  
  var _propTypes = _interopRequireDefault(require("prop-types"));
  
  var _schema = _interopRequireDefault(require("part:@sanity/base/schema"));
  
  var _default = _interopRequireDefault(require("part:@sanity/components/panes/default"));
  
  var _queryContainer = require("part:@sanity/base/query-container");
  
  var _default2 = _interopRequireDefault(require("part:@sanity/components/snackbar/default"));
  
  var _spinner = _interopRequireDefault(require("part:@sanity/components/loading/spinner"));
  
  var _draftUtils = require("part:@sanity/base/util/draft-utils");
  
  var _rxjs = require("rxjs");
  
  var _operators = require("rxjs/operators");
  
  var _shallowEquals = _interopRequireDefault(require("shallow-equals"));
  
  var _settings = _interopRequireDefault(require("../../settings"));
  
  var _DocumentsListPane = _interopRequireDefault(require("./DocumentsListPane.css"));
  
  var _ListView = _interopRequireDefault(require("../../components/listView/ListView.css"));
  
  var _infiniteList = require("./infiniteList");
  
  var _paneItem = require("../../components/paneItem");
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
  
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
  
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
  
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
  
  function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
  
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
  
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
  
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
  
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  
  var PARTIAL_PAGE_LIMIT = 100;
  var FULL_LIST_LIMIT = 2000;
  var DEFAULT_ORDERING = [{
    field: '_createdAt',
    direction: 'desc'
  }];
  
  function removePublishedWithDrafts(documents) {
    return (0, _draftUtils.collate)(documents).map(entry => {
      var doc = entry.draft || entry.published;
      return _objectSpread(_objectSpread({}, doc), {}, {
        hasPublished: !!entry.published,
        hasDraft: !!entry.draft
      });
    });
  }
  
  function getDocumentKey(document) {
    return (0, _draftUtils.getPublishedId)(document._id);
  }
  
  function getTypeNameFromSingleTypeFilter(filter) {
    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    var pattern = /\b_type\s*==\s*(['"].*?['"]|\$.*?(?:\s|$))|\B(['"].*?['"]|\$.*?(?:\s|$))\s*==\s*_type\b/;
    var matches = filter.match(pattern);
  
    if (!matches) {
      return null;
    }
  
    var match = (matches[1] || matches[2]).trim().replace(/^["']|["']$/g, '');
    var typeName = match[0] === '$' ? params[match.slice(1)] : match;
    return typeName || null;
  }
  
  function isSimpleTypeFilter(filter) {
    return /^_type\s*==\s*['"$]\w+['"]?\s*$/.test(filter.trim());
  }
  
  function toOrderClause(orderBy) {
    return orderBy.map(ordering => [ordering.field, (ordering.direction || '').toLowerCase()].map(str => str.trim()).filter(Boolean).join(' ')).join(', ');
  }
  
  class DocumentsListPane extends _react.default.PureComponent {
    constructor(props) {
      super();
  
      _defineProperty(this, "actionHandlers", {
        setLayout: (_ref) => {
          var layout = _ref.layout;
          this.layoutSetting.set(layout);
        },
        setSortOrder: sort => {
          this.sortOrderSetting.set(sort);
        }
      });
  
      _defineProperty(this, "state", {
        queryResult: {},
        sortOrder: null,
        layout: null,
        isLoadingMore: false,
        hasFullSubscription: false
      });
  
      _defineProperty(this, "renderItem", item => /*#__PURE__*/_react.default.createElement(_paneItem.PaneItem, {
        id: (0, _draftUtils.getPublishedId)(item._id),
        layout: this.state.layout || this.props.defaultLayout || 'default',
        value: item,
        icon: this.props.displayOptions.showIcons === false ? false : undefined,
        schemaType: _schema.default.get(item._type),
        isSelected: this.itemIsSelected(item)
      }));
  
      _defineProperty(this, "handleAction", item => {
        var handler = typeof item.action === 'function' ? item.action : this.actionHandlers[item.action];
  
        if (!handler) {
          return false;
        }
  
        handler(item.params, this);
        return true;
      });
  
      _defineProperty(this, "handleScroll", (scrollTop, itemHeight) => {
        var _this$state = this.state,
            queryResult = _this$state.queryResult,
            isLoadingMore = _this$state.isLoadingMore,
            hasFullSubscription = _this$state.hasFullSubscription;
        var result = queryResult.result;
        var documents = result && result.documents || [];
        var mightHaveMoreItems = documents.length === PARTIAL_PAGE_LIMIT;
  
        if (this.atLoadingThreshold || isLoadingMore || hasFullSubscription || !result || !mightHaveMoreItems) {
          return;
        }
  
        if (scrollTop >= itemHeight * (PARTIAL_PAGE_LIMIT / 2)) {
          // Prevent scroll handler from firing again before setState kicks in
          this.atLoadingThreshold = true;
          this.setState({
            isLoadingMore: true,
            hasFullSubscription: true
          }, () => {
            // Technically still here, but is only used to guard against double-firing
            this.atLoadingThreshold = false;
          });
          this.setupQuery({
            fullList: true
          });
        }
      });
  
      var _props$options = props.options,
          filter = _props$options.filter,
          params = _props$options.params;
      var typeName = getTypeNameFromSingleTypeFilter(filter, params);
  
      var settingsNamespace = _settings.default.forNamespace(typeName);
  
      this.atLoadingThreshold = false;
      this.sortOrderSetting = settingsNamespace.forKey('sortOrder');
      this.layoutSetting = settingsNamespace.forKey('layout'); // Passed to rendered <Menu> components. This prevents the "click outside"
      // functionality from kicking in when pressing the toggle menu button
  
      this.templateMenuId = Math.random().toString(36).substr(2, 6);
      var sync = true;
      this.settingsSubscription = (0, _rxjs.combineLatest)(this.sortOrderSetting.listen(DEFAULT_ORDERING), this.layoutSetting.listen()).pipe((0, _operators.map)((_ref2) => {
        var _ref3 = _slicedToArray(_ref2, 2),
            sortOrder = _ref3[0],
            layout = _ref3[1];
  
        return {
          sortOrder,
          layout
        };
      }), (0, _operators.tap)(nextState => {
        if (sync) {
          this.state = _objectSpread(_objectSpread({}, this.state), nextState);
        } else {
          this.setState(nextState);
        }
      })).subscribe();
      sync = false;
    }
  
    componentDidMount() {
      this.setupQuery({
        fullList: false
      });
    }
  
    componentWillUnmount() {
      this.settingsSubscription.unsubscribe();
  
      if (this.queryResults$) {
        this.queryResults$.unsubscribe();
      }
    }
  
    itemIsSelected(item) {
      return this.props.childItemId === (0, _draftUtils.getPublishedId)(item._id);
    }
  
    componentDidUpdate(prevProps, prevState) {
      // If the filter/params has changed, set up a new query from scratch
      var queryChanged = prevProps.options.filter !== this.props.options.filter || !(0, _shallowEquals.default)(prevProps.options.params, this.props.options.params); // If sort changed, set up a new query from scratch as well
  
      var sortChanged = !(0, _isEqual2.default)(this.state.sortOrder, prevState.sortOrder);
  
      if (queryChanged || sortChanged) {
        this.setupQuery({
          fullList: false
        });
      }
    }
  
    setupQuery(_ref4) {
      var _ref4$fullList = _ref4.fullList,
          fullList = _ref4$fullList === void 0 ? false : _ref4$fullList;
  
      if (this.queryResults$) {
        this.queryResults$.unsubscribe();
      }
  
      var params = this.props.options.params || {};
      var query = this.buildListQuery({
        fullList
      });
      this.queryResults$ = (0, _queryContainer.getQueryResults)((0, _rxjs.of)({
        query,
        params
      })).pipe((0, _operators.filter)(fullList ? (_ref5) => {
        var result = _ref5.result;
        return result;
      } : () => true)).subscribe(queryResult => this.setState({
        queryResult,
        isLoadingMore: false,
        hasFullSubscription: fullList
      }));
    }
  
    buildListQuery(_ref6) {
      var fullList = _ref6.fullList;
      var options = this.props.options;
      var filter = options.filter,
          defaultOrdering = options.defaultOrdering;
      var sortOrder = this.state.sortOrder;
      var extendedProjection = sortOrder && sortOrder.extendedProjection;
      var projectionFields = ['_id', '_type'];
      var finalProjection = projectionFields.join(', ');
      var sortBy = sortOrder && sortOrder.by || defaultOrdering || [];
      var limit = fullList ? FULL_LIST_LIMIT : PARTIAL_PAGE_LIMIT;
      var sort = sortBy.length > 0 ? sortBy : DEFAULT_ORDERING;
  
      if (extendedProjection) {
        var firstProjection = projectionFields.concat(extendedProjection).join(', '); // At first glance, you might think that 'order' should come before 'slice'?
        // However, this is actullay a counter-bug
        // to https://github.com/sanity-io/gradient/issues/922 which causes:
        // 1. case-insensitive ordering (we want this)
        // 2. null-values to sort to the top, even when order is desc (we don't want this)
        // Because Studios in the wild rely on the buggy nature of this
        // do not change this until we have API versioning
  
        return ["*[".concat(filter, "] [0...").concat(limit, "]"), "{".concat(firstProjection, "}"), "order(".concat(toOrderClause(sort), ")"), "{".concat(finalProjection, "}")].join(' | ');
      }
  
      return "*[".concat(filter, "] | order(").concat(toOrderClause(sort), ") [0...").concat(limit, "] {").concat(finalProjection, "}");
    }
  
    renderResults() {
      var _this$state2 = this.state,
          queryResult = _this$state2.queryResult,
          isLoadingMore = _this$state2.isLoadingMore;
      var result = queryResult.result;
  
      if (!result) {
        return null;
      }
  
      var _this$props = this.props,
          options = _this$props.options,
          defaultLayout = _this$props.defaultLayout;
      var layout = this.state.layout || defaultLayout || 'default';
      var filterIsSimpleTypeContraint = isSimpleTypeFilter(options.filter);
      var items = removePublishedWithDrafts(result ? result.documents : []);
  
      if (!items || items.length === 0) {
        return /*#__PURE__*/_react.default.createElement("div", {
          className: _DocumentsListPane.default.empty
        }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("h3", null, filterIsSimpleTypeContraint ? 'No documents of this type found' : 'No documents matching this filter found')));
      }
  
      return /*#__PURE__*/_react.default.createElement("div", {
        className: _DocumentsListPane.default["layout__".concat(layout)]
      }, items && /*#__PURE__*/_react.default.createElement(_infiniteList.InfiniteList, {
        className: _ListView.default.scroll,
        items: items,
        layout: layout,
        getItemKey: getDocumentKey,
        renderItem: this.renderItem,
        onScroll: this.handleScroll,
        hasMoreItems: items.length === FULL_LIST_LIMIT,
        isLoadingMore: isLoadingMore
      }));
    }
  
    renderContent() {
      var defaultLayout = this.props.defaultLayout;
      var layout = this.state.layout || defaultLayout || 'default';
      var _this$state$queryResu = this.state.queryResult,
          loading = _this$state$queryResu.loading,
          error = _this$state$queryResu.error,
          onRetry = _this$state$queryResu.onRetry;
  
      if (error) {
        return /*#__PURE__*/_react.default.createElement(_default2.default, {
          kind: "error",
          isPersisted: true,
          actionTitle: "Retry",
          onAction: onRetry,
          title: "An error occurred while loading items:",
          subtitle: /*#__PURE__*/_react.default.createElement("div", null, error.message)
        });
      }
  
      if (loading) {
        return /*#__PURE__*/_react.default.createElement("div", {
          className: _DocumentsListPane.default["layout__".concat(layout)]
        }, loading && /*#__PURE__*/_react.default.createElement(_spinner.default, {
          center: true,
          message: "Loading items\u2026"
        }));
      }
  
      return this.renderResults();
    }
  
    render() {
      var _this$props2 = this.props,
          title = _this$props2.title,
          className = _this$props2.className,
          isCollapsed = _this$props2.isCollapsed,
          isSelected = _this$props2.isSelected,
          onCollapse = _this$props2.onCollapse,
          onExpand = _this$props2.onExpand,
          menuItems = _this$props2.menuItems,
          menuItemGroups = _this$props2.menuItemGroups,
          initialValueTemplates = _this$props2.initialValueTemplates;
      return /*#__PURE__*/_react.default.createElement(_default.default, {
        title: title,
        className: className,
        styles: this.props.styles,
        index: this.props.index,
        menuItems: menuItems,
        menuItemGroups: menuItemGroups,
        initialValueTemplates: initialValueTemplates,
        isSelected: isSelected,
        isCollapsed: isCollapsed,
        onCollapse: onCollapse,
        onAction: this.handleAction,
        onExpand: onExpand,
        isScrollable: false
      }, this.renderContent());
    }
  
  }
  
  exports.default = DocumentsListPane;
  
  _defineProperty(DocumentsListPane, "propTypes", {
    index: _propTypes.default.number.isRequired,
    title: _propTypes.default.string.isRequired,
    childItemId: _propTypes.default.string.isRequired,
    className: _propTypes.default.string,
    styles: _propTypes.default.object,
    // eslint-disable-line react/forbid-prop-types
    defaultLayout: _propTypes.default.string,
    options: _propTypes.default.shape({
      filter: _propTypes.default.string.isRequired,
      defaultOrdering: _propTypes.default.arrayOf(_propTypes.default.shape({
        field: _propTypes.default.string.isRequired,
        direction: _propTypes.default.oneOf(['asc', 'desc'])
      })),
      params: _propTypes.default.object // eslint-disable-line react/forbid-prop-types
  
    }).isRequired,
    menuItems: _propTypes.default.arrayOf(_propTypes.default.shape({
      title: _propTypes.default.string.isRequired
    })),
    menuItemGroups: _propTypes.default.arrayOf(_propTypes.default.shape({
      id: _propTypes.default.string.isRequired
    })),
    initialValueTemplates: _propTypes.default.arrayOf(_propTypes.default.shape({
      templateId: _propTypes.default.string,
      parameters: _propTypes.default.object // eslint-disable-line react/forbid-prop-types
  
    })),
    displayOptions: _propTypes.default.shape({
      showIcons: _propTypes.default.bool
    }),
    isSelected: _propTypes.default.bool.isRequired,
    isCollapsed: _propTypes.default.bool.isRequired,
    onExpand: _propTypes.default.func,
    onCollapse: _propTypes.default.func
  });
  
  _defineProperty(DocumentsListPane, "defaultProps", {
    className: '',
    styles: {},
    menuItems: [],
    menuItemGroups: [],
    displayOptions: {},
    onExpand: undefined,
    onCollapse: undefined,
    defaultLayout: undefined,
    initialValueTemplates: undefined
  });