diff --git a/x-pack/solutions/search/plugins/search_query_rules/kibana.jsonc b/x-pack/solutions/search/plugins/search_query_rules/kibana.jsonc index ff86761f1e9e7..3146b2c38688b 100644 --- a/x-pack/solutions/search/plugins/search_query_rules/kibana.jsonc +++ b/x-pack/solutions/search/plugins/search_query_rules/kibana.jsonc @@ -19,6 +19,7 @@ "console", "searchNavigation", "share", + "usageCollection", ], "requiredBundles": [ "kibanaReact", diff --git a/x-pack/solutions/search/plugins/search_query_rules/public/analytics/constants.ts b/x-pack/solutions/search/plugins/search_query_rules/public/analytics/constants.ts new file mode 100644 index 0000000000000..0630cbeed7e1d --- /dev/null +++ b/x-pack/solutions/search/plugins/search_query_rules/public/analytics/constants.ts @@ -0,0 +1,42 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export enum AnalyticsEvents { + // Empty promp actions + gettingStartedButtonClicked = 'getting_started_button_clicked', + createInConsoleClicked = 'create_in_console_clicked', + emptyPromptLoaded = 'empty_prompt_loaded', + + // Error prompt loaded + genericErrorPromptLoaded = 'generic_error_prompt_loaded', + notFoundErrorPromptLoaded = 'not_found_error_prompt_loaded', + missingPermissionsErrorPromptLoaded = 'missing_permissions_error_prompt_loaded', + + rulesetCreateClicked = 'ruleset_create_clicked', + rulesetUpdateClicked = 'ruleset_update_clicked', + + // ruleset detail page actions + rulesetDetailPageLoaded = 'ruleset_details_page_loaded', + addRuleClicked = 'add_rule_clicked', + editRuleClicked = 'edit_rule_clicked', + deleteRuleClicked = 'delete_rule_clicked', + testInConsoleClicked = 'test_in_console_clicked', + deleteRulesetFromHeaderClicked = 'delete_ruleset_from_header_clicked', + backToRulesetListClicked = 'back_to_ruleset_list_clicked', + + rulesReordered = 'rules_reordered', + ruleFlyoutDocumentsReordered = 'rule_flyout_documents_reordered', + + // ruleset list page actions + editRulesetInlineNameClicked = 'edit_ruleset_inline_name_clicked', + editRulesetInlineDropdownClicked = 'edit_ruleset_inline_dropdown_clicked', + rulesetListPageLoaded = 'ruleset_list_page_loaded', + deleteRulesetInlineDropdownClicked = 'delete_ruleset_inline_dropdown_clicked', + testRulesetInlineDropdownClicked = 'test_ruleset_inline_dropdown_clicked', + rulesetSearched = 'ruleset_searched', + addRulesetClicked = 'add_ruleset_clicked', +} diff --git a/x-pack/solutions/search/plugins/search_query_rules/public/components/empty_prompt/empty_prompt.tsx b/x-pack/solutions/search/plugins/search_query_rules/public/components/empty_prompt/empty_prompt.tsx index 77b0c15995656..0fc16616fd131 100644 --- a/x-pack/solutions/search/plugins/search_query_rules/public/components/empty_prompt/empty_prompt.tsx +++ b/x-pack/solutions/search/plugins/search_query_rules/public/components/empty_prompt/empty_prompt.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { useEffect } from 'react'; import { EuiButton, @@ -35,14 +35,22 @@ import { useKibana } from '../../hooks/use_kibana'; import queryRulesImg from '../../assets/query-rules-context-alt.svg'; import queryRulesDarkImg from '../../assets/query-rules-context-alt-dark.svg'; import backgroundPanelImg from '../../assets/query-rule-panel-background.svg'; +import { AnalyticsEvents } from '../../analytics/constants'; +import { useUsageTracker } from '../../hooks/use_usage_tracker'; import backgroundPaneDarklImg from '../../assets/query-rule-panel-background-dark.svg'; interface EmptyPromptProps { getStartedAction: () => void; } export const EmptyPrompt: React.FC = ({ getStartedAction }) => { + const usageTracker = useUsageTracker(); const { application, share, console: consolePlugin } = useKibana().services; const { euiTheme, colorMode } = useEuiTheme(); + + useEffect(() => { + usageTracker?.load(AnalyticsEvents.emptyPromptLoaded); + }, [usageTracker]); + const gradientOverlay = css({ background: `linear-gradient(180deg, ${transparentize( euiTheme.colors.backgroundBasePlain, @@ -101,7 +109,10 @@ export const EmptyPrompt: React.FC = ({ getStartedAction }) => data-test-subj="searchQueryRulesEmptyPromptGetStartedButton" color="primary" fill - onClick={getStartedAction} + onClick={() => { + usageTracker?.click(AnalyticsEvents.gettingStartedButtonClicked); + getStartedAction(); + }} > = ({ getStartedAction }) => defaultMessage: 'Create in Console', })} showIcon + data-test-subj={AnalyticsEvents.createInConsoleClicked} /> diff --git a/x-pack/solutions/search/plugins/search_query_rules/public/components/error_prompt/error_prompt.tsx b/x-pack/solutions/search/plugins/search_query_rules/public/components/error_prompt/error_prompt.tsx index 8cba31940be83..c0d677f2d9cf9 100644 --- a/x-pack/solutions/search/plugins/search_query_rules/public/components/error_prompt/error_prompt.tsx +++ b/x-pack/solutions/search/plugins/search_query_rules/public/components/error_prompt/error_prompt.tsx @@ -5,10 +5,12 @@ * 2.0. */ -import React from 'react'; +import React, { useEffect } from 'react'; import { EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { useUsageTracker } from '../../hooks/use_usage_tracker'; +import { AnalyticsEvents } from '../../analytics/constants'; const ERROR_MESSAGES = { notFound: { @@ -19,6 +21,7 @@ const ERROR_MESSAGES = { defaultMessage="Requested resource was not found. Check if the URL is correct." /> ), + analyticsEvent: AnalyticsEvents.notFoundErrorPromptLoaded, }, generic: { title: , @@ -28,6 +31,7 @@ const ERROR_MESSAGES = { defaultMessage="An error occurred while fetching query rules. Check Kibana logs for more information." /> ), + analyticsEvent: AnalyticsEvents.genericErrorPromptLoaded, }, missingPermissions: { title: ( @@ -42,12 +46,17 @@ const ERROR_MESSAGES = { defaultMessage="You do not have the necessary permissions to manage query rules. Contact your system administrator." /> ), + analyticsEvent: AnalyticsEvents.missingPermissionsErrorPromptLoaded, }, }; export const ErrorPrompt: React.FC<{ errorType: 'missingPermissions' | 'generic' | 'notFound'; }> = ({ errorType }) => { + const useTracker = useUsageTracker(); + useEffect(() => { + useTracker?.load?.(ERROR_MESSAGES[errorType].analyticsEvent); + }, [errorType, useTracker]); return ( { + const usageTracker = useUsageTracker(); const { colorMode } = useEuiTheme(); - const { - data: queryRulesData, - isInitialLoading, - isError, - error, - refetch, - } = useFetchQueryRulesSets(); - useEffect(() => { - const interval = setInterval(() => { - refetch(); - }, 1000); - return () => clearInterval(interval); - }, [refetch]); + const { data: queryRulesData, isInitialLoading, isError, error } = useFetchQueryRulesSets(); const [isCreateModalVisible, setIsCreateModalVisible] = useState(false); + const backgroundProps = css({ backgroundImage: `url(${ colorMode === 'DARK' ? queryRulesBackgroundDark : queryRulesBackground @@ -61,6 +53,7 @@ export const QueryRulesOverview = () => { alignContent: 'center', backgroundPosition: 'center center', }); + return ( {!isInitialLoading && !isError && queryRulesData?._meta.totalItemCount !== 0 && ( @@ -95,6 +88,7 @@ export const QueryRulesOverview = () => { fill iconType="plusInCircle" onClick={() => { + usageTracker?.click(AnalyticsEvents.addRulesetClicked); setIsCreateModalVisible(true); }} > @@ -143,6 +137,7 @@ export const QueryRulesOverview = () => { { + usageTracker?.click(AnalyticsEvents.gettingStartedButtonClicked); setIsCreateModalVisible(true); }} /> diff --git a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_rules_sets/query_rules_sets.tsx b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_rules_sets/query_rules_sets.tsx index b0b17de0322a0..729a650ceb647 100644 --- a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_rules_sets/query_rules_sets.tsx +++ b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_rules_sets/query_rules_sets.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { QueryRulesListRulesetsQueryRulesetListItem } from '@elastic/elasticsearch/lib/api/types'; import { @@ -24,8 +24,11 @@ import { useQueryRulesSetsTableData } from '../../hooks/use_query_rules_sets_tab import { QueryRulesSetsSearch } from './query_rules_sets_search'; import { DeleteRulesetModal } from './delete_ruleset_modal'; import { UseRunQueryRuleset } from '../../hooks/use_run_query_ruleset'; +import { useUsageTracker } from '../../hooks/use_usage_tracker'; +import { AnalyticsEvents } from '../../analytics/constants'; export const QueryRulesSets = () => { + const useTracker = useUsageTracker(); const { services: { application, http }, } = useKibana(); @@ -43,6 +46,10 @@ export const QueryRulesSets = () => { pageSize ); + useEffect(() => { + useTracker?.load?.(AnalyticsEvents.rulesetListPageLoaded); + }, [useTracker]); + if (!queryRulesData) { return null; } @@ -57,6 +64,7 @@ export const QueryRulesSets = () => { { + useTracker?.click?.(AnalyticsEvents.editRulesetInlineNameClicked); application.navigateToUrl( http.basePath.prepend(`${PLUGIN_ROUTE_ROOT}/ruleset/${name}`) ); @@ -86,6 +94,9 @@ export const QueryRulesSets = () => { content={i18n.translate('xpack.queryRules.queryRulesSetTable.actions.run', { defaultMessage: 'Test in Console', })} + onClick={() => { + useTracker?.click?.(AnalyticsEvents.testRulesetInlineDropdownClicked); + }} /> ); }, @@ -102,10 +113,12 @@ export const QueryRulesSets = () => { icon: 'pencil', color: 'text', type: 'icon', - onClick: (ruleset: QueryRulesListRulesetsQueryRulesetListItem) => + onClick: (ruleset: QueryRulesListRulesetsQueryRulesetListItem) => { + useTracker?.click?.(AnalyticsEvents.editRulesetInlineDropdownClicked); application.navigateToUrl( http.basePath.prepend(`${PLUGIN_ROUTE_ROOT}/ruleset/${ruleset.ruleset_id}`) - ), + ); + }, }, { name: i18n.translate('xpack.queryRules.queryRulesSetTable.actions.delete', { @@ -121,6 +134,7 @@ export const QueryRulesSets = () => { type: 'icon', isPrimary: true, onClick: (ruleset: QueryRulesListRulesetsQueryRulesetListItem) => { + useTracker?.click?.(AnalyticsEvents.deleteRulesetInlineDropdownClicked); setRulesetToDelete(ruleset.ruleset_id); }, }, diff --git a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_rules_sets/query_rules_sets_search.tsx b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_rules_sets/query_rules_sets_search.tsx index 502f2c4c0869d..db8b06732478d 100644 --- a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_rules_sets/query_rules_sets_search.tsx +++ b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_rules_sets/query_rules_sets_search.tsx @@ -7,6 +7,8 @@ import { EuiFieldSearch } from '@elastic/eui'; import React, { useCallback } from 'react'; +import { useUsageTracker } from '../../hooks/use_usage_tracker'; +import { AnalyticsEvents } from '../../analytics/constants'; interface QueryRulesSetsSearchProps { searchKey: string; @@ -17,12 +19,15 @@ export const QueryRulesSetsSearch: React.FC = ({ searchKey, setSearchKey, }) => { + const useTracker = useUsageTracker(); const onSearch = useCallback( (newSearch: string) => { + useTracker?.load?.(AnalyticsEvents.rulesetSearched); + const trimSearch = newSearch.trim(); setSearchKey(trimSearch); }, - [setSearchKey] + [setSearchKey, useTracker] ); return ( diff --git a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_detail_panel.tsx b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_detail_panel.tsx index 198b57efbddd6..c4b54a47b9eeb 100644 --- a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_detail_panel.tsx +++ b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_detail_panel.tsx @@ -16,6 +16,8 @@ import { QueryRuleFlyout } from './query_rule_flyout/query_rule_flyout'; import { useGenerateRuleId } from '../../hooks/use_generate_rule_id'; import { SearchQueryRulesQueryRule } from '../../types'; import { RulesetDetailEmptyPrompt } from '../empty_prompt/ruleset_detail_empty_prompt'; +import { useUsageTracker } from '../../hooks/use_usage_tracker'; +import { AnalyticsEvents } from '../../analytics/constants'; interface QueryRuleDetailPanelProps { rules: SearchQueryRulesQueryRule[]; @@ -46,6 +48,8 @@ export const QueryRuleDetailPanel: React.FC = ({ const [ruleIdToEdit, setRuleIdToEdit] = React.useState(null); const [flyoutMode, setFlyoutMode] = React.useState<'create' | 'edit'>('edit'); + const useTracker = useUsageTracker(); + const { mutate: generateRuleId } = useGenerateRuleId(rulesetId); useEffect(() => { if (createMode && rules.length === 0) { @@ -94,6 +98,7 @@ export const QueryRuleDetailPanel: React.FC = ({ color="primary" data-test-subj="queryRulesetDetailAddRuleButton" onClick={() => { + useTracker?.click(AnalyticsEvents.addRuleClicked); generateRuleId(undefined, { onSuccess: (newRuleId) => { setFlyoutMode('create'); diff --git a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_draggable_list/query_rule_draggable_list.tsx b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_draggable_list/query_rule_draggable_list.tsx index 512b115efd23b..2a30df2881451 100644 --- a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_draggable_list/query_rule_draggable_list.tsx +++ b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_draggable_list/query_rule_draggable_list.tsx @@ -27,12 +27,14 @@ import { css } from '@emotion/react'; import { QueryRulesQueryRule } from '@elastic/elasticsearch/lib/api/types'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; +import { useUsageTracker } from '../../../hooks/use_usage_tracker'; import { SearchQueryRulesQueryRule } from '../../../../common/types'; import { DroppableContainer } from '../styles'; import { QueryRuleDraggableListHeader } from './query_rule_draggable_list_header'; import { QueryRuleDraggableListItemActionTypeBadge } from './query_rule_draggable_item_action_type_badge'; import { QueryRuleDraggableItemCriteriaDisplay } from './query_rule_draggable_item_criteria_display'; import { DeleteRulesetRuleModal } from './delete_ruleset_rule_modal'; +import { AnalyticsEvents } from '../../../analytics/constants'; export interface QueryRuleDraggableListItemProps { rules: SearchQueryRulesQueryRule[]; @@ -60,6 +62,7 @@ export const QueryRuleDraggableListItem: React.FC { const { euiTheme } = useEuiTheme(); + const useTracker = useUsageTracker(); const [isPopoverOpen, setIsPopoverOpen] = React.useState(false); const localTourTargetRef = useRef(null); const effectiveRef = tourInfo?.tourTargetRef || localTourTargetRef; @@ -174,6 +177,7 @@ export const QueryRuleDraggableListItem: React.FC { + useTracker?.click(AnalyticsEvents.editRuleClicked); onEditRuleFlyoutOpen(queryRule.rule_id); closePopover(); }} @@ -204,6 +208,7 @@ export const QueryRuleDraggableListItem: React.FC { + useTracker?.click(AnalyticsEvents.deleteRuleClicked); setRuleToDelete(queryRule.rule_id); closePopover(); }} @@ -263,11 +268,13 @@ export const QueryRuleDraggableList: React.FC = ({ tourInfo, }) => { const { euiTheme } = useEuiTheme(); + const useTracker = useUsageTracker(); return ( { if (source && destination) { + useTracker?.click(AnalyticsEvents.rulesReordered); const items = euiDragDropReorder(rules, source.index, destination.index); onReorder(items); } diff --git a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_flyout/use_query_rule_flyout_state.ts b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_flyout/use_query_rule_flyout_state.ts index 13ddffe994dfd..cd231b04c8259 100644 --- a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_flyout/use_query_rule_flyout_state.ts +++ b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_rule_flyout/use_query_rule_flyout_state.ts @@ -10,9 +10,11 @@ import { useEffect, useState } from 'react'; import { useFieldArray, useFormContext, useWatch } from 'react-hook-form'; import { OnDragEndResponder } from '@hello-pangea/dnd'; import { euiDragDropReorder } from '@elastic/eui'; +import { AnalyticsEvents } from '../../../analytics/constants'; import { QueryRuleEditorForm, SearchQueryRulesQueryRule } from '../../../../common/types'; import { useFetchIndexNames } from '../../../hooks/use_fetch_index_names'; import { isCriteriaAlways } from '../../../utils/query_rules_utils'; +import { useUsageTracker } from '../../../hooks/use_usage_tracker'; export const createEmptyRuleset = ( rulesetId: QueryRulesQueryRuleset['ruleset_id'] @@ -39,6 +41,7 @@ export const useQueryRuleFlyoutState = ({ setIsFormDirty, onSave, }: UseQueryRuleFlyoutStateProps) => { + const usageTracker = useUsageTracker(); const { control, getValues, reset, setValue, formState, trigger } = useFormContext(); const { @@ -242,6 +245,7 @@ export const useQueryRuleFlyoutState = ({ const shouldShowCriteriaCallout = criteriaCalloutActive && !isAlways; const dragEndHandle: OnDragEndResponder = ({ source, destination }) => { + usageTracker?.click(AnalyticsEvents.ruleFlyoutDocumentsReordered); if (source && destination && (ruleFromRuleset || createMode)) { if (isDocRule) { const newActions = euiDragDropReorder(actionFields, source.index, destination.index); diff --git a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_ruleset_detail.tsx b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_ruleset_detail.tsx index f4656cd7b6735..cb5346b13007f 100644 --- a/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_ruleset_detail.tsx +++ b/x-pack/solutions/search/plugins/search_query_rules/public/components/query_ruleset_detail/query_ruleset_detail.tsx @@ -40,6 +40,8 @@ import { DeleteRulesetModal } from '../query_rules_sets/delete_ruleset_modal'; import { QueryRuleDetailPanel } from './query_rule_detail_panel'; import { useQueryRulesetDetailState } from './use_query_ruleset_detail_state'; import { useFetchQueryRulesetExist } from '../../hooks/use_fetch_ruleset_exists'; +import { AnalyticsEvents } from '../../analytics/constants'; +import { useUsageTracker } from '../../hooks/use_usage_tracker'; export interface QueryRulesetDetailProps { createMode?: boolean; @@ -55,6 +57,7 @@ export const QueryRulesetDetail: React.FC = ({ createMo }>(); const { data: rulesetExists, isLoading: isFailsafeLoading } = useFetchQueryRulesetExist(rulesetId); + const useTracker = useUsageTracker(); useEffect(() => { // This is a failsafe in case user navigates to an existing ruleset via URL directly @@ -63,6 +66,10 @@ export const QueryRulesetDetail: React.FC = ({ createMo } }, [createMode, rulesetExists, application, http.basePath, rulesetId]); + useEffect(() => { + useTracker?.load?.(AnalyticsEvents.rulesetDetailPageLoaded); + }, [useTracker]); + const blockRender = (createMode && rulesetExists) || isFailsafeLoading; const { mutate: createRuleset } = usePutRuleset(() => { @@ -186,6 +193,9 @@ export const QueryRulesetDetail: React.FC = ({ createMo const handleSave = () => { setIsFormDirty(false); + useTracker?.click( + createMode ? AnalyticsEvents.rulesetCreateClicked : AnalyticsEvents.rulesetUpdateClicked + ); createRuleset({ rulesetId, forceWrite: true, @@ -232,8 +242,10 @@ export const QueryRulesetDetail: React.FC = ({ createMo ), color: 'primary', 'aria-current': false, - onClick: () => - application.navigateToUrl(http.basePath.prepend(`${PLUGIN_ROUTE_ROOT}`)), + onClick: () => { + useTracker?.click(AnalyticsEvents.backToRulesetListClicked); + application.navigateToUrl(http.basePath.prepend(`${PLUGIN_ROUTE_ROOT}`)); + }, }, ]} restrictWidth @@ -331,7 +343,10 @@ export const QueryRulesetDetail: React.FC = ({ createMo content={i18n.translate('xpack.queryRules.queryRulesetDetail.testButton', { defaultMessage: 'Test in Console', })} - onClick={finishTour} + onClick={() => { + useTracker?.click(AnalyticsEvents.testInConsoleClicked); + finishTour(); + }} /> diff --git a/x-pack/solutions/search/plugins/search_query_rules/public/hooks/use_usage_tracker.ts b/x-pack/solutions/search/plugins/search_query_rules/public/hooks/use_usage_tracker.ts new file mode 100644 index 0000000000000..e2154a5ba511c --- /dev/null +++ b/x-pack/solutions/search/plugins/search_query_rules/public/hooks/use_usage_tracker.ts @@ -0,0 +1,40 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useMemo } from 'react'; +import { METRIC_TYPE } from '@kbn/analytics'; +import { useKibana } from './use_kibana'; + +const APP_TRACKER_NAME = 'search_query_rules'; + +export const useUsageTracker = () => { + const { + services: { usageCollection }, + } = useKibana(); + + return useMemo(() => { + if (usageCollection) { + return { + click: usageCollection.reportUiCounter.bind( + usageCollection, + APP_TRACKER_NAME, + METRIC_TYPE.CLICK + ), + count: usageCollection.reportUiCounter.bind( + usageCollection, + APP_TRACKER_NAME, + METRIC_TYPE.COUNT + ), + load: usageCollection.reportUiCounter.bind( + usageCollection, + APP_TRACKER_NAME, + METRIC_TYPE.LOADED + ), + }; + } + }, [usageCollection]); +}; diff --git a/x-pack/solutions/search/plugins/search_query_rules/public/types.ts b/x-pack/solutions/search/plugins/search_query_rules/public/types.ts index 059bc65b164d2..0376f756bc472 100644 --- a/x-pack/solutions/search/plugins/search_query_rules/public/types.ts +++ b/x-pack/solutions/search/plugins/search_query_rules/public/types.ts @@ -9,6 +9,7 @@ import { SearchNavigationPluginStart } from '@kbn/search-navigation/public'; import { AppMountParameters, CoreStart } from '@kbn/core/public'; import type { ConsolePluginStart } from '@kbn/console-plugin/public'; import type { SharePluginStart } from '@kbn/share-plugin/public'; +import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; export * from '../common/types'; export interface AppPluginStartDependencies { @@ -16,6 +17,7 @@ export interface AppPluginStartDependencies { console?: ConsolePluginStart; share?: SharePluginStart; searchNavigation?: SearchNavigationPluginStart; + usageCollection?: UsageCollectionStart; } export type AppServicesContext = CoreStart & AppPluginStartDependencies; diff --git a/x-pack/solutions/search/plugins/search_query_rules/tsconfig.json b/x-pack/solutions/search/plugins/search_query_rules/tsconfig.json index f88604a80ec6b..78bfded065b66 100644 --- a/x-pack/solutions/search/plugins/search_query_rules/tsconfig.json +++ b/x-pack/solutions/search/plugins/search_query_rules/tsconfig.json @@ -30,6 +30,8 @@ "@kbn/search-index-documents", "@kbn/unsaved-changes-prompt", "@kbn/deeplinks-analytics", + "@kbn/analytics", + "@kbn/usage-collection-plugin", ], "exclude": [ "target/**/*",