mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Search][Homepage] Add Telemetry support (#188364)
## Summary Adds support for telemetry tracking to Search Homepage for both ES3 & Stack. Additionally fixed a small markup bug with the page header.
This commit is contained in:
parent
5756b299a3
commit
ef2d7b29ba
11 changed files with 141 additions and 33 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
@ -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 (
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* 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 {
|
||||
|
@ -12,8 +12,15 @@ import {
|
|||
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 (
|
||||
<>
|
||||
|
@ -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"
|
||||
>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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';
|
|
@ -23,6 +23,7 @@ import {
|
|||
SearchHomepagePluginStart,
|
||||
SearchHomepageAppPluginStartDependencies,
|
||||
SearchHomepageAppInfo,
|
||||
SearchHomepageServicesContext,
|
||||
} from './types';
|
||||
|
||||
const appInfo: SearchHomepageAppInfo = {
|
||||
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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';
|
||||
|
@ -59,16 +58,17 @@ export interface SearchHomepagePluginStart {
|
|||
}
|
||||
|
||||
export interface SearchHomepageAppPluginStartDependencies {
|
||||
history: AppMountParameters['history'];
|
||||
usageCollection?: UsageCollectionStart;
|
||||
share: SharePluginStart;
|
||||
console?: ConsolePluginStart;
|
||||
share: SharePluginStart;
|
||||
usageCollection?: UsageCollectionStart;
|
||||
}
|
||||
|
||||
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
x-pack/plugins/search_homepage/public/usage_tracker.ts
Normal file
42
x-pack/plugins/search_homepage/public/usage_tracker.ts
Normal file
|
@ -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[]) => {},
|
||||
};
|
||||
}
|
|
@ -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/**/*",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue