"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _lodash = require("lodash"); var _i18nReact = require("@kbn/i18n-react"); var _classnames = _interopRequireDefault(require("classnames")); var _react = _interopRequireWildcard(require("react")); var _eui = require("@elastic/eui"); var _memoizeOne = _interopRequireDefault(require("memoize-one")); var _analytics = require("@kbn/analytics"); var _esQuery = require("@kbn/es-query"); var _public = require("@kbn/kibana-react-plugin/public"); var _saved_query_form = require("../saved_query_form"); var _saved_query_management = require("../saved_query_management"); var _query_bar_menu = require("../query_string_input/query_bar_menu"); var _query_bar_top_row = _interopRequireDefault(require("../query_string_input/query_bar_top_row")); var _filter_bar = require("../filter_bar"); var _search_bar = require("./search_bar.styles"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ class SearchBarUI extends _react.Component { constructor(...args) { super(...args); (0, _defineProperty2.default)(this, "services", this.props.kibana.services); (0, _defineProperty2.default)(this, "savedQueryService", this.services.data.query.savedQueries); /* Keep the "draft" value in local state until the user actually submits the query. There are a couple advantages: 1. Each app doesn't have to maintain its own "draft" value if it wants to put off updating the query in app state until the user manually submits their changes. Most apps have watches on the query value in app state so we don't want to trigger those on every keypress. Also, some apps (e.g. dashboard) already juggle multiple query values, each with slightly different semantics and I'd rather not add yet another variable to the mix. 2. Changes to the local component state won't trigger an Angular digest cycle. Triggering digest cycles on every keypress has been a major source of performance issues for us in previous implementations of the query bar. See https://github.com/elastic/kibana/issues/14086 */ (0, _defineProperty2.default)(this, "state", { isFiltersVisible: true, openQueryBarMenu: false, showSavedQueryPopover: false, currentProps: this.props, query: this.props.query ? { ...this.props.query } : undefined, dateRangeFrom: (0, _lodash.get)(this.props, 'dateRangeFrom', 'now-15m'), dateRangeTo: (0, _lodash.get)(this.props, 'dateRangeTo', 'now') }); (0, _defineProperty2.default)(this, "isDirty", () => { if (!this.props.showDatePicker && this.state.query && this.props.query) { return !(0, _lodash.isEqual)(this.state.query, this.props.query); } return this.state.query && this.props.query && !(0, _lodash.isEqual)(this.state.query, this.props.query) || this.state.dateRangeFrom !== this.props.dateRangeFrom || this.state.dateRangeTo !== this.props.dateRangeTo; }); (0, _defineProperty2.default)(this, "onSave", async (savedQueryMeta, saveAsNew = false) => { if (!this.state.query) return; const savedQueryAttributes = { title: savedQueryMeta.title, description: savedQueryMeta.description, query: this.state.query }; if (savedQueryMeta.shouldIncludeFilters) { savedQueryAttributes.filters = this.props.filters; } if (savedQueryMeta.shouldIncludeTimefilter && this.state.dateRangeTo !== undefined && this.state.dateRangeFrom !== undefined && this.props.refreshInterval !== undefined && this.props.isRefreshPaused !== undefined) { savedQueryAttributes.timefilter = { from: this.state.dateRangeFrom, to: this.state.dateRangeTo, refreshInterval: { value: this.props.refreshInterval, pause: this.props.isRefreshPaused } }; } try { let response; if (this.props.savedQuery && !saveAsNew) { response = await this.savedQueryService.updateQuery(savedQueryMeta.id, savedQueryAttributes); } else { response = await this.savedQueryService.createQuery(savedQueryAttributes); } this.services.notifications.toasts.addSuccess(`Your query "${response.attributes.title}" was saved`); if (this.props.onSaved) { this.props.onSaved(response); } } catch (error) { this.services.notifications.toasts.addDanger(`An error occured while saving your query: ${error.message}`); throw error; } }); (0, _defineProperty2.default)(this, "onQueryBarChange", queryAndDateRange => { this.setState({ query: queryAndDateRange.query, dateRangeFrom: queryAndDateRange.dateRange.from, dateRangeTo: queryAndDateRange.dateRange.to }); if (this.props.onQueryChange) { this.props.onQueryChange(queryAndDateRange); } }); (0, _defineProperty2.default)(this, "onTextLangQueryChange", query => { this.setState({ query }); if (this.props.onQueryChange) { this.props.onQueryChange({ query, dateRange: { from: this.state.dateRangeFrom, to: this.state.dateRangeTo } }); } }); (0, _defineProperty2.default)(this, "toggleFilterBarMenuPopover", value => { this.setState({ openQueryBarMenu: value }); }); (0, _defineProperty2.default)(this, "onTextLangQuerySubmit", query => { var _this$props$onFilters, _this$props; // clean up all filters (_this$props$onFilters = (_this$props = this.props).onFiltersUpdated) === null || _this$props$onFilters === void 0 ? void 0 : _this$props$onFilters.call(_this$props, []); this.setState({ query: query }, () => { if (this.props.onQuerySubmit) { this.props.onQuerySubmit({ query: query, dateRange: { from: this.state.dateRangeFrom, to: this.state.dateRangeTo } }); } }); }); (0, _defineProperty2.default)(this, "onQueryBarSubmit", queryAndDateRange => { this.setState({ query: queryAndDateRange.query, dateRangeFrom: queryAndDateRange.dateRange && queryAndDateRange.dateRange.from || this.state.dateRangeFrom, dateRangeTo: queryAndDateRange.dateRange && queryAndDateRange.dateRange.to || this.state.dateRangeTo }, () => { var _this$services$usageC; if (this.props.onQuerySubmit) { this.props.onQuerySubmit({ query: this.state.query, dateRange: { from: this.state.dateRangeFrom, to: this.state.dateRangeTo } }); } (_this$services$usageC = this.services.usageCollection) === null || _this$services$usageC === void 0 ? void 0 : _this$services$usageC.reportUiCounter(this.services.appName, _analytics.METRIC_TYPE.CLICK, 'query_submitted'); }); }); (0, _defineProperty2.default)(this, "onLoadSavedQuery", savedQuery => { const dateRangeFrom = (0, _lodash.get)(savedQuery, 'attributes.timefilter.from', this.state.dateRangeFrom); const dateRangeTo = (0, _lodash.get)(savedQuery, 'attributes.timefilter.to', this.state.dateRangeTo); this.setState({ query: savedQuery.attributes.query, dateRangeFrom, dateRangeTo }); if (this.props.onSavedQueryUpdated) { this.props.onSavedQueryUpdated(savedQuery); } }); (0, _defineProperty2.default)(this, "renderSavedQueryManagement", (0, _memoizeOne.default)((onClearSavedQuery, showSaveQuery, savedQuery) => { const savedQueryManagement = onClearSavedQuery && /*#__PURE__*/_react.default.createElement(_saved_query_management.SavedQueryManagementList, { showSaveQuery: showSaveQuery, loadedSavedQuery: savedQuery, onLoad: this.onLoadSavedQuery, savedQueryService: this.savedQueryService, onClearSavedQuery: onClearSavedQuery, onClose: () => this.setState({ openQueryBarMenu: false }), hasFiltersOrQuery: this.hasFiltersOrQuery() }); return savedQueryManagement; })); } static getDerivedStateFromProps(nextProps, prevState) { if ((0, _lodash.isEqual)(prevState.currentProps, nextProps)) { return null; } let nextQuery = null; if (nextProps.query && (0, _esQuery.isOfQueryType)(nextProps.query) && nextProps.query.query !== (0, _lodash.get)(prevState, 'currentProps.query.query')) { nextQuery = { query: nextProps.query.query, language: nextProps.query.language }; } else if (nextProps.query && prevState.query && (0, _esQuery.isOfQueryType)(nextProps.query) && (0, _esQuery.isOfQueryType)(prevState.query) && nextProps.query.language !== prevState.query.language) { nextQuery = { query: '', language: nextProps.query.language }; } else if (nextProps.query && !(0, _esQuery.isOfQueryType)(nextProps.query)) { nextQuery = nextProps.query; } let nextDateRange = null; if (nextProps.dateRangeFrom !== (0, _lodash.get)(prevState, 'currentProps.dateRangeFrom') || nextProps.dateRangeTo !== (0, _lodash.get)(prevState, 'currentProps.dateRangeTo')) { nextDateRange = { dateRangeFrom: nextProps.dateRangeFrom, dateRangeTo: nextProps.dateRangeTo }; } const nextState = { currentProps: nextProps }; if (nextQuery) { nextState.query = nextQuery; } if (nextDateRange) { nextState.dateRangeFrom = nextDateRange.dateRangeFrom; nextState.dateRangeTo = nextDateRange.dateRangeTo; /** * Some applications do not rely on the _g url parameter to update the time. The onTimeRangeChange * callback can be used in these cases to notify the consumer for the time change. */ if (nextDateRange.dateRangeFrom && nextDateRange.dateRangeTo) { var _nextProps$onTimeRang; nextProps === null || nextProps === void 0 ? void 0 : (_nextProps$onTimeRang = nextProps.onTimeRangeChange) === null || _nextProps$onTimeRang === void 0 ? void 0 : _nextProps$onTimeRang.call(nextProps, { dateRange: { from: nextDateRange.dateRangeFrom, to: nextDateRange.dateRangeTo } }); } } return nextState; } componentWillUnmount() { this.renderSavedQueryManagement.clear(); } shouldRenderFilterBar() { return this.props.showFilterBar && this.props.filters && this.props.indexPatterns && (0, _lodash.compact)(this.props.indexPatterns).length > 0; } /* * This Function is here to show the toggle in saved query form * in case you the date range (from/to) */ shouldRenderTimeFilterInSavedQueryForm() { const { dateRangeFrom, dateRangeTo, showDatePicker, indexPatterns } = this.props; if (!showDatePicker && dateRangeFrom !== undefined && dateRangeTo !== undefined) { return false; } if (indexPatterns !== null && indexPatterns !== void 0 && indexPatterns.length) { // return true if at least one of the DateView has timeFieldName return indexPatterns.some(dataView => Boolean(dataView.timeFieldName)); } return true; } shouldShowDatePickerAsBadge() { return this.shouldRenderFilterBar() && !this.props.showQueryInput; } render() { var _this$state, _this$state2, _this$state2$query; const { theme } = this.props; const isScreenshotMode = this.props.isScreenshotMode === true; const styles = (0, _search_bar.searchBarStyles)(theme); const cssStyles = [styles.uniSearchBar, this.props.displayStyle && styles[this.props.displayStyle], isScreenshotMode && styles.hidden]; const classes = (0, _classnames.default)('uniSearchBar', { [`uniSearchBar--hidden`]: isScreenshotMode, [`uniSearchBar--${this.props.displayStyle}`]: this.props.displayStyle }); const timeRangeForSuggestionsOverride = this.props.showDatePicker ? undefined : false; const saveAsNewQueryFormComponent = /*#__PURE__*/_react.default.createElement(_saved_query_form.SaveQueryForm, { savedQueryService: this.savedQueryService, onSave: savedQueryMeta => this.onSave(savedQueryMeta, true), onClose: () => this.setState({ openQueryBarMenu: false }), showFilterOption: this.props.showFilterBar, showTimeFilterOption: this.shouldRenderTimeFilterInSavedQueryForm() }); const saveQueryFormComponent = /*#__PURE__*/_react.default.createElement(_saved_query_form.SaveQueryForm, { savedQuery: this.props.savedQuery ? this.props.savedQuery : undefined, savedQueryService: this.savedQueryService, onSave: this.onSave, onClose: () => this.setState({ openQueryBarMenu: false }), showFilterOption: this.props.showFilterBar, showTimeFilterOption: this.shouldRenderTimeFilterInSavedQueryForm() }); const queryBarMenu = this.props.showQueryMenu ? /*#__PURE__*/_react.default.createElement(_query_bar_menu.QueryBarMenu, { nonKqlMode: this.props.nonKqlMode, disableQueryLanguageSwitcher: this.props.disableQueryLanguageSwitcher, language: this.state.query && (0, _esQuery.isOfQueryType)((_this$state = this.state) === null || _this$state === void 0 ? void 0 : _this$state.query) ? (_this$state2 = this.state) === null || _this$state2 === void 0 ? void 0 : (_this$state2$query = _this$state2.query) === null || _this$state2$query === void 0 ? void 0 : _this$state2$query.language : 'kuery', onQueryChange: this.onQueryBarChange, onQueryBarSubmit: this.onQueryBarSubmit, dateRangeFrom: this.state.dateRangeFrom, dateRangeTo: this.state.dateRangeTo, savedQueryService: this.savedQueryService, saveAsNewQueryFormComponent: saveAsNewQueryFormComponent, saveFormComponent: saveQueryFormComponent, toggleFilterBarMenuPopover: this.toggleFilterBarMenuPopover, openQueryBarMenu: this.state.openQueryBarMenu, onFiltersUpdated: this.props.onFiltersUpdated, filters: this.props.filters, hiddenPanelOptions: this.props.hiddenFilterPanelOptions, query: this.state.query, savedQuery: this.props.savedQuery, onClearSavedQuery: this.props.onClearSavedQuery, showQueryInput: this.props.showQueryInput, showFilterBar: this.props.showFilterBar, showSaveQuery: this.props.showSaveQuery, isDisabled: this.props.isDisabled, buttonProps: { size: this.shouldShowDatePickerAsBadge() ? 's' : 'm' }, indexPatterns: this.props.indexPatterns, timeRangeForSuggestionsOverride: timeRangeForSuggestionsOverride, filtersForSuggestions: this.props.filtersForSuggestions, manageFilterSetComponent: this.props.showFilterBar && this.state.query ? this.renderSavedQueryManagement(this.props.onClearSavedQuery, this.props.showSaveQuery, this.props.savedQuery) : undefined, suggestionsAbstraction: this.props.suggestionsAbstraction }) : undefined; let filterBar; if (this.shouldRenderFilterBar()) { filterBar = this.shouldShowDatePickerAsBadge() ? /*#__PURE__*/_react.default.createElement(_filter_bar.FilterItems, { filters: this.props.filters, onFiltersUpdated: this.props.onFiltersUpdated, indexPatterns: this.props.indexPatterns, timeRangeForSuggestionsOverride: timeRangeForSuggestionsOverride, filtersForSuggestions: this.props.filtersForSuggestions, hiddenPanelOptions: this.props.hiddenFilterPanelOptions, readOnly: this.props.isDisabled, suggestionsAbstraction: this.props.suggestionsAbstraction }) : /*#__PURE__*/_react.default.createElement(_filter_bar.FilterBar, { afterQueryBar: true, filters: this.props.filters, onFiltersUpdated: this.props.onFiltersUpdated, indexPatterns: this.props.indexPatterns, timeRangeForSuggestionsOverride: timeRangeForSuggestionsOverride, filtersForSuggestions: this.props.filtersForSuggestions, hiddenPanelOptions: this.props.hiddenFilterPanelOptions, isDisabled: this.props.isDisabled, "data-test-subj": "unifiedFilterBar", prepend: this.props.prependFilterBar, suggestionsAbstraction: this.props.suggestionsAbstraction }); } return /*#__PURE__*/_react.default.createElement("div", { className: classes, css: cssStyles, "data-test-subj": "globalQueryBar" }, /*#__PURE__*/_react.default.createElement(_query_bar_top_row.default, { timeHistory: this.props.timeHistory, query: this.state.query, screenTitle: this.props.screenTitle, onSubmit: this.onQueryBarSubmit, indexPatterns: this.props.indexPatterns, isLoading: this.props.isLoading, fillSubmitButton: this.props.fillSubmitButton || false, prepend: this.props.showFilterBar || this.props.showQueryInput ? queryBarMenu : undefined, showDatePicker: this.props.showDatePicker, dateRangeFrom: this.state.dateRangeFrom, dateRangeTo: this.state.dateRangeTo, isRefreshPaused: this.props.isRefreshPaused, refreshInterval: this.props.refreshInterval, showAutoRefreshOnly: this.props.showAutoRefreshOnly, showQueryInput: this.props.showQueryInput, showAddFilter: this.props.showFilterBar, isDisabled: this.props.isDisabled, onRefresh: this.props.onRefresh, onRefreshChange: this.props.onRefreshChange, onChange: this.onQueryBarChange, isDirty: this.isDirty(), customSubmitButton: this.props.customSubmitButton ? this.props.customSubmitButton : undefined, dataViewPickerOverride: this.props.dataViewPickerOverride, showSubmitButton: this.props.showSubmitButton, submitButtonStyle: this.props.submitButtonStyle, dataTestSubj: this.props.dataTestSubj, indicateNoData: this.props.indicateNoData, placeholder: this.props.placeholder, isClearable: this.props.isClearable, iconType: this.props.iconType, nonKqlMode: this.props.nonKqlMode, timeRangeForSuggestionsOverride: timeRangeForSuggestionsOverride, filtersForSuggestions: this.props.filtersForSuggestions, filters: this.props.filters, onFiltersUpdated: this.props.onFiltersUpdated, dataViewPickerComponentProps: this.props.dataViewPickerComponentProps, textBasedLanguageModeErrors: this.props.textBasedLanguageModeErrors, onTextBasedSavedAndExit: this.props.onTextBasedSavedAndExit, showDatePickerAsBadge: this.shouldShowDatePickerAsBadge(), filterBar: filterBar, suggestionsSize: this.props.suggestionsSize, isScreenshotMode: this.props.isScreenshotMode, onTextLangQuerySubmit: this.onTextLangQuerySubmit, onTextLangQueryChange: this.onTextLangQueryChange, submitOnBlur: this.props.submitOnBlur, suggestionsAbstraction: this.props.suggestionsAbstraction })); } hasFiltersOrQuery() { const hasFilters = Boolean(this.props.filters && this.props.filters.length > 0); const hasQuery = Boolean(this.state.query && (0, _esQuery.isOfQueryType)(this.state.query) && this.state.query.query); return hasFilters || hasQuery; } } // Needed for React.lazy // eslint-disable-next-line import/no-default-export (0, _defineProperty2.default)(SearchBarUI, "defaultProps", { showQueryMenu: true, showFilterBar: true, showDatePicker: true, showSubmitButton: true, showAutoRefreshOnly: false, filtersForSuggestions: [] }); var _default = (0, _i18nReact.injectI18n)((0, _eui.withEuiTheme)((0, _public.withKibana)(SearchBarUI))); exports.default = _default; module.exports = exports.default;