mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Dashboard Navigation] Add Links telemetry (#171877)
Closes https://github.com/elastic/kibana/issues/164305
## Summary
This PR adds two `uiCounters` to keep track of when something is clicked
in the new Links panel:
1. `dashboardLink:click` - counts when a dashboard link is clicked
2. `externalLink:click` - counts when an external link is clicked
These counters can be tracked via the `kibana-ui-counters` data view on
the telemetry clusters, like so:

Note that this **only** applies if the `onClick` method is called; if
the user, for example, right clicks on the link and selects "Open in new
tab" instead, this "click" will not be tracked. To my knowledge, there
is no way to track these types of clicks.
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
618cc48bc5
commit
31a8b7bca6
6 changed files with 45 additions and 23 deletions
|
@ -17,7 +17,7 @@
|
|||
"uiActionsEnhanced",
|
||||
"visualizations"
|
||||
],
|
||||
"optionalPlugins": ["triggersActionsUi"],
|
||||
"optionalPlugins": ["triggersActionsUi", "usageCollection"],
|
||||
"requiredBundles": ["savedObjects"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import useAsync from 'react-use/lib/useAsync';
|
|||
import useObservable from 'react-use/lib/useObservable';
|
||||
|
||||
import { EuiButtonEmpty, EuiListGroupItem } from '@elastic/eui';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import {
|
||||
DashboardLocatorParams,
|
||||
getDashboardLocatorParamsFromEmbeddable,
|
||||
|
@ -22,7 +23,13 @@ import {
|
|||
DEFAULT_DASHBOARD_DRILLDOWN_OPTIONS,
|
||||
} from '@kbn/presentation-util-plugin/public';
|
||||
|
||||
import { Link, LinksLayoutType, LINKS_VERTICAL_LAYOUT } from '../../../common/content_management';
|
||||
import {
|
||||
DASHBOARD_LINK_TYPE,
|
||||
Link,
|
||||
LinksLayoutType,
|
||||
LINKS_VERTICAL_LAYOUT,
|
||||
} from '../../../common/content_management';
|
||||
import { trackUiMetric } from '../../services/kibana_services';
|
||||
import { useLinks } from '../links_hooks';
|
||||
import { DashboardLinkStrings } from './dashboard_link_strings';
|
||||
import { fetchDashboard } from './dashboard_link_tools';
|
||||
|
@ -97,9 +104,9 @@ export const DashboardLinkComponent = ({
|
|||
/**
|
||||
* Dashboard-to-dashboard navigation
|
||||
*/
|
||||
const { loading: loadingOnClickProps, value: onClickProps } = useAsync(async () => {
|
||||
const onClickProps = useMemo(() => {
|
||||
/** If the link points to the current dashboard, then there should be no `onClick` or `href` prop */
|
||||
if (link.destination === parentDashboardId) return;
|
||||
if (!link.destination || link.destination === parentDashboardId) return;
|
||||
|
||||
const linkOptions = {
|
||||
...DEFAULT_DASHBOARD_DRILLDOWN_OPTIONS,
|
||||
|
@ -118,6 +125,8 @@ export const DashboardLinkComponent = ({
|
|||
return {
|
||||
href,
|
||||
onClick: async (event: React.MouseEvent) => {
|
||||
trackUiMetric?.(METRIC_TYPE.CLICK, `${DASHBOARD_LINK_TYPE}:click`);
|
||||
|
||||
/**
|
||||
* If the link is being opened via a modified click, then we should use the default `href` navigation behaviour
|
||||
* by passing all the dashboard state via the URL - this will keep behaviour consistent across all browsers.
|
||||
|
@ -132,26 +141,19 @@ export const DashboardLinkComponent = ({
|
|||
if (linkOptions.openInNewTab) {
|
||||
window.open(href, '_blank');
|
||||
} else {
|
||||
locator.navigate(params);
|
||||
await locator.navigate(params);
|
||||
}
|
||||
},
|
||||
};
|
||||
}, [link]);
|
||||
}, [link, dashboardContainer.locator, linksEmbeddable, parentDashboardId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (loadingDestinationDashboard || loadingOnClickProps) {
|
||||
if (loadingDestinationDashboard) {
|
||||
onLoading();
|
||||
} else {
|
||||
onRender();
|
||||
}
|
||||
}, [
|
||||
link,
|
||||
linksEmbeddable,
|
||||
loadingDestinationDashboard,
|
||||
loadingOnClickProps,
|
||||
onLoading,
|
||||
onRender,
|
||||
]);
|
||||
}, [link, linksEmbeddable, loadingDestinationDashboard, onLoading, onRender]);
|
||||
|
||||
const id = `dashboardLink--${link.id}`;
|
||||
|
||||
|
@ -178,7 +180,7 @@ export const DashboardLinkComponent = ({
|
|||
}}
|
||||
iconType={error ? 'warning' : undefined}
|
||||
iconProps={{ className: 'dashboardLinkIcon' }}
|
||||
isDisabled={Boolean(error) || loadingOnClickProps}
|
||||
isDisabled={Boolean(error)}
|
||||
className={classNames('linksPanelLink', {
|
||||
linkCurrent: link.destination === parentDashboardId,
|
||||
dashboardLinkError: Boolean(error),
|
||||
|
|
|
@ -9,15 +9,21 @@
|
|||
import React, { useMemo, useState } from 'react';
|
||||
import useMount from 'react-use/lib/useMount';
|
||||
|
||||
import {
|
||||
UrlDrilldownOptions,
|
||||
DEFAULT_URL_DRILLDOWN_OPTIONS,
|
||||
} from '@kbn/ui-actions-enhanced-plugin/public';
|
||||
import { EuiListGroupItem } from '@elastic/eui';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import {
|
||||
DEFAULT_URL_DRILLDOWN_OPTIONS,
|
||||
UrlDrilldownOptions,
|
||||
} from '@kbn/ui-actions-enhanced-plugin/public';
|
||||
|
||||
import {
|
||||
EXTERNAL_LINK_TYPE,
|
||||
Link,
|
||||
LinksLayoutType,
|
||||
LINKS_VERTICAL_LAYOUT,
|
||||
} from '../../../common/content_management';
|
||||
import { coreServices, trackUiMetric } from '../../services/kibana_services';
|
||||
import { validateUrl } from './external_link_tools';
|
||||
import { coreServices } from '../../services/kibana_services';
|
||||
import { Link, LinksLayoutType, LINKS_VERTICAL_LAYOUT } from '../../../common/content_management';
|
||||
|
||||
export const ExternalLinkComponent = ({
|
||||
link,
|
||||
|
@ -78,6 +84,8 @@ export const ExternalLinkComponent = ({
|
|||
onClick={async (event) => {
|
||||
if (!destination) return;
|
||||
|
||||
trackUiMetric?.(METRIC_TYPE.CLICK, `${EXTERNAL_LINK_TYPE}:click`);
|
||||
|
||||
/** Only use `navigateToUrl` if we **aren't** opening in a new window/tab; otherwise, just use default href handling */
|
||||
const modifiedClick = event.ctrlKey || event.metaKey || event.shiftKey;
|
||||
if (!modifiedClick) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import { DashboardStart } from '@kbn/dashboard-plugin/public';
|
|||
import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container';
|
||||
import { EmbeddableSetup, EmbeddableStart } from '@kbn/embeddable-plugin/public';
|
||||
import { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public';
|
||||
import { UsageCollectionStart } from '@kbn/usage-collection-plugin/public';
|
||||
import { VisualizationsSetup } from '@kbn/visualizations-plugin/public';
|
||||
|
||||
import { APP_ICON, APP_NAME, CONTENT_ID, LATEST_VERSION } from '../common';
|
||||
|
@ -36,6 +37,7 @@ export interface LinksStartDependencies {
|
|||
dashboard: DashboardStart;
|
||||
presentationUtil: PresentationUtilPluginStart;
|
||||
contentManagement: ContentManagementPublicStart;
|
||||
usageCollection?: UsageCollectionStart;
|
||||
}
|
||||
|
||||
export class LinksPlugin
|
||||
|
|
|
@ -8,12 +8,13 @@
|
|||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
import { ContentManagementPublicStart } from '@kbn/content-management-plugin/public';
|
||||
import { CoreStart } from '@kbn/core/public';
|
||||
import { DashboardStart } from '@kbn/dashboard-plugin/public';
|
||||
import { EmbeddableStart } from '@kbn/embeddable-plugin/public';
|
||||
import { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public';
|
||||
import { ContentManagementPublicStart } from '@kbn/content-management-plugin/public';
|
||||
|
||||
import { CONTENT_ID } from '../../common';
|
||||
import { LinksStartDependencies } from '../plugin';
|
||||
|
||||
export let coreServices: CoreStart;
|
||||
|
@ -21,6 +22,11 @@ export let dashboardServices: DashboardStart;
|
|||
export let embeddableService: EmbeddableStart;
|
||||
export let presentationUtil: PresentationUtilPluginStart;
|
||||
export let contentManagement: ContentManagementPublicStart;
|
||||
export let trackUiMetric: (
|
||||
type: string,
|
||||
eventNames: string | string[],
|
||||
count?: number
|
||||
) => void | undefined;
|
||||
|
||||
const servicesReady$ = new BehaviorSubject(false);
|
||||
|
||||
|
@ -42,6 +48,8 @@ export const setKibanaServices = (kibanaCore: CoreStart, deps: LinksStartDepende
|
|||
embeddableService = deps.embeddable;
|
||||
presentationUtil = deps.presentationUtil;
|
||||
contentManagement = deps.contentManagement;
|
||||
if (deps.usageCollection)
|
||||
trackUiMetric = deps.usageCollection.reportUiCounter.bind(deps.usageCollection, CONTENT_ID);
|
||||
|
||||
servicesReady$.next(true);
|
||||
};
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
"@kbn/core-plugins-server",
|
||||
"@kbn/react-kibana-mount",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
"@kbn/analytics",
|
||||
"@kbn/usage-collection-plugin",
|
||||
"@kbn/visualizations-plugin",
|
||||
"@kbn/core-mount-utils-browser"
|
||||
],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue