function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } } return n; }, _extends.apply(null, arguments); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) { o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) { if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } } return t; }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
function _createSuper(t) { var r = _isNativeReflectConstruct(); return function () { var e, o = _getPrototypeOf(t); if (r) { var s = _getPrototypeOf(this).constructor; e = Reflect.construct(o, arguments, s); } else e = o.apply(this, arguments); return _possibleConstructorReturn(this, e); }; }
function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
import PropTypes from "prop-types";
/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * The OpenSearch Contributors require contributions made to
 * this file be licensed under the Apache-2.0 license or a
 * compatible open source license.
 *
 * Modifications Copyright OpenSearch Contributors. See
 * GitHub history for details.
 */

/*
 * Licensed to Elasticsearch B.V. under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch B.V. licenses this file to you under
 * the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import React, { Component } from 'react';
import { isString } from '../../services/predicate';
import { OuiFlexGroup, OuiFlexItem } from '../flex';
import { OuiSearchBox } from './search_box';
import { OuiSearchFilters } from './search_filters';
import { Query, Query as QueryForExport } from './query/query';
export { Ast } from './query';
export { QueryForExport as Query }; // Explicity export and import due to webpack/babel re-export issue

var parseQuery = function parseQuery(query, props) {
  var schema = undefined;
  if (props.box && props.box.schema && _typeof(props.box.schema) === 'object') {
    schema = props.box.schema;
  }
  var dateFormat = props.dateFormat;
  var parseOptions = {
    schema: schema,
    dateFormat: dateFormat
  };
  if (!query) {
    return Query.parse('', parseOptions);
  }
  return isString(query) ? Query.parse(query, parseOptions) : query;
};

// `state.query` is never null, but can be passed as `null` to `notifyControllingParent`
// when `error` is not null.

export var OuiSearchBar = /*#__PURE__*/function (_Component) {
  _inherits(OuiSearchBar, _Component);
  var _super = _createSuper(OuiSearchBar);
  function OuiSearchBar(props) {
    var _this;
    _classCallCheck(this, OuiSearchBar);
    _this = _super.call(this, props);
    _defineProperty(_assertThisInitialized(_this), "onSearch", function (queryText) {
      try {
        var query = parseQuery(queryText, _this.props);
        _this.notifyControllingParent({
          query: query,
          queryText: queryText,
          error: null
        });
        _this.setState({
          query: query,
          queryText: queryText,
          error: null
        });
      } catch (e) {
        var error = e instanceof Error ? {
          name: e.name,
          message: e.message
        } : {
          name: 'Unexpected error',
          message: String(e)
        };
        _this.notifyControllingParent({
          query: null,
          queryText: queryText,
          error: error
        });
        _this.setState({
          queryText: queryText,
          error: error
        });
      }
    });
    _defineProperty(_assertThisInitialized(_this), "onFiltersChange", function (query) {
      _this.notifyControllingParent({
        query: query,
        queryText: query.text,
        error: null
      });
      _this.setState({
        query: query,
        queryText: query.text,
        error: null
      });
    });
    var _query = parseQuery(props.defaultQuery || props.query, props);
    _this.state = {
      query: _query,
      queryText: _query.text,
      error: null
    };
    return _this;
  }
  _createClass(OuiSearchBar, [{
    key: "notifyControllingParent",
    value: function notifyControllingParent(newState) {
      var onChange = this.props.onChange;
      if (!onChange) {
        return;
      }
      var oldState = this.state;
      var query = newState.query,
        queryText = newState.queryText,
        error = newState.error;
      var isQueryDifferent = oldState.queryText !== queryText;
      var oldError = oldState.error ? oldState.error.message : null;
      var newError = error ? error.message : null;
      var isErrorDifferent = oldError !== newError;
      if (isQueryDifferent || isErrorDifferent) {
        if (error == null) {
          onChange({
            query: query,
            queryText: queryText,
            error: error
          });
        } else {
          onChange({
            query: null,
            queryText: queryText,
            error: error
          });
        }
      }
    }
  }, {
    key: "renderTools",
    value: function renderTools(tools) {
      if (!tools) {
        return undefined;
      }
      if (Array.isArray(tools)) {
        return tools.map(function (tool) {
          return /*#__PURE__*/React.createElement(OuiFlexItem, {
            grow: false,
            key: tool.key == null ? undefined : tool.key
          }, tool);
        });
      }
      return /*#__PURE__*/React.createElement(OuiFlexItem, {
        grow: false
      }, tools);
    }
  }, {
    key: "render",
    value: function render() {
      var _this$state = this.state,
        query = _this$state.query,
        queryText = _this$state.queryText,
        error = _this$state.error;
      var _this$props = this.props,
        _this$props$box = _this$props.box;
      _this$props$box = _this$props$box === void 0 ? {
        schema: ''
      } : _this$props$box;
      var schema = _this$props$box.schema,
        box = _objectWithoutProperties(_this$props$box, ["schema"]),
        filters = _this$props.filters,
        toolsLeft = _this$props.toolsLeft,
        toolsRight = _this$props.toolsRight,
        compressed = _this$props.compressed,
        className = _this$props.className;
      var toolsLeftEl = this.renderTools(toolsLeft);
      var filtersBar = !filters ? undefined : /*#__PURE__*/React.createElement(OuiFlexItem, {
        className: "ouiSearchBar__filtersHolder",
        grow: false
      }, /*#__PURE__*/React.createElement(OuiSearchFilters, {
        filters: filters,
        query: query,
        onChange: this.onFiltersChange,
        compressed: compressed
      }));
      var toolsRightEl = this.renderTools(toolsRight);
      return /*#__PURE__*/React.createElement(OuiFlexGroup, {
        gutterSize: compressed ? 's' : 'm',
        alignItems: "center",
        className: className,
        wrap: true
      }, toolsLeftEl, /*#__PURE__*/React.createElement(OuiFlexItem, {
        className: "ouiSearchBar__searchHolder",
        grow: true
      }, /*#__PURE__*/React.createElement(OuiSearchBox, _extends({
        compressed: compressed
      }, box, {
        query: queryText,
        onSearch: this.onSearch,
        isInvalid: error != null,
        title: error ? error.message : undefined
      }))), filtersBar, toolsRightEl);
    }
  }], [{
    key: "getDerivedStateFromProps",
    value: function getDerivedStateFromProps(nextProps, prevState) {
      if ((nextProps.query || nextProps.query === '') && (!prevState.query || typeof nextProps.query !== 'string' && nextProps.query.text !== prevState.query.text || typeof nextProps.query === 'string' && nextProps.query !== prevState.query.text)) {
        var query = parseQuery(nextProps.query, nextProps);
        return {
          query: query,
          queryText: query.text,
          error: null
        };
      }
      return null;
    }
  }]);
  return OuiSearchBar;
}(Component);

/* OUI -> EUI Aliases: Build-Time */
_defineProperty(OuiSearchBar, "Query", Query);
OuiSearchBar.propTypes = {
  onChange: PropTypes.func,
  /**
     The initial query the bar will hold when first mounted
     */
  defaultQuery: PropTypes.oneOfType([PropTypes.any.isRequired, PropTypes.string.isRequired]),
  /**
     If you wish to use the search bar as a controlled component, continuously pass the query via this prop.
     */
  query: PropTypes.oneOfType([PropTypes.any.isRequired, PropTypes.string.isRequired]),
  /**
     Configures the search box. Set `placeholder` to change the placeholder text in the box and `incremental` to support incremental (as you type) search.
     */
  box: PropTypes.shape({
    name: PropTypes.string,
    id: PropTypes.string,
    placeholder: PropTypes.string,
    value: PropTypes.string,
    isInvalid: PropTypes.bool,
    fullWidth: PropTypes.bool,
    isLoading: PropTypes.bool,
    /**
       * Called when the user presses [Enter] OR on change if the incremental prop is `true`.
       * If you don't need the on[Enter] functionality, prefer using onChange
       */
    onSearch: PropTypes.func,
    /**
       * When `true` the search will be executed (that is, the `onSearch` will be called) as the
       * user types.
       */
    incremental: PropTypes.bool,
    /**
       * when `true` creates a shorter height input
       */
    compressed: PropTypes.bool,
    inputRef: PropTypes.func,
    /**
       * Shows a button that quickly clears any input
       */
    isClearable: PropTypes.bool,
    /**
       * Creates an input group with element(s) coming before input
       * `string` | `ReactElement` or an array of these
       */
    prepend: PropTypes.oneOfType([PropTypes.oneOfType([PropTypes.string.isRequired, PropTypes.element.isRequired]).isRequired, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string.isRequired, PropTypes.element.isRequired]).isRequired).isRequired]),
    /**
       * Creates an input group with element(s) coming after input.
       * `string` | `ReactElement` or an array of these
       */
    append: PropTypes.oneOfType([PropTypes.oneOfType([PropTypes.string.isRequired, PropTypes.element.isRequired]).isRequired, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string.isRequired, PropTypes.element.isRequired]).isRequired).isRequired]),
    className: PropTypes.string,
    "aria-label": PropTypes.string,
    "data-test-subj": PropTypes.string,
    // Boolean values are not meaningful to this OuiSearchBox, but are allowed so that other
    // components can use e.g. a true value to mean "auto-derive a schema". See OuiInMemoryTable.
    // Admittedly, this is a bit of a hack.
    schema: PropTypes.oneOfType([PropTypes.shape({
      strict: PropTypes.bool,
      fields: PropTypes.any,
      flags: PropTypes.arrayOf(PropTypes.string.isRequired)
    }).isRequired, PropTypes.bool.isRequired])
  }),
  /**
     An array of search filters. See #SearchFilterConfig.
     */
  filters: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({
    type: PropTypes.oneOf(["is"]).isRequired,
    field: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
    negatedName: PropTypes.string,
    available: PropTypes.func,
    compressed: PropTypes.bool
  }).isRequired, PropTypes.shape({
    type: PropTypes.oneOf(["field_value_selection"]).isRequired,
    field: PropTypes.string,
    name: PropTypes.string.isRequired,
    /**
       * See #FieldValueOptionType
       */
    options: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.shape({
      field: PropTypes.string,
      value: PropTypes.oneOfType([PropTypes.string.isRequired, PropTypes.number.isRequired, PropTypes.bool.isRequired, PropTypes.shape({
        type: PropTypes.oneOf(["date"]).isRequired,
        raw: PropTypes.any.isRequired,
        granularity: PropTypes.oneOfType([PropTypes.shape({
          es: PropTypes.oneOf(["d", "w", "M", "y"]).isRequired,
          js: PropTypes.oneOf(["day", "week", "month", "year"]).isRequired,
          isSame: PropTypes.func.isRequired,
          start: PropTypes.func.isRequired,
          startOfNext: PropTypes.func.isRequired,
          iso8601: PropTypes.func.isRequired
        }).isRequired, PropTypes.oneOf([undefined])]).isRequired,
        text: PropTypes.string.isRequired,
        resolve: PropTypes.func.isRequired
      }).isRequired]).isRequired,
      name: PropTypes.string,
      view: PropTypes.node
    }).isRequired).isRequired, PropTypes.func.isRequired]).isRequired,
    filterWith: PropTypes.oneOfType([PropTypes.oneOf(["prefix", "includes"]), PropTypes.func.isRequired]),
    cache: PropTypes.number,
    multiSelect: PropTypes.oneOfType([PropTypes.bool.isRequired, PropTypes.oneOf(["and", "or"])]),
    loadingMessage: PropTypes.string,
    noOptionsMessage: PropTypes.string,
    searchThreshold: PropTypes.number,
    available: PropTypes.func,
    autoClose: PropTypes.bool,
    operator: PropTypes.oneOf(["eq", "exact", "gt", "gte", "lt", "lte"]),
    compressed: PropTypes.bool
  }).isRequired, PropTypes.shape({
    type: PropTypes.oneOf(["field_value_toggle"]).isRequired,
    field: PropTypes.string.isRequired,
    value: PropTypes.oneOfType([PropTypes.string.isRequired, PropTypes.number.isRequired, PropTypes.bool.isRequired, PropTypes.shape({
      type: PropTypes.oneOf(["date"]).isRequired,
      raw: PropTypes.any.isRequired,
      granularity: PropTypes.oneOfType([PropTypes.shape({
        es: PropTypes.oneOf(["d", "w", "M", "y"]).isRequired,
        js: PropTypes.oneOf(["day", "week", "month", "year"]).isRequired,
        isSame: PropTypes.func.isRequired,
        start: PropTypes.func.isRequired,
        startOfNext: PropTypes.func.isRequired,
        iso8601: PropTypes.func.isRequired
      }).isRequired, PropTypes.oneOf([undefined])]).isRequired,
      text: PropTypes.string.isRequired,
      resolve: PropTypes.func.isRequired
    }).isRequired]).isRequired,
    name: PropTypes.string.isRequired,
    negatedName: PropTypes.string,
    available: PropTypes.func,
    operator: PropTypes.oneOf(["eq", "exact", "gt", "gte", "lt", "lte"]),
    compressed: PropTypes.bool
  }).isRequired, PropTypes.shape({
    type: PropTypes.oneOf(["field_value_toggle_group"]).isRequired,
    field: PropTypes.string.isRequired,
    /**
       * See #FieldValueToggleGroupFilterItemType
       */
    items: PropTypes.arrayOf(PropTypes.shape({
      value: PropTypes.oneOfType([PropTypes.string.isRequired, PropTypes.number.isRequired, PropTypes.bool.isRequired]).isRequired,
      name: PropTypes.string.isRequired,
      negatedName: PropTypes.string,
      operator: PropTypes.oneOf(["eq", "exact", "gt", "gte", "lt", "lte"])
    }).isRequired).isRequired,
    available: PropTypes.func,
    compressed: PropTypes.bool
  }).isRequired]).isRequired),
  /**
     * Tools which go to the left of the search bar.
     */
  toolsLeft: PropTypes.oneOfType([PropTypes.element.isRequired, PropTypes.arrayOf(PropTypes.element.isRequired).isRequired]),
  /**
     * Tools which go to the right of the search bar.
     */
  toolsRight: PropTypes.oneOfType([PropTypes.element.isRequired, PropTypes.arrayOf(PropTypes.element.isRequired).isRequired]),
  /**
     * Date formatter to use when parsing date values
     */
  dateFormat: PropTypes.any,
  compressed: PropTypes.bool,
  // @deprecated This property has never been consumed despite being defined
  "aria-label": PropTypes.string,
  // @deprecated This property has never been consumed despite being defined
  "data-test-subj": PropTypes.string,
  className: PropTypes.string
};
/* OUI -> EUI Aliases: Build-Time */export { EuiSearchBar } from '../../eui_components/search_bar/search_bar';