Skip to content

Commit

Permalink
[Search][Homepage] Add Telemetry support (#188364)
Browse files Browse the repository at this point in the history
## Summary

Adds support for telemetry tracking to Search Homepage for both ES3 &
Stack.

Additionally fixed a small markup bug with the page header.
  • Loading branch information
TattdCodeMonkey authored Jul 16, 2024
1 parent 5756b29 commit ef2d7b2
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 33 deletions.
17 changes: 10 additions & 7 deletions x-pack/plugins/search_homepage/public/application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,25 @@ import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { I18nProvider } from '@kbn/i18n-react';
import { Router } from '@kbn/shared-ux-router';
import { SearchHomepageAppPluginStartDependencies } from './types';
import { SearchHomepageServicesContext } from './types';
import { HomepageRouter } from './router';
import { UsageTrackerContextProvider } from './contexts/usage_tracker_context';

export const renderApp = async (
core: CoreStart,
services: SearchHomepageAppPluginStartDependencies,
services: SearchHomepageServicesContext,
element: HTMLElement
) => {
ReactDOM.render(
<KibanaRenderContextProvider {...core}>
<KibanaContextProvider services={{ ...core, ...services }}>
<I18nProvider>
<Router history={services.history}>
<HomepageRouter />
</Router>
</I18nProvider>
<UsageTrackerContextProvider usageCollection={services.usageCollection}>
<I18nProvider>
<Router history={services.history}>
<HomepageRouter />
</Router>
</I18nProvider>
</UsageTrackerContextProvider>
</KibanaContextProvider>
</KibanaRenderContextProvider>,
element
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import type { ConsolePluginStart } from '@kbn/console-plugin/public';

import { useKibana } from '../hooks/use_kibana';
import { useUsageTracker } from '../hooks/use_usage_tracker';

const canOpenConsole = (plugin?: ConsolePluginStart): boolean => {
if (!plugin) return false;
Expand All @@ -21,11 +22,13 @@ export const ConsoleLinkButton = () => {
const {
services: { console: consolePlugin },
} = useKibana();
const usageTracker = useUsageTracker();
const openConsole = useCallback(() => {
usageTracker.click('get_started_in_console');
if (!canOpenConsole(consolePlugin)) return;

consolePlugin!.openEmbeddedConsole!();
}, [consolePlugin]);
}, [consolePlugin, usageTracker]);
if (consolePlugin === undefined || consolePlugin.openEmbeddedConsole === undefined) return null;

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import React, { useState, useCallback } from 'react';
import { EuiButtonEmpty, EuiFlexGroup, EuiFlyout, EuiHeaderLinks } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import {
KibanaWiredConnectionDetailsProvider,
ConnectionDetailsFlyoutContent,
} from '@kbn/cloud/connection_details';

import { useUsageTracker } from '../hooks/use_usage_tracker';

export const EndpointsHeaderAction = () => {
const [open, setOpen] = React.useState(false);
const usageTracker = useUsageTracker();
const [open, setOpen] = useState<boolean>(false);
const onClickEndpointsButton = useCallback(() => {
usageTracker.click('endpoints_and_api_keys');
setOpen(true);
}, [usageTracker]);

return (
<>
Expand All @@ -22,7 +29,7 @@ export const EndpointsHeaderAction = () => {
<EuiButtonEmpty
iconType="endpoint"
size="s"
onClick={() => setOpen(true)}
onClick={onClickEndpointsButton}
data-test-subj="searchHomepageEndpointsHeaderActionEndpointsApiKeysButton"
data-telemetry-id="searchHomepageEndpointsHeaderActionEndpointsApiKeysButton"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,8 @@ export interface SearchHomepageHeaderProps {
export const SearchHomepageHeader = ({ showEndpointsAPIKeys }: SearchHomepageHeaderProps) => (
<EuiPageTemplate.Header
pageTitle={
<EuiTitle data-test-subj="search-homepage-header-title">
<h2>
<FormattedMessage
id="xpack.searchHomepage.pageTitle"
defaultMessage="Welcome to Search"
/>
</h2>
<EuiTitle data-test-subj="search-homepage-header-title" size="l">
<FormattedMessage id="xpack.searchHomepage.pageTitle" defaultMessage="Welcome to Search" />
</EuiTitle>
}
data-test-subj="search-homepage-header"
Expand Down
10 changes: 8 additions & 2 deletions x-pack/plugins/search_homepage/public/components/stack_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@
*/

import React from 'react';

import { UsageTrackerContextProvider } from '../contexts/usage_tracker_context';
import { useKibana } from '../hooks/use_kibana';
import { SearchHomepageBody } from './search_homepage_body';
import { SearchHomepageHeader } from './search_homepage_header';

export const App: React.FC = () => {
const {
services: { usageCollection },
} = useKibana();
return (
<>
<UsageTrackerContextProvider usageCollection={usageCollection}>
<SearchHomepageHeader showEndpointsAPIKeys={false} />
<SearchHomepageBody />
</>
</UsageTrackerContextProvider>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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 React, { createContext, useContext, useMemo } from 'react';
import type {
UsageCollectionSetup,
UsageCollectionStart,
} from '@kbn/usage-collection-plugin/public';

import { createUsageTracker, createEmptyUsageTracker } from '../usage_tracker';
import { AppUsageTracker } from '../types';

const UsageTrackerContext = createContext<AppUsageTracker>(createEmptyUsageTracker());

export interface UsageTrackerContextProviderProps {
children: React.ReactNode | React.ReactNode[];
usageCollection?: UsageCollectionSetup | UsageCollectionStart;
}
export function UsageTrackerContextProvider({
children,
usageCollection,
}: UsageTrackerContextProviderProps) {
const usageTracker = useMemo(() => {
const homePageUsageTracker = createUsageTracker(usageCollection);
homePageUsageTracker.load('opened_app');
return homePageUsageTracker;
}, [usageCollection]);
return (
<UsageTrackerContext.Provider value={usageTracker}>{children}</UsageTrackerContext.Provider>
);
}

export const useUsageTracker = () => {
const ctx = useContext(UsageTrackerContext);
if (!ctx) {
throw new Error('UsageTrackerContext should be used inside of the UsageTrackerContextProvider');
}
return ctx;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* 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 { useUsageTracker } from '../contexts/usage_tracker_context';
3 changes: 2 additions & 1 deletion x-pack/plugins/search_homepage/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
SearchHomepagePluginStart,
SearchHomepageAppPluginStartDependencies,
SearchHomepageAppInfo,
SearchHomepageServicesContext,
} from './types';

const appInfo: SearchHomepageAppInfo = {
Expand Down Expand Up @@ -56,7 +57,7 @@ export class SearchHomepagePlugin
async mount({ element, history }: AppMountParameters) {
const { renderApp } = await import('./application');
const [coreStart, depsStart] = await core.getStartServices();
const startDeps: SearchHomepageAppPluginStartDependencies = {
const startDeps: SearchHomepageServicesContext = {
...depsStart,
history,
};
Expand Down
22 changes: 11 additions & 11 deletions x-pack/plugins/search_homepage/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
*/

import type { ComponentProps, FC } from 'react';
import type { CloudSetup } from '@kbn/cloud-plugin/public';
import type { ConsolePluginStart } from '@kbn/console-plugin/public';
import type { AppMountParameters, HttpStart } from '@kbn/core/public';
import type { AppMountParameters } from '@kbn/core/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public';
import type { App } from './components/stack_app';
Expand Down Expand Up @@ -59,16 +58,17 @@ export interface SearchHomepagePluginStart {
}

export interface SearchHomepageAppPluginStartDependencies {
history: AppMountParameters['history'];
usageCollection?: UsageCollectionStart;
share: SharePluginStart;
console?: ConsolePluginStart;
}

export interface SearchHomepageServicesContext {
http: HttpStart;
share: SharePluginStart;
cloud?: CloudSetup;
usageCollection?: UsageCollectionStart;
console?: ConsolePluginStart;
}

export interface SearchHomepageServicesContext extends SearchHomepageAppPluginStartDependencies {
history: AppMountParameters['history'];
}

export interface AppUsageTracker {
click: (eventName: string | string[]) => void;
count: (eventName: string | string[]) => void;
load: (eventName: string | string[]) => void;
}
42 changes: 42 additions & 0 deletions x-pack/plugins/search_homepage/public/usage_tracker.ts
Original file line number Diff line number Diff line change
@@ -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.
*/

import { METRIC_TYPE, UiCounterMetricType } from '@kbn/analytics';
import type {
UsageCollectionSetup,
UsageCollectionStart,
} from '@kbn/usage-collection-plugin/public';
import { AppUsageTracker } from './types';

const APP_TRACKER_NAME = 'searchHomepage';

export function createUsageTracker(
usageCollection?: UsageCollectionSetup | UsageCollectionStart
): AppUsageTracker {
const track = (type: UiCounterMetricType, name: string | string[]) =>
usageCollection?.reportUiCounter(APP_TRACKER_NAME, type, name);

return {
click: (eventName: string | string[]) => {
track(METRIC_TYPE.CLICK, eventName);
},
count: (eventName: string | string[]) => {
track(METRIC_TYPE.COUNT, eventName);
},
load: (eventName: string | string[]) => {
track(METRIC_TYPE.LOADED, eventName);
},
};
}

export function createEmptyUsageTracker(): AppUsageTracker {
return {
click: (_eventName: string | string[]) => {},
count: (_eventName: string | string[]) => {},
load: (_eventName: string | string[]) => {},
};
}
2 changes: 1 addition & 1 deletion x-pack/plugins/search_homepage/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
"@kbn/shared-ux-page-kibana-template",
"@kbn/shared-ux-utility",
"@kbn/i18n",
"@kbn/cloud-plugin",
"@kbn/console-plugin",
"@kbn/share-plugin",
"@kbn/usage-collection-plugin",
"@kbn/config-schema",
"@kbn/cloud",
"@kbn/analytics",
],
"exclude": [
"target/**/*",
Expand Down

0 comments on commit ef2d7b2

Please sign in to comment.