mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* [Discover] Add telemetry around query/filter bar usage * Updating documentation * Adding a separate method for tracking query submit * Updating doc changes * Adding trackUiMetric to Data plugin * Doc changes * Do not make usageCollection a start dependency * Updating documentation * Adding metrics for filter inclusion, edit, and disabled * updating docs Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
05286a6190
commit
2e3421132a
7 changed files with 39 additions and 5 deletions
|
@ -7,7 +7,7 @@
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
SearchBar: React.ComponentClass<Pick<Pick<SearchBarProps, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "intl" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated">, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated">, any> & {
|
||||
WrappedComponent: React.ComponentType<Pick<SearchBarProps, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "intl" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated"> & ReactIntl.InjectedIntlProps>;
|
||||
SearchBar: React.ComponentClass<Pick<Pick<SearchBarProps, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "intl" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "trackUiMetric" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated">, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "trackUiMetric" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated">, any> & {
|
||||
WrappedComponent: React.ComponentType<Pick<SearchBarProps, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "intl" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "trackUiMetric" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated"> & ReactIntl.InjectedIntlProps>;
|
||||
}
|
||||
```
|
||||
|
|
|
@ -73,6 +73,7 @@ import {
|
|||
|
||||
import { SavedObjectsClientPublicToCommon } from './index_patterns';
|
||||
import { indexPatternLoad } from './index_patterns/expressions/load_index_pattern';
|
||||
import { UsageCollectionSetup } from '../../usage_collection/public';
|
||||
|
||||
declare module '../../ui_actions/public' {
|
||||
export interface ActionContextMapping {
|
||||
|
@ -95,6 +96,7 @@ export class DataPublicPlugin
|
|||
private readonly fieldFormatsService: FieldFormatsService;
|
||||
private readonly queryService: QueryService;
|
||||
private readonly storage: IStorageWrapper;
|
||||
private usageCollection: UsageCollectionSetup | undefined;
|
||||
|
||||
constructor(initializerContext: PluginInitializerContext<ConfigSchema>) {
|
||||
this.searchService = new SearchService(initializerContext);
|
||||
|
@ -113,6 +115,8 @@ export class DataPublicPlugin
|
|||
expressions.registerFunction(esaggs);
|
||||
expressions.registerFunction(indexPatternLoad);
|
||||
|
||||
this.usageCollection = usageCollection;
|
||||
|
||||
const queryService = this.queryService.setup({
|
||||
uiSettings: core.uiSettings,
|
||||
storage: this.storage,
|
||||
|
@ -213,6 +217,7 @@ export class DataPublicPlugin
|
|||
core,
|
||||
data: dataServices,
|
||||
storage: this.storage,
|
||||
trackUiMetric: this.usageCollection?.reportUiStats.bind(this.usageCollection, 'data_plugin'),
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -84,6 +84,7 @@ import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport';
|
|||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { UiActionsSetup } from 'src/plugins/ui_actions/public';
|
||||
import { UiActionsStart } from 'src/plugins/ui_actions/public';
|
||||
import { UiStatsMetricType } from '@kbn/analytics';
|
||||
import { Unit } from '@elastic/datemath';
|
||||
import { UnregisterCallback } from 'history';
|
||||
import { UserProvidedValues } from 'src/core/server/types';
|
||||
|
@ -2004,8 +2005,8 @@ export const search: {
|
|||
// Warning: (ae-missing-release-tag) "SearchBar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const SearchBar: React.ComponentClass<Pick<Pick<SearchBarProps, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "intl" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated">, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated">, any> & {
|
||||
WrappedComponent: React.ComponentType<Pick<SearchBarProps, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "intl" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated"> & ReactIntl.InjectedIntlProps>;
|
||||
export const SearchBar: React.ComponentClass<Pick<Pick<SearchBarProps, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "intl" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "trackUiMetric" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated">, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "trackUiMetric" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated">, any> & {
|
||||
WrappedComponent: React.ComponentType<Pick<SearchBarProps, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "intl" | "indexPatterns" | "dataTestSubj" | "screenTitle" | "showQueryInput" | "showDatePicker" | "showAutoRefreshOnly" | "dateRangeFrom" | "dateRangeTo" | "isRefreshPaused" | "customSubmitButton" | "timeHistory" | "indicateNoData" | "onFiltersUpdated" | "trackUiMetric" | "savedQuery" | "showSaveQuery" | "onClearSavedQuery" | "showQueryBar" | "showFilterBar" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated"> & ReactIntl.InjectedIntlProps>;
|
||||
};
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "SearchBarOwnProps" needs to be exported by the entry point index.d.ts
|
||||
|
|
|
@ -22,6 +22,7 @@ import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
|||
import classNames from 'classnames';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { METRIC_TYPE, UiStatsMetricType } from '@kbn/analytics';
|
||||
import { FilterEditor } from './filter_editor';
|
||||
import { FILTER_EDITOR_WIDTH, FilterItem } from './filter_item';
|
||||
import { FilterOptions } from './filter_options';
|
||||
|
@ -45,6 +46,9 @@ interface Props {
|
|||
className: string;
|
||||
indexPatterns: IIndexPattern[];
|
||||
intl: InjectedIntl;
|
||||
appName: string;
|
||||
// Track UI Metrics
|
||||
trackUiMetric?: (metricType: UiStatsMetricType, eventName: string | string[]) => void;
|
||||
}
|
||||
|
||||
function FilterBarUI(props: Props) {
|
||||
|
@ -128,6 +132,9 @@ function FilterBarUI(props: Props) {
|
|||
|
||||
function onAdd(filter: Filter) {
|
||||
setIsAddFilterPopoverOpen(false);
|
||||
if (props.trackUiMetric) {
|
||||
props.trackUiMetric(METRIC_TYPE.CLICK, `${props.appName}:filter_added`);
|
||||
}
|
||||
const filters = [...props.filters, filter];
|
||||
onFiltersUpdated(filters);
|
||||
}
|
||||
|
@ -139,6 +146,9 @@ function FilterBarUI(props: Props) {
|
|||
}
|
||||
|
||||
function onUpdate(i: number, filter: Filter) {
|
||||
if (props.trackUiMetric) {
|
||||
props.trackUiMetric(METRIC_TYPE.CLICK, `${props.appName}:filter_edited`);
|
||||
}
|
||||
const filters = [...props.filters];
|
||||
filters[i] = filter;
|
||||
onFiltersUpdated(filters);
|
||||
|
@ -165,11 +175,17 @@ function FilterBarUI(props: Props) {
|
|||
}
|
||||
|
||||
function onToggleAllNegated() {
|
||||
if (props.trackUiMetric) {
|
||||
props.trackUiMetric(METRIC_TYPE.CLICK, `${props.appName}:filter_invertInclusion`);
|
||||
}
|
||||
const filters = props.filters.map(toggleFilterNegated);
|
||||
onFiltersUpdated(filters);
|
||||
}
|
||||
|
||||
function onToggleAllDisabled() {
|
||||
if (props.trackUiMetric) {
|
||||
props.trackUiMetric(METRIC_TYPE.CLICK, `${props.appName}:filter_toggleAllDisabled`);
|
||||
}
|
||||
const filters = props.filters.map(toggleFilterDisabled);
|
||||
onFiltersUpdated(filters);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import _ from 'lodash';
|
|||
import React, { useEffect, useRef } from 'react';
|
||||
import { CoreStart } from 'src/core/public';
|
||||
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
|
||||
import { UiStatsMetricType } from '@kbn/analytics';
|
||||
import { KibanaContextProvider } from '../../../../kibana_react/public';
|
||||
import { QueryStart, SavedQuery } from '../../query';
|
||||
import { SearchBar, SearchBarOwnProps } from './';
|
||||
|
@ -35,6 +36,7 @@ interface StatefulSearchBarDeps {
|
|||
core: CoreStart;
|
||||
data: Omit<DataPublicPluginStart, 'ui'>;
|
||||
storage: IStorageWrapper;
|
||||
trackUiMetric?: (metricType: UiStatsMetricType, eventName: string | string[]) => void;
|
||||
}
|
||||
|
||||
export type StatefulSearchBarProps = SearchBarOwnProps & {
|
||||
|
@ -119,7 +121,7 @@ const overrideDefaultBehaviors = (props: StatefulSearchBarProps) => {
|
|||
return props.useDefaultBehaviors ? {} : props;
|
||||
};
|
||||
|
||||
export function createSearchBar({ core, storage, data }: StatefulSearchBarDeps) {
|
||||
export function createSearchBar({ core, storage, data, trackUiMetric }: StatefulSearchBarDeps) {
|
||||
// App name should come from the core application service.
|
||||
// Until it's available, we'll ask the user to provide it for the pre-wired component.
|
||||
return (props: StatefulSearchBarProps) => {
|
||||
|
@ -197,6 +199,7 @@ export function createSearchBar({ core, storage, data }: StatefulSearchBarDeps)
|
|||
onClearSavedQuery={defaultOnClearSavedQuery(props, clearSavedQuery)}
|
||||
onSavedQueryUpdated={defaultOnSavedQueryUpdated(props, setSavedQuery)}
|
||||
onSaved={defaultOnSavedQueryUpdated(props, setSavedQuery)}
|
||||
trackUiMetric={trackUiMetric}
|
||||
{...overrideDefaultBehaviors(props)}
|
||||
/>
|
||||
</KibanaContextProvider>
|
||||
|
|
|
@ -24,6 +24,7 @@ import React, { Component } from 'react';
|
|||
import ResizeObserver from 'resize-observer-polyfill';
|
||||
import { get, isEqual } from 'lodash';
|
||||
|
||||
import { METRIC_TYPE, UiStatsMetricType } from '@kbn/analytics';
|
||||
import { withKibana, KibanaReactContextValue } from '../../../../kibana_react/public';
|
||||
|
||||
import QueryBarTopRow from '../query_string_input/query_bar_top_row';
|
||||
|
@ -78,6 +79,8 @@ export interface SearchBarOwnProps {
|
|||
|
||||
onRefresh?: (payload: { dateRange: TimeRange }) => void;
|
||||
indicateNoData?: boolean;
|
||||
// Track UI Metrics
|
||||
trackUiMetric?: (metricType: UiStatsMetricType, eventName: string | string[]) => void;
|
||||
}
|
||||
|
||||
export type SearchBarProps = SearchBarOwnProps & SearchBarInjectedDeps;
|
||||
|
@ -331,6 +334,9 @@ class SearchBarUI extends Component<SearchBarProps, State> {
|
|||
},
|
||||
});
|
||||
}
|
||||
if (this.props.trackUiMetric) {
|
||||
this.props.trackUiMetric(METRIC_TYPE.CLICK, `${this.services.appName}:query_submitted`);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -432,6 +438,8 @@ class SearchBarUI extends Component<SearchBarProps, State> {
|
|||
filters={this.props.filters!}
|
||||
onFiltersUpdated={this.props.onFiltersUpdated}
|
||||
indexPatterns={this.props.indexPatterns!}
|
||||
appName={this.services.appName}
|
||||
trackUiMetric={this.props.trackUiMetric}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -80,6 +80,7 @@ import { TransportRequestParams } from '@elastic/elasticsearch/lib/Transport';
|
|||
import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport';
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { UiComponent } from 'src/plugins/kibana_utils/public';
|
||||
import { UiStatsMetricType } from '@kbn/analytics';
|
||||
import { UnregisterCallback } from 'history';
|
||||
import { UserProvidedValues } from 'src/core/server/types';
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue