diff --git a/.eslintrc.js b/.eslintrc.js index c604844089ef4..9fc9aac9cb42c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -974,6 +974,12 @@ module.exports = { '@kbn/telemetry/event_generating_elements_should_be_instrumented': 'error', }, }, + { + files: ['x-pack/plugins/search*/**/*.tsx', 'x-pack/packages/search/**/*.tsx'], + rules: { + '@kbn/telemetry/event_generating_elements_should_be_instrumented': 'warn', + }, + }, { files: [ 'x-pack/plugins/observability_solution/**/!(*.stories.tsx|*.test.tsx|*.storybook_decorator.tsx|*.mock.tsx)', diff --git a/packages/kbn-search-api-keys-components/src/components/api_key_form.tsx b/packages/kbn-search-api-keys-components/src/components/api_key_form.tsx index ccd169c413bb1..02e5a46b640ac 100644 --- a/packages/kbn-search-api-keys-components/src/components/api_key_form.tsx +++ b/packages/kbn-search-api-keys-components/src/components/api_key_form.tsx @@ -43,6 +43,7 @@ export const ApiKeyForm: React.FC = ({ hasTitle = true }) => { value={displayedApiKey} copyValue={apiKey} dataTestSubj="apiKeyFormAPIKey" + copyValueDataTestSubj="APIKeyButtonCopy" actions={[ void; } export const TryInConsoleButton = ({ request, @@ -38,6 +40,8 @@ export const TryInConsoleButton = ({ content = RUN_IN_CONSOLE, showIcon = true, type = 'emptyButton', + telemetryId, + onClick: onClickProp, }: TryInConsoleButtonProps) => { const url = sharePlugin?.url; const canShowDevtools = !!application?.capabilities?.dev_tools?.show; @@ -65,6 +69,7 @@ export const TryInConsoleButton = ({ } else { window.open(consolePreviewLink, '_blank', 'noreferrer'); } + onClickProp?.(); }; const getAriaLabel = () => { @@ -84,6 +89,7 @@ export const TryInConsoleButton = ({ const commonProps = { 'data-test-subj': type === 'link' ? 'tryInConsoleLink' : 'tryInConsoleButton', 'aria-label': getAriaLabel(), + 'data-telemetry-id': telemetryId, onClick, }; const iconType = showIcon ? 'play' : undefined; diff --git a/x-pack/packages/search/shared_ui/src/form_info_field/form_info_field.tsx b/x-pack/packages/search/shared_ui/src/form_info_field/form_info_field.tsx index 89e14e72454c6..c99daba9f4537 100644 --- a/x-pack/packages/search/shared_ui/src/form_info_field/form_info_field.tsx +++ b/x-pack/packages/search/shared_ui/src/form_info_field/form_info_field.tsx @@ -23,6 +23,7 @@ interface FormInfoFieldProps { value: string; copyValue?: string; dataTestSubj?: string; + copyValueDataTestSubj?: string; } export const FormInfoField: React.FC = ({ @@ -31,6 +32,7 @@ export const FormInfoField: React.FC = ({ value, copyValue, dataTestSubj, + copyValueDataTestSubj, }) => { const { euiTheme } = useEuiTheme(); @@ -71,6 +73,7 @@ export const FormInfoField: React.FC = ({ { value={elasticsearchUrl} copyValue={elasticsearchUrl} dataTestSubj="connectionDetailsEndpoint" + copyValueDataTestSubj="connectionDetailsEndpointCopy" /> ); }; diff --git a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx index b2e1ab9f2c992..8cc673d073101 100644 --- a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx +++ b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx @@ -34,6 +34,8 @@ import { SearchIndexDetailsMappings } from './details_page_mappings'; import { SearchIndexDetailsSettings } from './details_page_settings'; import { SearchIndexDetailsPageMenuItemPopover } from './details_page_menu_item'; import { useIndexDocumentSearch } from '../../hooks/api/use_document_search'; +import { useUsageTracker } from '../../contexts/usage_tracker_context'; +import { AnalyticsEvents } from '../../analytics/constants'; export const SearchIndexDetailsPage = () => { const indexName = decodeURIComponent(useParams<{ indexName: string }>().indexName); @@ -69,6 +71,7 @@ export const SearchIndexDetailsPage = () => { setDocumentsLoading(isInitialLoading); setDocumentsExists(!(!isInitialLoading && indexDocuments?.results?.data.length === 0)); }, [indexDocuments, isInitialLoading, setDocumentsExists, setDocumentsLoading]); + const usageTracker = useUsageTracker(); const detailsPageTabs: EuiTabbedContentTab[] = useMemo(() => { return [ @@ -114,9 +117,19 @@ export const SearchIndexDetailsPage = () => { const handleTabClick = useCallback( (tab: EuiTabbedContentTab) => { history.push(`index_details/${indexName}/${tab.id}`); + + const tabEvent = { + [SearchIndexDetailsTabs.DATA]: AnalyticsEvents.indexDetailsNavDataTab, + [SearchIndexDetailsTabs.MAPPINGS]: AnalyticsEvents.indexDetailsNavMappingsTab, + [SearchIndexDetailsTabs.SETTINGS]: AnalyticsEvents.indexDetailsNavSettingsTab, + }[tab.id]; + + if (tabEvent) { + usageTracker.click(tabEvent); + } }, - [history, indexName] + [history, indexName, usageTracker] ); const embeddableConsole = useMemo( () => (consolePlugin?.EmbeddableConsole ? : null), diff --git a/x-pack/plugins/search_indices/public/components/start/create_index.tsx b/x-pack/plugins/search_indices/public/components/start/create_index.tsx index f1392b3d33813..788bd1e36f2ee 100644 --- a/x-pack/plugins/search_indices/public/components/start/create_index.tsx +++ b/x-pack/plugins/search_indices/public/components/start/create_index.tsx @@ -63,9 +63,14 @@ export const CreateIndexForm = ({ return; } usageTracker.click(AnalyticsEvents.startCreateIndexClick); + + if (formState.defaultIndexName !== formState.indexName) { + usageTracker.click(AnalyticsEvents.startCreateIndexPageModifyIndexName); + } + createIndex({ indexName: formState.indexName }); }, - [usageTracker, createIndex, formState.indexName] + [usageTracker, createIndex, formState.indexName, formState.defaultIndexName] ); const onIndexNameChange = (e: React.ChangeEvent) => { const newIndexName = e.target.value; diff --git a/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx b/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx index 0c18610f44d9e..ed473b1a63012 100644 --- a/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx +++ b/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx @@ -86,6 +86,13 @@ export const CreateIndexCodeView = ({ application={application} sharePlugin={share} consolePlugin={consolePlugin} + telemetryId={`${selectedLanguage}_create_index`} + onClick={() => { + usageTracker.click([ + AnalyticsEvents.startCreateIndexRunInConsole, + `${AnalyticsEvents.startCreateIndexRunInConsole}_${selectedLanguage}`, + ]); + }} /> )} diff --git a/x-pack/plugins/search_indices/public/components/start/elasticsearch_start.tsx b/x-pack/plugins/search_indices/public/components/start/elasticsearch_start.tsx index 8bc8d5fcd7ea2..42b021043cb34 100644 --- a/x-pack/plugins/search_indices/public/components/start/elasticsearch_start.tsx +++ b/x-pack/plugins/search_indices/public/components/start/elasticsearch_start.tsx @@ -35,8 +35,10 @@ import { CreateIndexFormState } from './types'; import { useKibana } from '../../hooks/use_kibana'; function initCreateIndexState(): CreateIndexFormState { + const defaultIndexName = generateRandomIndexName(); return { - indexName: generateRandomIndexName(), + indexName: defaultIndexName, + defaultIndexName, codingLanguage: getDefaultCodingLanguage(), }; } diff --git a/x-pack/plugins/search_indices/public/components/start/hooks/use_indices_redirect.tsx b/x-pack/plugins/search_indices/public/components/start/hooks/use_indices_redirect.tsx index 86fdf75a1d080..899d44da2afa8 100644 --- a/x-pack/plugins/search_indices/public/components/start/hooks/use_indices_redirect.tsx +++ b/x-pack/plugins/search_indices/public/components/start/hooks/use_indices_redirect.tsx @@ -12,11 +12,14 @@ import type { IndicesStatusResponse } from '../../../../common'; import { useKibana } from '../../../hooks/use_kibana'; import { navigateToIndexDetails } from './utils'; +import { useUsageTracker } from '../../../contexts/usage_tracker_context'; +import { AnalyticsEvents } from '../../../analytics/constants'; export const useIndicesRedirect = (indicesStatus?: IndicesStatusResponse) => { const { application, http } = useKibana().services; const [lastStatus, setLastStatus] = useState(() => undefined); const [hasDoneRedirect, setHasDoneRedirect] = useState(() => false); + const usageTracker = useUsageTracker(); return useEffect(() => { if (hasDoneRedirect) { return; @@ -36,9 +39,18 @@ export const useIndicesRedirect = (indicesStatus?: IndicesStatusResponse) => { if (indicesStatus.indexNames.length === 1) { navigateToIndexDetails(application, http, indicesStatus.indexNames[0]); setHasDoneRedirect(true); + usageTracker.click(AnalyticsEvents.startCreateIndexCreatedRedirect); return; } application.navigateToApp('management', { deepLinkId: 'index_management' }); setHasDoneRedirect(true); - }, [application, http, indicesStatus, lastStatus, hasDoneRedirect]); + }, [ + application, + http, + indicesStatus, + lastStatus, + setHasDoneRedirect, + usageTracker, + hasDoneRedirect, + ]); }; diff --git a/x-pack/plugins/search_indices/public/components/start/types.ts b/x-pack/plugins/search_indices/public/components/start/types.ts index c0dbbeca88883..4c0235ec515f1 100644 --- a/x-pack/plugins/search_indices/public/components/start/types.ts +++ b/x-pack/plugins/search_indices/public/components/start/types.ts @@ -9,5 +9,6 @@ import type { AvailableLanguages } from '../../code_examples'; export interface CreateIndexFormState { indexName: string; + defaultIndexName: string; codingLanguage: AvailableLanguages; }