Add telemetry for editor clicks events (#100664) (#102341)

* Track editor clicks events

Closes: #98949

* add create and open telemetries

* add telemetry for dashboard

* remove hardcoded originatingApp for lens

* DashboardConstants.DASHBOARDS_ID ->  DashboardConstants.DASHBOARD_ID

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Alexey Antonov 2021-06-16 18:21:17 +03:00 committed by GitHub
parent 0adf3b5ff0
commit db1bd7ec03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 175 additions and 56 deletions

View file

@ -9,7 +9,7 @@ Constructs a new instance of the `AddPanelAction` class
<b>Signature:</b>
```typescript
constructor(getFactory: EmbeddableStart['getEmbeddableFactory'], getAllFactories: EmbeddableStart['getEmbeddableFactories'], overlays: OverlayStart, notifications: NotificationsStart, SavedObjectFinder: React.ComponentType<any>);
constructor(getFactory: EmbeddableStart['getEmbeddableFactory'], getAllFactories: EmbeddableStart['getEmbeddableFactories'], overlays: OverlayStart, notifications: NotificationsStart, SavedObjectFinder: React.ComponentType<any>, reportUiCounter?: ((appName: string, type: import("@kbn/analytics").UiCounterMetricType, eventNames: string | string[], count?: number | undefined) => void) | undefined);
```
## Parameters
@ -21,4 +21,5 @@ constructor(getFactory: EmbeddableStart['getEmbeddableFactory'], getAllFactories
| overlays | <code>OverlayStart</code> | |
| notifications | <code>NotificationsStart</code> | |
| SavedObjectFinder | <code>React.ComponentType&lt;any&gt;</code> | |
| reportUiCounter | <code>((appName: string, type: import(&quot;@kbn/analytics&quot;).UiCounterMetricType, eventNames: string &#124; string[], count?: number &#124; undefined) =&gt; void) &#124; undefined</code> | |

View file

@ -14,7 +14,7 @@ export declare class AddPanelAction implements Action<ActionContext>
| Constructor | Modifiers | Description |
| --- | --- | --- |
| [(constructor)(getFactory, getAllFactories, overlays, notifications, SavedObjectFinder)](./kibana-plugin-plugins-embeddable-public.addpanelaction._constructor_.md) | | Constructs a new instance of the <code>AddPanelAction</code> class |
| [(constructor)(getFactory, getAllFactories, overlays, notifications, SavedObjectFinder, reportUiCounter)](./kibana-plugin-plugins-embeddable-public.addpanelaction._constructor_.md) | | Constructs a new instance of the <code>AddPanelAction</code> class |
## Properties

View file

@ -15,6 +15,7 @@ export declare function openAddPanelFlyout(options: {
notifications: NotificationsStart;
SavedObjectFinder: React.ComponentType<any>;
showCreateNewMenu?: boolean;
reportUiCounter?: UsageCollectionStart['reportUiCounter'];
}): OverlayRef;
```
@ -22,7 +23,7 @@ export declare function openAddPanelFlyout(options: {
| Parameter | Type | Description |
| --- | --- | --- |
| options | <code>{</code><br/><code> embeddable: IContainer;</code><br/><code> getFactory: EmbeddableStart['getEmbeddableFactory'];</code><br/><code> getAllFactories: EmbeddableStart['getEmbeddableFactories'];</code><br/><code> overlays: OverlayStart;</code><br/><code> notifications: NotificationsStart;</code><br/><code> SavedObjectFinder: React.ComponentType&lt;any&gt;;</code><br/><code> showCreateNewMenu?: boolean;</code><br/><code>}</code> | |
| options | <code>{</code><br/><code> embeddable: IContainer;</code><br/><code> getFactory: EmbeddableStart['getEmbeddableFactory'];</code><br/><code> getAllFactories: EmbeddableStart['getEmbeddableFactories'];</code><br/><code> overlays: OverlayStart;</code><br/><code> notifications: NotificationsStart;</code><br/><code> SavedObjectFinder: React.ComponentType&lt;any&gt;;</code><br/><code> showCreateNewMenu?: boolean;</code><br/><code> reportUiCounter?: UsageCollectionStart['reportUiCounter'];</code><br/><code>}</code> | |
<b>Returns:</b>

View file

@ -132,7 +132,7 @@ export function DashboardTopNav({
const trackUiMetric = usageCollection?.reportUiCounter.bind(
usageCollection,
DashboardConstants.DASHBOARDS_ID
DashboardConstants.DASHBOARD_ID
);
useEffect(() => {
@ -163,6 +163,7 @@ export function DashboardTopNav({
notifications: core.notifications,
overlays: core.overlays,
SavedObjectFinder: getSavedObjectFinder(core.savedObjects, uiSettings),
reportUiCounter: usageCollection?.reportUiCounter,
}),
}));
}
@ -174,6 +175,7 @@ export function DashboardTopNav({
core.savedObjects,
core.overlays,
uiSettings,
usageCollection,
]);
const createNewVisType = useCallback(
@ -183,7 +185,7 @@ export function DashboardTopNav({
if (visType) {
if (trackUiMetric) {
trackUiMetric(METRIC_TYPE.CLICK, visType.name);
trackUiMetric(METRIC_TYPE.CLICK, `${visType.name}:create`);
}
if ('aliasPath' in visType) {

View file

@ -51,7 +51,7 @@ export const EditorMenu = ({ dashboardContainer, createNewVisType }: Props) => {
const trackUiMetric = usageCollection?.reportUiCounter.bind(
usageCollection,
DashboardConstants.DASHBOARDS_ID
DashboardConstants.DASHBOARD_ID
);
const createNewAggsBasedVis = useCallback(

View file

@ -14,6 +14,7 @@ import deepEqual from 'fast-deep-equal';
import { buildContextMenuForActions, UiActionsService, Action } from '../ui_actions';
import { CoreStart, OverlayStart } from '../../../../../core/public';
import { toMountPoint } from '../../../../kibana_react/public';
import { UsageCollectionStart } from '../../../../usage_collection/public';
import { Start as InspectorStartContract } from '../inspector';
import {
@ -62,6 +63,7 @@ interface Props {
SavedObjectFinder: React.ComponentType<any>;
stateTransfer?: EmbeddableStateTransfer;
hideHeader?: boolean;
reportUiCounter?: UsageCollectionStart['reportUiCounter'];
}
interface State {
@ -312,7 +314,8 @@ export class EmbeddablePanel extends React.Component<Props, State> {
this.props.getAllEmbeddableFactories,
this.props.overlays,
this.props.notifications,
this.props.SavedObjectFinder
this.props.SavedObjectFinder,
this.props.reportUiCounter
),
inspectPanel: new InspectPanelAction(this.props.inspector),
removePanel: new RemovePanelAction(),

View file

@ -13,6 +13,7 @@ import { EmbeddableStart } from 'src/plugins/embeddable/public/plugin';
import { ViewMode } from '../../../../types';
import { openAddPanelFlyout } from './open_add_panel_flyout';
import { IContainer } from '../../../../containers';
import { UsageCollectionStart } from '../../../../../../../usage_collection/public';
export const ACTION_ADD_PANEL = 'ACTION_ADD_PANEL';
@ -29,7 +30,8 @@ export class AddPanelAction implements Action<ActionContext> {
private readonly getAllFactories: EmbeddableStart['getEmbeddableFactories'],
private readonly overlays: OverlayStart,
private readonly notifications: NotificationsStart,
private readonly SavedObjectFinder: React.ComponentType<any>
private readonly SavedObjectFinder: React.ComponentType<any>,
private readonly reportUiCounter?: UsageCollectionStart['reportUiCounter']
) {}
public getDisplayName() {
@ -60,6 +62,7 @@ export class AddPanelAction implements Action<ActionContext> {
overlays: this.overlays,
notifications: this.notifications,
SavedObjectFinder: this.SavedObjectFinder,
reportUiCounter: this.reportUiCounter,
});
}
}

View file

@ -9,15 +9,17 @@
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import React, { ReactElement } from 'react';
import { CoreSetup } from 'src/core/public';
import { METRIC_TYPE } from '@kbn/analytics';
import { CoreSetup, SavedObjectAttributes, SimpleSavedObject } from 'src/core/public';
import { EuiContextMenuItem, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui';
import { EmbeddableStart } from 'src/plugins/embeddable/public';
import { EmbeddableFactory, EmbeddableStart } from 'src/plugins/embeddable/public';
import { IContainer } from '../../../../containers';
import { EmbeddableFactoryNotFoundError } from '../../../../errors';
import { SavedObjectFinderCreateNew } from './saved_object_finder_create_new';
import { SavedObjectEmbeddableInput } from '../../../../embeddables';
import { UsageCollectionStart } from '../../../../../../../usage_collection/public';
interface Props {
onClose: () => void;
@ -27,6 +29,7 @@ interface Props {
notifications: CoreSetup['notifications'];
SavedObjectFinder: React.ComponentType<any>;
showCreateNewMenu?: boolean;
reportUiCounter?: UsageCollectionStart['reportUiCounter'];
}
interface State {
@ -84,7 +87,12 @@ export class AddPanelFlyout extends React.Component<Props, State> {
}
};
public onAddPanel = async (savedObjectId: string, savedObjectType: string, name: string) => {
public onAddPanel = async (
savedObjectId: string,
savedObjectType: string,
name: string,
so: SimpleSavedObject<SavedObjectAttributes>
) => {
const factoryForSavedObjectType = [...this.props.getAllFactories()].find(
(factory) =>
factory.savedObjectMetaData && factory.savedObjectMetaData.type === savedObjectType
@ -98,9 +106,27 @@ export class AddPanelFlyout extends React.Component<Props, State> {
{ savedObjectId }
);
this.doTelemetryForAddEvent(this.props.container.type, factoryForSavedObjectType, so);
this.showToast(name);
};
private doTelemetryForAddEvent(
appName: string,
factoryForSavedObjectType: EmbeddableFactory,
so: SimpleSavedObject<SavedObjectAttributes>
) {
const { reportUiCounter } = this.props;
if (reportUiCounter) {
const type = factoryForSavedObjectType.savedObjectMetaData?.getSavedObjectSubType
? factoryForSavedObjectType.savedObjectMetaData.getSavedObjectSubType(so)
: factoryForSavedObjectType.type;
reportUiCounter(appName, METRIC_TYPE.CLICK, `${type}:add`);
}
}
private getCreateMenuItems(): ReactElement[] {
return [...this.props.getAllFactories()]
.filter(

View file

@ -12,6 +12,7 @@ import { EmbeddableStart } from '../../../../../plugin';
import { toMountPoint } from '../../../../../../../kibana_react/public';
import { IContainer } from '../../../../containers';
import { AddPanelFlyout } from './add_panel_flyout';
import { UsageCollectionStart } from '../../../../../../../usage_collection/public';
export function openAddPanelFlyout(options: {
embeddable: IContainer;
@ -21,6 +22,7 @@ export function openAddPanelFlyout(options: {
notifications: NotificationsStart;
SavedObjectFinder: React.ComponentType<any>;
showCreateNewMenu?: boolean;
reportUiCounter?: UsageCollectionStart['reportUiCounter'];
}): OverlayRef {
const {
embeddable,
@ -30,6 +32,7 @@ export function openAddPanelFlyout(options: {
notifications,
SavedObjectFinder,
showCreateNewMenu,
reportUiCounter,
} = options;
const flyoutSession = overlays.openFlyout(
toMountPoint(
@ -43,6 +46,7 @@ export function openAddPanelFlyout(options: {
getFactory={getFactory}
getAllFactories={getAllFactories}
notifications={notifications}
reportUiCounter={reportUiCounter}
SavedObjectFinder={SavedObjectFinder}
showCreateNewMenu={showCreateNewMenu}
/>

View file

@ -63,6 +63,7 @@ import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport';
import { Type } from '@kbn/config-schema';
import { TypeOf } from '@kbn/config-schema';
import { UiComponent } from 'src/plugins/kibana_utils/public';
import { UiCounterMetricType } from '@kbn/analytics';
import { UnregisterCallback } from 'history';
import { URL } from 'url';
import { UserProvidedValues } from 'src/core/server/types';
@ -95,7 +96,7 @@ export interface Adapters {
// @public (undocumented)
export class AddPanelAction implements Action_3<ActionContext_2> {
// Warning: (ae-forgotten-export) The symbol "React" needs to be exported by the entry point index.d.ts
constructor(getFactory: EmbeddableStart_2['getEmbeddableFactory'], getAllFactories: EmbeddableStart_2['getEmbeddableFactories'], overlays: OverlayStart_2, notifications: NotificationsStart_2, SavedObjectFinder: React_2.ComponentType<any>);
constructor(getFactory: EmbeddableStart_2['getEmbeddableFactory'], getAllFactories: EmbeddableStart_2['getEmbeddableFactories'], overlays: OverlayStart_2, notifications: NotificationsStart_2, SavedObjectFinder: React_2.ComponentType<any>, reportUiCounter?: ((appName: string, type: import("@kbn/analytics").UiCounterMetricType, eventNames: string | string[], count?: number | undefined) => void) | undefined);
// (undocumented)
execute(context: ActionExecutionContext_2<ActionContext_2>): Promise<void>;
// (undocumented)
@ -729,6 +730,7 @@ export function openAddPanelFlyout(options: {
notifications: NotificationsStart_2;
SavedObjectFinder: React.ComponentType<any>;
showCreateNewMenu?: boolean;
reportUiCounter?: UsageCollectionStart['reportUiCounter'];
}): OverlayRef_2;
// Warning: (ae-missing-release-tag) "OutputSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@ -890,6 +892,7 @@ export const withEmbeddableSubscription: <I extends EmbeddableInput, O extends E
// Warnings were encountered during analysis:
//
// src/plugins/embeddable/common/types.ts:31:3 - (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts
// src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/add_panel/open_add_panel_flyout.tsx:25:3 - (ae-forgotten-export) The symbol "UsageCollectionStart" needs to be exported by the entry point index.d.ts
// src/plugins/embeddable/public/lib/triggers/triggers.ts:35:5 - (ae-forgotten-export) The symbol "Datatable" needs to be exported by the entry point index.d.ts
// (No @packageDocumentation comment for this package)

View file

@ -46,6 +46,7 @@ export interface SavedObjectMetaData<T = unknown> {
getIconForSavedObject(savedObject: SimpleSavedObject<T>): IconType;
getTooltipForSavedObject?(savedObject: SimpleSavedObject<T>): string;
showSavedObject?(savedObject: SimpleSavedObject<T>): boolean;
getSavedObjectSubType?(savedObject: SimpleSavedObject<T>): string;
includeFields?: string[];
}

View file

@ -104,6 +104,9 @@ export class VisualizeEmbeddableFactory
}
return visType.stage !== 'experimental';
},
getSavedObjectSubType: (savedObject) => {
return JSON.parse(savedObject.attributes.visState).type;
},
};
constructor(private readonly deps: VisualizeEmbeddableFactoryDeps) {}

View file

@ -7,6 +7,7 @@
*/
import { SavedObject } from '../../../../core/types/saved_objects';
import { BaseVisType } from './base_vis_type';
export type VisualizationStage = 'experimental' | 'beta' | 'production';
@ -23,6 +24,7 @@ export interface VisualizationListItem {
getSupportedTriggers?: () => string[];
typeTitle: string;
image?: string;
type?: BaseVisType | string;
}
export interface VisualizationsAppExtension {

View file

@ -153,7 +153,7 @@ class NewVisModal extends React.Component<TypeSelectionProps, TypeSelectionState
searchId?: string
) {
if (this.trackUiMetric) {
this.trackUiMetric(METRIC_TYPE.CLICK, visType.name);
this.trackUiMetric(METRIC_TYPE.CLICK, `${visType.name}:create`);
}
let params;

View file

@ -16,7 +16,8 @@
"optionalPlugins": [
"home",
"share",
"savedObjectsTaggingOss"
"savedObjectsTaggingOss",
"usageCollection"
],
"requiredBundles": [
"kibanaUtils",

View file

@ -6,9 +6,19 @@
* Side Public License, v 1.
*/
import { History } from 'history';
import { Query, Filter, DataPublicPluginStart, TimeRange } from 'src/plugins/data/public';
import {
import type { EventEmitter } from 'events';
import type { History } from 'history';
import type {
CoreStart,
PluginInitializerContext,
ChromeStart,
ToastsStart,
ScopedHistory,
AppMountParameters,
} from 'kibana/public';
import type {
SavedVisState,
VisualizationsStart,
Vis,
@ -17,28 +27,23 @@ import {
PersistedState,
VisParams,
} from 'src/plugins/visualizations/public';
import {
CoreStart,
PluginInitializerContext,
ChromeStart,
ToastsStart,
ScopedHistory,
AppMountParameters,
} from 'kibana/public';
import { NavigationPublicPluginStart as NavigationStart } from 'src/plugins/navigation/public';
import {
import type {
Storage,
IKbnUrlStateStorage,
ReduxLikeStateContainer,
} from 'src/plugins/kibana_utils/public';
import { SharePluginStart } from 'src/plugins/share/public';
import { SavedObjectsStart, SavedObject } from 'src/plugins/saved_objects/public';
import { EmbeddableStart, EmbeddableStateTransfer } from 'src/plugins/embeddable/public';
import { UrlForwardingStart } from 'src/plugins/url_forwarding/public';
import { PresentationUtilPluginStart } from 'src/plugins/presentation_util/public';
import { EventEmitter } from 'events';
import { DashboardStart } from '../../../dashboard/public';
import type { NavigationPublicPluginStart as NavigationStart } from 'src/plugins/navigation/public';
import type { Query, Filter, DataPublicPluginStart, TimeRange } from 'src/plugins/data/public';
import type { SharePluginStart } from 'src/plugins/share/public';
import type { SavedObjectsStart, SavedObject } from 'src/plugins/saved_objects/public';
import type { EmbeddableStart, EmbeddableStateTransfer } from 'src/plugins/embeddable/public';
import type { UrlForwardingStart } from 'src/plugins/url_forwarding/public';
import type { PresentationUtilPluginStart } from 'src/plugins/presentation_util/public';
import type { DashboardStart } from '../../../dashboard/public';
import type { SavedObjectsTaggingApi } from '../../../saved_objects_tagging_oss/public';
import type { UsageCollectionStart } from '../../../usage_collection/public';
export type PureVisState = SavedVisState;
@ -97,6 +102,7 @@ export interface VisualizeServices extends CoreStart {
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
savedObjectsTagging?: SavedObjectsTaggingApi;
presentationUtil: PresentationUtilPluginStart;
usageCollection?: UsageCollectionStart;
}
export interface SavedVisInstance {

View file

@ -7,6 +7,7 @@
*/
import React from 'react';
import { METRIC_TYPE } from '@kbn/analytics';
import { EuiBetaBadge, EuiButton, EuiEmptyPrompt, EuiIcon, EuiLink, EuiBadge } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
@ -16,6 +17,16 @@ import { VisualizationListItem } from 'src/plugins/visualizations/public';
import type { SavedObjectsTaggingApi } from 'src/plugins/saved_objects_tagging_oss/public';
import { RedirectAppLinks } from '../../../../kibana_react/public';
import { getVisualizeListItemLink } from './get_visualize_list_item_link';
import { getUsageCollector } from '../../services';
import { APP_NAME } from '../visualize_constants';
const doTelemetryForAddEvent = (visType?: string) => {
const usageCollection = getUsageCollector();
if (usageCollection && visType) {
usageCollection.reportUiCounter(APP_NAME, METRIC_TYPE.CLICK, `${visType}:add`);
}
};
const getBadge = (item: VisualizationListItem) => {
if (item.stage === 'beta') {
@ -82,12 +93,16 @@ export const getTableColumns = (
defaultMessage: 'Title',
}),
sortable: true,
render: (field: string, { editApp, editUrl, title, error }: VisualizationListItem) =>
render: (field: string, { editApp, editUrl, title, error, type }: VisualizationListItem) =>
// In case an error occurs i.e. the vis has wrong type, we render the vis but without the link
!error ? (
<RedirectAppLinks application={application} className="visListingTable__titleLink">
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
<EuiLink
href={getVisualizeListItemLink(application, kbnUrlStateStorage, editApp, editUrl)}
onClick={() => {
doTelemetryForAddEvent(typeof type === 'string' ? type : type?.name);
}}
data-test-subj={`visListingTitleLink-${title.split(' ').join('-')}`}
>
{field}

View file

@ -8,6 +8,7 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
import { METRIC_TYPE } from '@kbn/analytics';
import { Capabilities } from 'src/core/public';
import { TopNavMenuData } from 'src/plugins/navigation/public';
@ -29,7 +30,7 @@ import {
VisualizeAppStateContainer,
VisualizeEditorVisInstance,
} from '../types';
import { VisualizeConstants } from '../visualize_constants';
import { APP_NAME, VisualizeConstants } from '../visualize_constants';
import { getEditBreadcrumbs } from './breadcrumbs';
import { EmbeddableStateTransfer } from '../../../../embeddable/public';
@ -92,10 +93,22 @@ export const getTopNavConfig = (
dashboard,
savedObjectsTagging,
presentationUtil,
usageCollection,
}: VisualizeServices
) => {
const { vis, embeddableHandler } = visInstance;
const savedVis = visInstance.savedVis;
const doTelemetryForSaveEvent = (visType: string) => {
if (usageCollection) {
usageCollection.reportUiCounter(
originatingApp ?? APP_NAME,
METRIC_TYPE.CLICK,
`${visType}:save`
);
}
};
/**
* Called when the user clicks "Save" button.
*/
@ -394,6 +407,8 @@ export const getTopNavConfig = (
return { id: true };
}
doTelemetryForSaveEvent(vis.type.name);
// We're adding the viz to a library so we need to save it and then
// add to a dashboard if necessary
const response = await doSave(saveOptions);
@ -503,6 +518,8 @@ export const getTopNavConfig = (
}
},
run: async () => {
doTelemetryForSaveEvent(vis.type.name);
if (!savedVis?.id) {
return createVisReference();
}

View file

@ -6,10 +6,11 @@
* Side Public License, v 1.
*/
import { BehaviorSubject } from 'rxjs';
import { i18n } from '@kbn/i18n';
import { filter, map } from 'rxjs/operators';
import { createHashHistory } from 'history';
import { BehaviorSubject } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import {
AppMountParameters,
AppUpdater,
@ -18,29 +19,33 @@ import {
Plugin,
PluginInitializerContext,
ScopedHistory,
} from 'kibana/public';
DEFAULT_APP_CATEGORIES,
} from '../../../core/public';
import { PresentationUtilPluginStart } from '../../../../src/plugins/presentation_util/public';
import {
Storage,
createKbnUrlTracker,
createKbnUrlStateStorage,
withNotifyOnErrors,
} from '../../kibana_utils/public';
import { DataPublicPluginStart, DataPublicPluginSetup, esFilters } from '../../data/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../navigation/public';
import { SharePluginStart, SharePluginSetup } from '../../share/public';
import { UrlForwardingSetup, UrlForwardingStart } from '../../url_forwarding/public';
import { VisualizationsStart } from '../../visualizations/public';
import { VisualizeConstants } from './application/visualize_constants';
import { DataPublicPluginStart, DataPublicPluginSetup, esFilters } from '../../data/public';
import { FeatureCatalogueCategory, HomePublicPluginSetup } from '../../home/public';
import { VisualizeServices } from './application/types';
import { DEFAULT_APP_CATEGORIES } from '../../../core/public';
import { SavedObjectsStart } from '../../saved_objects/public';
import { EmbeddableStart } from '../../embeddable/public';
import { DashboardStart } from '../../dashboard/public';
import type { PresentationUtilPluginStart } from '../../../../src/plugins/presentation_util/public';
import type { NavigationPublicPluginStart as NavigationStart } from '../../navigation/public';
import type { SharePluginStart, SharePluginSetup } from '../../share/public';
import type { UrlForwardingSetup, UrlForwardingStart } from '../../url_forwarding/public';
import type { VisualizationsStart } from '../../visualizations/public';
import type { VisualizeServices } from './application/types';
import type { SavedObjectsStart } from '../../saved_objects/public';
import type { EmbeddableStart } from '../../embeddable/public';
import type { DashboardStart } from '../../dashboard/public';
import type { SavedObjectTaggingOssPluginStart } from '../../saved_objects_tagging_oss/public';
import { setVisEditorsRegistry, setUISettings } from './services';
import type { UsageCollectionStart } from '../../usage_collection/public';
import { setVisEditorsRegistry, setUISettings, setUsageCollector } from './services';
import { createVisEditorsRegistry, VisEditorsRegistry } from './vis_editors_registry';
export interface VisualizePluginStartDependencies {
@ -54,6 +59,7 @@ export interface VisualizePluginStartDependencies {
dashboard: DashboardStart;
savedObjectsTaggingOss?: SavedObjectTaggingOssPluginStart;
presentationUtil: PresentationUtilPluginStart;
usageCollection?: UsageCollectionStart;
}
export interface VisualizePluginSetupDependencies {
@ -202,6 +208,7 @@ export class VisualizePlugin
setHeaderActionMenu: params.setHeaderActionMenu,
savedObjectsTagging: pluginsStart.savedObjectsTaggingOss?.getTaggingApi(),
presentationUtil: pluginsStart.presentationUtil,
usageCollection: pluginsStart.usageCollection,
};
params.element.classList.add('visAppWrapper');
@ -238,8 +245,12 @@ export class VisualizePlugin
} as VisualizePluginSetup;
}
public start(core: CoreStart, plugins: VisualizePluginStartDependencies) {
public start(core: CoreStart, { usageCollection }: VisualizePluginStartDependencies) {
setVisEditorsRegistry(this.visEditorsRegistry);
if (usageCollection) {
setUsageCollector(usageCollection);
}
}
stop() {

View file

@ -6,12 +6,18 @@
* Side Public License, v 1.
*/
import { IUiSettingsClient } from '../../../core/public';
import { createGetterSetter } from '../../../plugins/kibana_utils/public';
import { VisEditorsRegistry } from './vis_editors_registry';
import type { IUiSettingsClient } from '../../../core/public';
import type { VisEditorsRegistry } from './vis_editors_registry';
import type { UsageCollectionStart } from '../../usage_collection/public';
export const [getUISettings, setUISettings] = createGetterSetter<IUiSettingsClient>('UISettings');
export const [getUsageCollector, setUsageCollector] = createGetterSetter<UsageCollectionStart>(
'UsageCollection'
);
export const [
getVisEditorsRegistry,
setVisEditorsRegistry,

View file

@ -222,6 +222,7 @@ export function App({
persistedDoc: appState.persistedDoc,
onAppLeave,
redirectTo,
originatingApp: incomingState?.originatingApp,
...lensAppServices,
},
saveProps,

View file

@ -52,7 +52,7 @@ export async function getLensServices(
startDependencies: LensPluginStartDependencies,
attributeService: () => Promise<LensAttributeService>
): Promise<LensAppServices> {
const { data, navigation, embeddable, savedObjectsTagging } = startDependencies;
const { data, navigation, embeddable, savedObjectsTagging, usageCollection } = startDependencies;
const storage = new Storage(localStorage);
const stateTransfer = embeddable?.getStateTransfer();
@ -63,6 +63,7 @@ export async function getLensServices(
storage,
navigation,
stateTransfer,
usageCollection,
savedObjectsTagging,
attributeService: await attributeService(),
http: coreStart.http,

View file

@ -9,6 +9,7 @@ import React, { useEffect, useState } from 'react';
import { ChromeStart, NotificationsStart } from 'kibana/public';
import { i18n } from '@kbn/i18n';
import { partition, uniq } from 'lodash';
import { METRIC_TYPE } from '@kbn/analytics';
import { SaveModal } from './save_modal';
import { LensAppProps, LensAppServices } from './types';
import type { SaveProps } from './app';
@ -112,6 +113,7 @@ export function SaveModalContainer({
attributeService,
redirectTo,
redirectToOrigin,
originatingApp,
getIsByValueMode: () => false,
onAppLeave: () => {},
},
@ -178,6 +180,7 @@ export const runSaveLensVisualization = async (
lastKnownDoc?: Document;
getIsByValueMode: () => boolean;
persistedDoc?: Document;
originatingApp?: string;
} & ExtraProps &
LensAppServices,
saveProps: SaveProps,
@ -190,6 +193,7 @@ export const runSaveLensVisualization = async (
const {
chrome,
initialInput,
originatingApp,
lastKnownDoc,
persistedDoc,
savedObjectsClient,
@ -197,6 +201,7 @@ export const runSaveLensVisualization = async (
notifications,
stateTransfer,
attributeService,
usageCollection,
savedObjectsTagging,
getIsByValueMode,
redirectToOrigin,
@ -209,6 +214,9 @@ export const runSaveLensVisualization = async (
persistedDoc && savedObjectsTagging
? savedObjectsTagging.ui.getTagIdsFromReferences(persistedDoc.references)
: [];
if (usageCollection) {
usageCollection.reportUiCounter(originatingApp || 'visualize', METRIC_TYPE.CLICK, 'lens:save');
}
let references = lastKnownDoc.references;
if (savedObjectsTagging) {

View file

@ -18,6 +18,7 @@ import {
SavedObjectsStart,
} from '../../../../../src/core/public';
import { DataPublicPluginStart } from '../../../../../src/plugins/data/public';
import { UsageCollectionStart } from '../../../../../src/plugins/usage_collection/public';
import { DashboardStart } from '../../../../../src/plugins/dashboard/public';
import { LensEmbeddableInput } from '../editor_frame_service/embeddable/embeddable';
import { NavigationPublicPluginStart } from '../../../../../src/plugins/navigation/public';
@ -97,6 +98,7 @@ export interface LensAppServices {
uiSettings: IUiSettingsClient;
application: ApplicationStart;
notifications: NotificationsStart;
usageCollection?: UsageCollectionStart;
stateTransfer: EmbeddableStateTransfer;
navigation: NavigationPublicPluginStart;
attributeService: LensAttributeService;

View file

@ -6,7 +6,7 @@
*/
import { AppMountParameters, CoreSetup, CoreStart } from 'kibana/public';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/public';
import { UsageCollectionSetup, UsageCollectionStart } from 'src/plugins/usage_collection/public';
import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../../src/plugins/data/public';
import { EmbeddableSetup, EmbeddableStart } from '../../../../src/plugins/embeddable/public';
import { DashboardStart } from '../../../../src/plugins/dashboard/public';
@ -81,6 +81,7 @@ export interface LensPluginStartDependencies {
savedObjectsTagging?: SavedObjectTaggingPluginStart;
presentationUtil: PresentationUtilPluginStart;
indexPatternFieldEditor: IndexPatternFieldEditorStart;
usageCollection?: UsageCollectionStart;
}
export interface LensPublicStart {

View file

@ -42,6 +42,7 @@ export const getLensAliasConfig = (): VisTypeAlias => ({
icon: 'lensApp',
stage: 'production',
savedObjectType: type,
type: 'lens',
typeTitle: i18n.translate('xpack.lens.visTypeAlias.type', { defaultMessage: 'Lens' }),
};
},