mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[8.16] [SecuritySolution][Onboarding] Send Telemetry when integration tabs or cards clicked (#196291) (#197296)
# Backport This will backport the following commits from `main` to `8.16`: - [[SecuritySolution][Onboarding] Send Telemetry when integration tabs or cards clicked (#196291)](https://github.com/elastic/kibana/pull/196291) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Angela Chuang","email":"6295984+angorayc@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-10-22T15:52:43Z","message":"[SecuritySolution][Onboarding] Send Telemetry when integration tabs or cards clicked (#196291)\n\n## Summary\r\nhttps://github.com/elastic/kibana/issues/196145\r\n\r\nTo verify:\r\n\r\n1. Add these lines to `kibana.dev.yml`\r\n```\r\nlogging.browser.root.level: debug\r\ntelemetry.optIn: true\r\n```\r\n2. In the onboarding hub, expand the integration card.\r\nIt should log `onboarding_tab_${tabId}` on tabs clicked.\r\n\r\n\r\n\r\n\r\nhttps://github.com/user-attachments/assets/bd30c9ed-7c99-4ca0-93e7-6d9bf0146e62\r\n\r\n\r\nIt should log `onboarding_card_${integrationId}` on integration cards\r\nclicked.\r\n\r\n\r\nhttps://github.com/user-attachments/assets/58750d88-7bbf-4b27-8e54-587f3f6f32c2\r\n\r\n\r\n3. Manage integrations callout link clicked::\r\n`onboarding_manage_integrations`;\r\n4. Endpoint callout link clicked: `onboarding_endpoint_learn_more`;\r\n5. Agentless callout link clicked: `onboarding_agentless_learn_more`;\r\n6. Agent still required callout link clicked:\r\n`onboarding_agent_required`;\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"2b270897a3f22ed5ca04ef173895cfa8660f9ea2","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["backport","release_note:skip","v9.0.0","v6.8.16","Team:Threat Hunting:Explore","ci:cloud-deploy"],"title":"[SecuritySolution][Onboarding] Send Telemetry when integration tabs or cards clicked","number":196291,"url":"https://github.com/elastic/kibana/pull/196291","mergeCommit":{"message":"[SecuritySolution][Onboarding] Send Telemetry when integration tabs or cards clicked (#196291)\n\n## Summary\r\nhttps://github.com/elastic/kibana/issues/196145\r\n\r\nTo verify:\r\n\r\n1. Add these lines to `kibana.dev.yml`\r\n```\r\nlogging.browser.root.level: debug\r\ntelemetry.optIn: true\r\n```\r\n2. In the onboarding hub, expand the integration card.\r\nIt should log `onboarding_tab_${tabId}` on tabs clicked.\r\n\r\n\r\n\r\n\r\nhttps://github.com/user-attachments/assets/bd30c9ed-7c99-4ca0-93e7-6d9bf0146e62\r\n\r\n\r\nIt should log `onboarding_card_${integrationId}` on integration cards\r\nclicked.\r\n\r\n\r\nhttps://github.com/user-attachments/assets/58750d88-7bbf-4b27-8e54-587f3f6f32c2\r\n\r\n\r\n3. Manage integrations callout link clicked::\r\n`onboarding_manage_integrations`;\r\n4. Endpoint callout link clicked: `onboarding_endpoint_learn_more`;\r\n5. Agentless callout link clicked: `onboarding_agentless_learn_more`;\r\n6. Agent still required callout link clicked:\r\n`onboarding_agent_required`;\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"2b270897a3f22ed5ca04ef173895cfa8660f9ea2"}},"sourceBranch":"main","suggestedTargetBranches":["6.8"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/196291","number":196291,"mergeCommit":{"message":"[SecuritySolution][Onboarding] Send Telemetry when integration tabs or cards clicked (#196291)\n\n## Summary\r\nhttps://github.com/elastic/kibana/issues/196145\r\n\r\nTo verify:\r\n\r\n1. Add these lines to `kibana.dev.yml`\r\n```\r\nlogging.browser.root.level: debug\r\ntelemetry.optIn: true\r\n```\r\n2. In the onboarding hub, expand the integration card.\r\nIt should log `onboarding_tab_${tabId}` on tabs clicked.\r\n\r\n\r\n\r\n\r\nhttps://github.com/user-attachments/assets/bd30c9ed-7c99-4ca0-93e7-6d9bf0146e62\r\n\r\n\r\nIt should log `onboarding_card_${integrationId}` on integration cards\r\nclicked.\r\n\r\n\r\nhttps://github.com/user-attachments/assets/58750d88-7bbf-4b27-8e54-587f3f6f32c2\r\n\r\n\r\n3. Manage integrations callout link clicked::\r\n`onboarding_manage_integrations`;\r\n4. Endpoint callout link clicked: `onboarding_endpoint_learn_more`;\r\n5. Agentless callout link clicked: `onboarding_agentless_learn_more`;\r\n6. Agent still required callout link clicked:\r\n`onboarding_agent_required`;\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"2b270897a3f22ed5ca04ef173895cfa8660f9ea2"}},{"branch":"6.8","label":"v6.8.16","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Angela Chuang <6295984+angorayc@users.noreply.github.com>
This commit is contained in:
parent
f9dee7cb67
commit
2f89ad1d9d
15 changed files with 185 additions and 12 deletions
|
@ -35,6 +35,8 @@ export enum TELEMETRY_EVENT {
|
|||
DASHBOARD = 'navigate_to_dashboard',
|
||||
CREATE_DASHBOARD = 'create_dashboard',
|
||||
|
||||
ONBOARDING = 'onboarding',
|
||||
|
||||
// value list
|
||||
OPEN_VALUE_LIST_MODAL = 'open_value_list_modal',
|
||||
CREATE_VALUE_LIST_ITEM = 'create_value_list_item',
|
||||
|
|
|
@ -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 const trackOnboardingLinkClick = jest.fn();
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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, TELEMETRY_EVENT, track } from '../../../common/lib/telemetry';
|
||||
|
||||
export const trackOnboardingLinkClick = (linkId: string) => {
|
||||
track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.ONBOARDING}_${linkId}`);
|
||||
};
|
|
@ -14,8 +14,10 @@ import React from 'react';
|
|||
import { render } from '@testing-library/react';
|
||||
import { AgentRequiredCallout } from './agent_required_callout';
|
||||
import { TestProviders } from '../../../../../../common/mock/test_providers';
|
||||
import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry';
|
||||
|
||||
jest.mock('../../../../../../common/lib/kibana');
|
||||
jest.mock('../../../../../common/lib/telemetry');
|
||||
|
||||
describe('AgentRequiredCallout', () => {
|
||||
beforeEach(() => {
|
||||
|
@ -30,4 +32,12 @@ describe('AgentRequiredCallout', () => {
|
|||
).toBeInTheDocument();
|
||||
expect(getByTestId('agentLink')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should track the agent link click', () => {
|
||||
const { getByTestId } = render(<AgentRequiredCallout />, { wrapper: TestProviders });
|
||||
|
||||
getByTestId('agentLink').click();
|
||||
|
||||
expect(trackOnboardingLinkClick).toHaveBeenCalledWith('agent_required');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -11,16 +11,22 @@ import { EuiIcon } from '@elastic/eui';
|
|||
import { LinkAnchor } from '../../../../../../common/components/links';
|
||||
import { CardCallOut } from '../../common/card_callout';
|
||||
import { useNavigation } from '../../../../../../common/lib/kibana';
|
||||
import { FLEET_APP_ID, ADD_AGENT_PATH } from '../constants';
|
||||
import { FLEET_APP_ID, ADD_AGENT_PATH, TELEMETRY_AGENT_REQUIRED } from '../constants';
|
||||
import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry';
|
||||
|
||||
const fleetAgentLinkProps = { appId: FLEET_APP_ID, path: ADD_AGENT_PATH };
|
||||
|
||||
export const AgentRequiredCallout = React.memo(() => {
|
||||
const { getAppUrl, navigateTo } = useNavigation();
|
||||
const addAgentLink = getAppUrl(fleetAgentLinkProps);
|
||||
const onAddAgentClick = useCallback(() => {
|
||||
navigateTo(fleetAgentLinkProps);
|
||||
}, [navigateTo]);
|
||||
const onAddAgentClick = useCallback(
|
||||
(e: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
e.preventDefault();
|
||||
trackOnboardingLinkClick(TELEMETRY_AGENT_REQUIRED);
|
||||
navigateTo(fleetAgentLinkProps);
|
||||
},
|
||||
[navigateTo]
|
||||
);
|
||||
|
||||
return (
|
||||
<CardCallOut
|
||||
|
|
|
@ -10,10 +10,10 @@ import React from 'react';
|
|||
import { TestProviders } from '../../../../../../common/mock/test_providers';
|
||||
import { AgentlessAvailableCallout } from './agentless_available_callout';
|
||||
import { useKibana } from '../../../../../../common/lib/kibana';
|
||||
import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry';
|
||||
|
||||
jest.mock('../../../../../../common/lib/kibana', () => ({
|
||||
useKibana: jest.fn(),
|
||||
}));
|
||||
jest.mock('../../../../../../common/lib/kibana');
|
||||
jest.mock('../../../../../common/lib/telemetry');
|
||||
|
||||
describe('AgentlessAvailableCallout', () => {
|
||||
const mockUseKibana = useKibana as jest.Mock;
|
||||
|
@ -62,4 +62,14 @@ describe('AgentlessAvailableCallout', () => {
|
|||
).toBeInTheDocument();
|
||||
expect(getByTestId('agentlessLearnMoreLink')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should track the agentless learn more link click', () => {
|
||||
const { getByTestId } = render(<AgentlessAvailableCallout />, {
|
||||
wrapper: TestProviders,
|
||||
});
|
||||
|
||||
getByTestId('agentlessLearnMoreLink').click();
|
||||
|
||||
expect(trackOnboardingLinkClick).toHaveBeenCalledWith('agentless_learn_more');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,19 +5,25 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { EuiIcon, useEuiTheme } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
|
||||
import { useKibana } from '../../../../../../common/lib/kibana';
|
||||
import { LinkAnchor } from '../../../../../../common/components/links';
|
||||
import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry';
|
||||
import { CardCallOut } from '../../common/card_callout';
|
||||
import { TELEMETRY_AGENTLESS_LEARN_MORE } from '../constants';
|
||||
|
||||
export const AgentlessAvailableCallout = React.memo(() => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const { docLinks } = useKibana().services;
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
trackOnboardingLinkClick(TELEMETRY_AGENTLESS_LEARN_MORE);
|
||||
}, []);
|
||||
|
||||
/* @ts-expect-error: add the blog link to `packages/kbn-doc-links/src/get_doc_links.ts` when it is ready and remove this exit condition*/
|
||||
if (!docLinks.links.fleet.agentlessBlog) {
|
||||
return null;
|
||||
|
@ -54,6 +60,7 @@ export const AgentlessAvailableCallout = React.memo(() => {
|
|||
<LinkAnchor
|
||||
/* @ts-expect-error-next-line */
|
||||
href={docLinks.links.fleet.agentlessBlog}
|
||||
onClick={onClick}
|
||||
data-test-subj="agentlessLearnMoreLink"
|
||||
external={true}
|
||||
target="_blank"
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
/*
|
||||
* 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 from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { EndpointCallout } from './endpoint_callout';
|
||||
import { TestProviders } from '../../../../../../common/mock/test_providers';
|
||||
import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry';
|
||||
|
||||
jest.mock('../../../../../../common/lib/kibana');
|
||||
jest.mock('../../../../../common/lib/telemetry');
|
||||
|
||||
describe('EndpointCallout', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders the callout', () => {
|
||||
const { getByTestId, getByText } = render(<EndpointCallout />, { wrapper: TestProviders });
|
||||
|
||||
expect(
|
||||
getByText('Orchestrate response across endpoint vendors with bidirectional integrations')
|
||||
).toBeInTheDocument();
|
||||
expect(getByTestId('endpointLearnMoreLink')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should track the agent link click', () => {
|
||||
const { getByTestId } = render(<EndpointCallout />, { wrapper: TestProviders });
|
||||
|
||||
getByTestId('endpointLearnMoreLink').click();
|
||||
|
||||
expect(trackOnboardingLinkClick).toHaveBeenCalledWith('endpoint_learn_more');
|
||||
});
|
||||
});
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { EuiIcon, useEuiTheme } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
|
@ -13,10 +13,15 @@ import { css } from '@emotion/react';
|
|||
import { useKibana } from '../../../../../../common/lib/kibana/kibana_react';
|
||||
import { LinkAnchor } from '../../../../../../common/components/links';
|
||||
import { CardCallOut } from '../../common/card_callout';
|
||||
import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry';
|
||||
import { TELEMETRY_ENDPOINT_LEARN_MORE } from '../constants';
|
||||
|
||||
export const EndpointCallout = React.memo(() => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const { docLinks } = useKibana().services;
|
||||
const onClick = useCallback(() => {
|
||||
trackOnboardingLinkClick(TELEMETRY_ENDPOINT_LEARN_MORE);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<CardCallOut
|
||||
|
@ -51,6 +56,7 @@ export const EndpointCallout = React.memo(() => {
|
|||
data-test-subj="endpointLearnMoreLink"
|
||||
external={true}
|
||||
target="_blank"
|
||||
onClick={onClick}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.onboarding.integrationsCard.callout.button.endpointLearnMoreLink"
|
||||
|
|
|
@ -4,18 +4,29 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { EuiIcon } from '@elastic/eui';
|
||||
|
||||
import { LinkAnchor } from '../../../../../../common/components/links';
|
||||
import { CardCallOut } from '../../common/card_callout';
|
||||
import { useAddIntegrationsUrl } from '../../../../../../common/hooks/use_add_integrations_url';
|
||||
import { trackOnboardingLinkClick } from '../../../../../common/lib/telemetry';
|
||||
import { TELEMETRY_MANAGE_INTEGRATIONS } from '../constants';
|
||||
|
||||
export const ManageIntegrationsCallout = React.memo(
|
||||
({ installedIntegrationsCount }: { installedIntegrationsCount: number }) => {
|
||||
const { href: integrationUrl, onClick: onAddIntegrationClicked } = useAddIntegrationsUrl();
|
||||
|
||||
const onClick = useCallback(
|
||||
(e: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
e.preventDefault();
|
||||
trackOnboardingLinkClick(TELEMETRY_MANAGE_INTEGRATIONS);
|
||||
onAddIntegrationClicked(e);
|
||||
},
|
||||
[onAddIntegrationClicked]
|
||||
);
|
||||
|
||||
if (!installedIntegrationsCount) {
|
||||
return null;
|
||||
}
|
||||
|
@ -41,7 +52,7 @@ export const ManageIntegrationsCallout = React.memo(
|
|||
),
|
||||
link: (
|
||||
<LinkAnchor
|
||||
onClick={onAddIntegrationClicked}
|
||||
onClick={onClick}
|
||||
href={integrationUrl}
|
||||
data-test-subj="manageIntegrationsLink"
|
||||
>
|
||||
|
|
|
@ -24,3 +24,9 @@ export const SCROLL_ELEMENT_ID = 'integrations-scroll-container';
|
|||
export const SEARCH_FILTER_CATEGORIES: CategoryFacet[] = [];
|
||||
export const WITH_SEARCH_BOX_HEIGHT = '568px';
|
||||
export const WITHOUT_SEARCH_BOX_HEIGHT = '513px';
|
||||
export const TELEMETRY_MANAGE_INTEGRATIONS = `manage_integrations`;
|
||||
export const TELEMETRY_ENDPOINT_LEARN_MORE = `endpoint_learn_more`;
|
||||
export const TELEMETRY_AGENTLESS_LEARN_MORE = `agentless_learn_more`;
|
||||
export const TELEMETRY_AGENT_REQUIRED = `agent_required`;
|
||||
export const TELEMETRY_INTEGRATION_CARD = `card`;
|
||||
export const TELEMETRY_INTEGRATION_TAB = `tab`;
|
||||
|
|
|
@ -15,9 +15,11 @@ import {
|
|||
useStoredIntegrationTabId,
|
||||
} from '../../../../hooks/use_stored_state';
|
||||
import { DEFAULT_TAB } from './constants';
|
||||
import { trackOnboardingLinkClick } from '../../../../common/lib/telemetry';
|
||||
|
||||
jest.mock('../../../onboarding_context');
|
||||
jest.mock('../../../../hooks/use_stored_state');
|
||||
jest.mock('../../../../common/lib/telemetry');
|
||||
|
||||
jest.mock('../../../../../common/lib/kibana', () => ({
|
||||
...jest.requireActual('../../../../../common/lib/kibana'),
|
||||
|
@ -118,6 +120,33 @@ describe('IntegrationsCardGridTabsComponent', () => {
|
|||
expect(mockSetTabId).toHaveBeenCalledWith('user');
|
||||
});
|
||||
|
||||
it('tracks the tab clicks', () => {
|
||||
(useStoredIntegrationTabId as jest.Mock).mockReturnValue(['recommended', mockSetTabId]);
|
||||
|
||||
mockUseAvailablePackages.mockReturnValue({
|
||||
isLoading: false,
|
||||
filteredCards: [],
|
||||
setCategory: mockSetCategory,
|
||||
setSelectedSubCategory: mockSetSelectedSubCategory,
|
||||
setSearchTerm: mockSetSearchTerm,
|
||||
});
|
||||
|
||||
const { getByTestId } = render(
|
||||
<IntegrationsCardGridTabsComponent
|
||||
{...props}
|
||||
useAvailablePackages={mockUseAvailablePackages}
|
||||
/>
|
||||
);
|
||||
|
||||
const tabButton = getByTestId('user');
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(tabButton);
|
||||
});
|
||||
|
||||
expect(trackOnboardingLinkClick).toHaveBeenCalledWith('tab_user');
|
||||
});
|
||||
|
||||
it('renders no search tools when showSearchTools is false', async () => {
|
||||
mockUseAvailablePackages.mockReturnValue({
|
||||
isLoading: false,
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
LOADING_SKELETON_TEXT_LINES,
|
||||
SCROLL_ELEMENT_ID,
|
||||
SEARCH_FILTER_CATEGORIES,
|
||||
TELEMETRY_INTEGRATION_TAB,
|
||||
WITHOUT_SEARCH_BOX_HEIGHT,
|
||||
WITH_SEARCH_BOX_HEIGHT,
|
||||
} from './constants';
|
||||
|
@ -28,6 +29,7 @@ import { INTEGRATION_TABS, INTEGRATION_TABS_BY_ID } from './integration_tabs_con
|
|||
import { useIntegrationCardList } from './use_integration_card_list';
|
||||
import { IntegrationTabId } from './types';
|
||||
import { IntegrationCardTopCallout } from './callouts/integration_card_top_callout';
|
||||
import { trackOnboardingLinkClick } from '../../../../common/lib/telemetry';
|
||||
|
||||
export interface IntegrationsCardGridTabsProps {
|
||||
installedIntegrationsCount: number;
|
||||
|
@ -55,8 +57,10 @@ export const IntegrationsCardGridTabsComponent = React.memo<IntegrationsCardGrid
|
|||
const onTabChange = useCallback(
|
||||
(stringId: string) => {
|
||||
const id = stringId as IntegrationTabId;
|
||||
const trackId = `${TELEMETRY_INTEGRATION_TAB}_${id}`;
|
||||
scrollElement.current?.scrollTo?.(0, 0);
|
||||
setSelectedTabIdToStorage(id);
|
||||
trackOnboardingLinkClick(trackId);
|
||||
},
|
||||
[setSelectedTabIdToStorage]
|
||||
);
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
*/
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { useIntegrationCardList } from './use_integration_card_list';
|
||||
import { trackOnboardingLinkClick } from '../../../../common/lib/telemetry';
|
||||
|
||||
jest.mock('../../../../common/lib/telemetry');
|
||||
jest.mock('../../../../../common/lib/kibana', () => ({
|
||||
...jest.requireActual('../../../../../common/lib/kibana'),
|
||||
useNavigation: jest.fn().mockReturnValue({
|
||||
navigateTo: jest.fn(),
|
||||
getAppUrl: jest.fn(),
|
||||
getAppUrl: jest.fn().mockReturnValue(''),
|
||||
}),
|
||||
}));
|
||||
|
||||
|
@ -73,4 +75,17 @@ describe('useIntegrationCardList', () => {
|
|||
|
||||
expect(result.current).toEqual([mockFilteredCards.featuredCards['epr:endpoint']]);
|
||||
});
|
||||
|
||||
it('tracks integration card click', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useIntegrationCardList({
|
||||
integrationsList: mockIntegrationsList,
|
||||
})
|
||||
);
|
||||
|
||||
const card = result.current[0];
|
||||
card.onCardClick?.();
|
||||
|
||||
expect(trackOnboardingLinkClick).toHaveBeenCalledWith('card_epr:endpoint');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -20,8 +20,10 @@ import {
|
|||
MAX_CARD_HEIGHT_IN_PX,
|
||||
ONBOARDING_APP_ID,
|
||||
ONBOARDING_LINK,
|
||||
TELEMETRY_INTEGRATION_CARD,
|
||||
} from './constants';
|
||||
import type { GetAppUrl, NavigateTo } from '../../../../../common/lib/kibana';
|
||||
import { trackOnboardingLinkClick } from '../../../../common/lib/telemetry';
|
||||
|
||||
const addPathParamToUrl = (url: string, onboardingLink: string) => {
|
||||
const encoded = encodeURIComponent(onboardingLink);
|
||||
|
@ -97,6 +99,8 @@ const addSecuritySpecificProps = ({
|
|||
showInstallationStatus: true,
|
||||
url,
|
||||
onCardClick: () => {
|
||||
const trackId = `${TELEMETRY_INTEGRATION_CARD}_${card.id}`;
|
||||
trackOnboardingLinkClick(trackId);
|
||||
if (url.startsWith(APP_INTEGRATIONS_PATH)) {
|
||||
navigateTo({
|
||||
appId: INTEGRATION_APP_ID,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue