From c5b399dc9996c61b2840b976a941eca78a4020b2 Mon Sep 17 00:00:00 2001 From: Polina Boneva <13227501+polibb@users.noreply.github.com> Date: Thu, 3 Aug 2023 16:41:26 +0300 Subject: [PATCH] Dashboard: Add analytics events for sharing a dashboard (#72613) * activeTab for public dashboard matches others * add analytics action for going through categories of sharing modal * add analytics for going through actions of any cateogry in sharing modal * change 'tab' to 'category'; add key 'sharing_category' to actions for easier distinction * sharedCategory sounds like a category is shared; changed naming to shareDashboardType * remove hard-coded analytic event name * wrap the reportInteraction call for all actions when sharing dashboard --------- Co-authored-by: Alexandra Vargas --- .../components/ShareModal/ShareExport.tsx | 9 ++-- .../components/ShareModal/ShareLink.tsx | 11 +++-- .../components/ShareModal/ShareModal.tsx | 28 ++++++----- .../ConfigPublicDashboard.tsx | 18 +++++-- .../ConfigPublicDashboard/Configuration.tsx | 18 ++++--- .../EmailSharingConfiguration.tsx | 20 ++++---- .../CreatePublicDashboard.tsx | 5 +- .../SharePublicDashboard.test.tsx | 49 ++++++++++++++----- .../SharePublicDashboard.tsx | 7 +-- .../components/ShareModal/ShareSnapshot.tsx | 9 ++-- .../components/ShareModal/analytics.ts | 19 +++++++ .../dashboard/components/ShareModal/utils.ts | 13 +++++ 12 files changed, 141 insertions(+), 65 deletions(-) create mode 100644 public/app/features/dashboard/components/ShareModal/analytics.ts diff --git a/public/app/features/dashboard/components/ShareModal/ShareExport.tsx b/public/app/features/dashboard/components/ShareModal/ShareExport.tsx index e729c25300d..a2fbf2013b4 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareExport.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareExport.tsx @@ -1,7 +1,7 @@ import { saveAs } from 'file-saver'; import React, { PureComponent } from 'react'; -import { config, reportInteraction } from '@grafana/runtime'; +import { config } from '@grafana/runtime'; import { Button, Field, Modal, Switch } from '@grafana/ui'; import { appEvents } from 'app/core/core'; import { t, Trans } from 'app/core/internationalization'; @@ -10,7 +10,9 @@ import { DashboardExporter } from 'app/features/dashboard/components/DashExportM import { ShowModalReactEvent } from 'app/types/events'; import { ViewJsonModal } from './ViewJsonModal'; +import { trackDashboardSharingActionPerType } from './analytics'; import { ShareModalTabProps } from './types'; +import { shareDashboardType } from './utils'; interface Props extends ShareModalTabProps {} @@ -32,10 +34,6 @@ export class ShareExport extends PureComponent { this.exporter = new DashboardExporter(); } - componentDidMount() { - reportInteraction('grafana_dashboards_export_share_viewed'); - } - onShareExternallyChange = () => { this.setState({ shareExternally: !this.state.shareExternally, @@ -115,6 +113,7 @@ export class ShareExport extends PureComponent { }); const time = new Date().getTime(); saveAs(blob, `${dash.title}-${time}.json`); + trackDashboardSharingActionPerType('save_export', shareDashboardType.export); }; openJsonModal = (clone: object) => { diff --git a/public/app/features/dashboard/components/ShareModal/ShareLink.tsx b/public/app/features/dashboard/components/ShareModal/ShareLink.tsx index db86d459533..aae761139b5 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareLink.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareLink.tsx @@ -1,14 +1,14 @@ import React, { PureComponent } from 'react'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors'; -import { reportInteraction } from '@grafana/runtime/src'; import { Alert, ClipboardButton, Field, FieldSet, Icon, Input, Switch } from '@grafana/ui'; import config from 'app/core/config'; import { t, Trans } from 'app/core/internationalization'; import { ThemePicker } from './ThemePicker'; +import { trackDashboardSharingActionPerType } from './analytics'; import { ShareModalTabProps } from './types'; -import { buildImageUrl, buildShareUrl } from './utils'; +import { buildImageUrl, buildShareUrl, shareDashboardType } from './utils'; export interface Props extends ShareModalTabProps {} @@ -33,7 +33,6 @@ export class ShareLink extends PureComponent { } componentDidMount() { - reportInteraction('grafana_dashboards_link_share_viewed'); this.buildUrl(); } @@ -74,6 +73,10 @@ export class ShareLink extends PureComponent { return this.state.shareUrl; }; + onCopy() { + trackDashboardSharingActionPerType('copy_link', shareDashboardType.link); + } + render() { const { panel, dashboard } = this.props; const isRelativeTime = dashboard ? dashboard.time.to === 'now' : false; @@ -118,7 +121,7 @@ export class ShareLink extends PureComponent { value={shareUrl} readOnly addonAfter={ - + Copy } diff --git a/public/app/features/dashboard/components/ShareModal/ShareModal.tsx b/public/app/features/dashboard/components/ShareModal/ShareModal.tsx index 6c583dbc0bb..1f05fccbb9e 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareModal.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareModal.tsx @@ -2,7 +2,6 @@ import { css } from '@emotion/css'; import React from 'react'; import { GrafanaTheme2 } from '@grafana/data'; -import { reportInteraction } from '@grafana/runtime/src'; import { Modal, ModalTabsHeader, TabContent, Themeable2, withTheme2 } from '@grafana/ui'; import { config } from 'app/core/config'; import { contextSrv } from 'app/core/core'; @@ -16,7 +15,9 @@ import { ShareExport } from './ShareExport'; import { ShareLibraryPanel } from './ShareLibraryPanel'; import { ShareLink } from './ShareLink'; import { ShareSnapshot } from './ShareSnapshot'; +import { trackDashboardSharingTypeOpen } from './analytics'; import { ShareModalTabModel } from './types'; +import { shareDashboardType } from './utils'; const customDashboardTabs: ShareModalTabModel[] = []; const customPanelTabs: ShareModalTabModel[] = []; @@ -31,30 +32,38 @@ export function addPanelShareTab(tab: ShareModalTabModel) { function getTabs(panel?: PanelModel, activeTab?: string) { const linkLabel = t('share-modal.tab-title.link', 'Link'); - const tabs: ShareModalTabModel[] = [{ label: linkLabel, value: 'link', component: ShareLink }]; + const tabs: ShareModalTabModel[] = [{ label: linkLabel, value: shareDashboardType.link, component: ShareLink }]; if (contextSrv.isSignedIn && config.snapshotEnabled) { const snapshotLabel = t('share-modal.tab-title.snapshot', 'Snapshot'); - tabs.push({ label: snapshotLabel, value: 'snapshot', component: ShareSnapshot }); + tabs.push({ label: snapshotLabel, value: shareDashboardType.snapshot, component: ShareSnapshot }); } if (panel) { const embedLabel = t('share-modal.tab-title.embed', 'Embed'); - tabs.push({ label: embedLabel, value: 'embed', component: ShareEmbed }); + tabs.push({ label: embedLabel, value: shareDashboardType.embed, component: ShareEmbed }); if (!isPanelModelLibraryPanel(panel)) { const libraryPanelLabel = t('share-modal.tab-title.library-panel', 'Library panel'); - tabs.push({ label: libraryPanelLabel, value: 'library_panel', component: ShareLibraryPanel }); + tabs.push({ label: libraryPanelLabel, value: shareDashboardType.libraryPanel, component: ShareLibraryPanel }); } tabs.push(...customPanelTabs); } else { const exportLabel = t('share-modal.tab-title.export', 'Export'); - tabs.push({ label: exportLabel, value: 'export', component: ShareExport }); + tabs.push({ + label: exportLabel, + value: shareDashboardType.export, + component: ShareExport, + }); tabs.push(...customDashboardTabs); } if (Boolean(config.featureToggles['publicDashboards'])) { - tabs.push({ label: 'Public dashboard', value: 'public-dashboard', component: SharePublicDashboard }); + tabs.push({ + label: 'Public dashboard', + value: shareDashboardType.publicDashboard, + component: SharePublicDashboard, + }); } const at = tabs.find((t) => t.value === activeTab); @@ -93,12 +102,9 @@ class UnthemedShareModal extends React.Component { this.state = getInitialState(props); } - componentDidMount() { - reportInteraction('grafana_dashboards_share_modal_viewed'); - } - onSelectTab: React.ComponentProps['onChangeTab'] = (t) => { this.setState((prevState) => ({ ...prevState, activeTab: t.value })); + trackDashboardSharingTypeOpen(t.value); }; getActiveTab() { diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/ConfigPublicDashboard.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/ConfigPublicDashboard.tsx index 8215c8c852e..53d21359435 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/ConfigPublicDashboard.tsx +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/ConfigPublicDashboard.tsx @@ -4,7 +4,7 @@ import { useForm } from 'react-hook-form'; import { GrafanaTheme2 } from '@grafana/data/src'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src'; -import { config, featureEnabled, reportInteraction } from '@grafana/runtime/src'; +import { config, featureEnabled } from '@grafana/runtime/src'; import { ClipboardButton, Field, @@ -25,6 +25,8 @@ import { isOrgAdmin } from '../../../../../plugins/admin/permissions'; import { useGetPublicDashboardQuery, useUpdatePublicDashboardMutation } from '../../../../api/publicDashboardApi'; import { useIsDesktop } from '../../../../utils/screen'; import { ShareModal } from '../../ShareModal'; +import { trackDashboardSharingActionPerType } from '../../analytics'; +import { shareDashboardType } from '../../utils'; import { NoUpsertPermissionsAlert } from '../ModalAlerts/NoUpsertPermissionsAlert'; import { SaveDashboardChangesAlert } from '../ModalAlerts/SaveDashboardChangesAlert'; import { UnsupportedDataSourcesAlert } from '../ModalAlerts/UnsupportedDataSourcesAlert'; @@ -100,10 +102,14 @@ const ConfigPublicDashboard = () => { showModal(ShareModal, { dashboard, onDismiss: hideModal, - activeTab: 'public-dashboard', + activeTab: shareDashboardType.publicDashboard, }); }; + function onCopyURL() { + trackDashboardSharingActionPerType('copy_public_url', shareDashboardType.publicDashboard); + } + return (
{hasWritePermissions && dashboard.hasUnsavedChanges() && } @@ -127,6 +133,7 @@ const ConfigPublicDashboard = () => { variant="primary" disabled={!publicDashboard?.isEnabled} getText={() => generatePublicDashboardUrl(publicDashboard!.accessToken!)} + onClipboardCopy={onCopyURL} > Copy @@ -140,9 +147,10 @@ const ConfigPublicDashboard = () => { {...register('isPaused')} disabled={disableInputs} onChange={(e) => { - reportInteraction('grafana_dashboards_public_enable_clicked', { - action: e.currentTarget.checked ? 'disable' : 'enable', - }); + trackDashboardSharingActionPerType( + e.currentTarget.checked ? 'disable_sharing' : 'enable_sharing', + shareDashboardType.publicDashboard + ); onChange('isPaused', e.currentTarget.checked); }} data-testid={selectors.PauseSwitch} diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/Configuration.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/Configuration.tsx index 75a6bf1b76f..230f90d55a7 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/Configuration.tsx +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/Configuration.tsx @@ -3,10 +3,12 @@ import { UseFormRegister } from 'react-hook-form'; import { TimeRange } from '@grafana/data/src'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src'; -import { reportInteraction } from '@grafana/runtime/src'; import { FieldSet, Label, Switch, TimeRangeInput, VerticalGroup } from '@grafana/ui/src'; import { Layout } from '@grafana/ui/src/components/Layout/Layout'; +import { trackDashboardSharingActionPerType } from '../../analytics'; +import { shareDashboardType } from '../../utils'; + import { ConfigPublicDashboardForm } from './ConfigPublicDashboard'; const selectors = e2eSelectors.pages.ShareDashboardModal.PublicDashboard; @@ -37,9 +39,10 @@ export const Configuration = ({ {...register('isTimeSelectionEnabled')} data-testid={selectors.EnableTimeRangeSwitch} onChange={(e) => { - reportInteraction('grafana_dashboards_public_time_selection_clicked', { - action: e.currentTarget.checked ? 'enable' : 'disable', - }); + trackDashboardSharingActionPerType( + e.currentTarget.checked ? 'enable_time' : 'disable_time', + shareDashboardType.publicDashboard + ); onChange('isTimeSelectionEnabled', e.currentTarget.checked); }} /> @@ -49,9 +52,10 @@ export const Configuration = ({ { - reportInteraction('grafana_dashboards_public_annotations_clicked', { - action: e.currentTarget.checked ? 'enable' : 'disable', - }); + trackDashboardSharingActionPerType( + e.currentTarget.checked ? 'enable_annotations' : 'disable_annotations', + shareDashboardType.publicDashboard + ); onChange('isAnnotationsEnabled', e.currentTarget.checked); }} data-testid={selectors.EnableAnnotationsSwitch} diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/EmailSharingConfiguration.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/EmailSharingConfiguration.tsx index 3080727f9cb..5b916eb980a 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/EmailSharingConfiguration.tsx +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ConfigPublicDashboard/EmailSharingConfiguration.tsx @@ -5,7 +5,6 @@ import { useWindowSize } from 'react-use'; import { GrafanaTheme2, SelectableValue } from '@grafana/data/src'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src'; -import { reportInteraction } from '@grafana/runtime/src'; import { Button, ButtonGroup, @@ -25,6 +24,8 @@ import { } from 'app/features/dashboard/api/publicDashboardApi'; import { useSelector } from 'app/types'; +import { trackDashboardSharingActionPerType } from '../../analytics'; +import { shareDashboardType } from '../../utils'; import { PublicDashboard, PublicDashboardShareType, validEmailRegex } from '../SharePublicDashboardUtils'; interface EmailSharingConfigurationForm { @@ -55,12 +56,12 @@ const EmailList = ({ const isLoading = isDeleteLoading || isReshareLoading; const onDeleteEmail = (recipientUid: string) => { - reportInteraction('grafana_dashboards_public_delete_sharing_email_clicked'); + trackDashboardSharingActionPerType('delete_email', shareDashboardType.publicDashboard); deleteEmail({ recipientUid, dashboardUid: dashboardUid, uid: publicDashboardUid }); }; const onReshare = (recipientUid: string) => { - reportInteraction('grafana_dashboards_public_reshare_email_clicked'); + trackDashboardSharingActionPerType('reshare_email', shareDashboardType.publicDashboard); reshareAccess({ recipientUid, uid: publicDashboardUid }); }; @@ -133,7 +134,7 @@ export const EmailSharingConfiguration = () => { mode: 'onSubmit', }); - const onShareTypeChange = (shareType: PublicDashboardShareType) => { + const onUpdateShareType = (shareType: PublicDashboardShareType) => { const req = { dashboard, payload: { @@ -147,7 +148,7 @@ export const EmailSharingConfiguration = () => { const onSubmit = async (data: EmailSharingConfigurationForm) => { //TODO: add if it's domain or not when developed. - reportInteraction('grafana_dashboards_public_add_share_email_clicked'); + trackDashboardSharingActionPerType('invite_email', shareDashboardType.publicDashboard); await addEmail({ recipient: data.email, uid: publicDashboard!.uid, dashboardUid: dashboard.uid }).unwrap(); reset({ email: '', shareType: PublicDashboardShareType.EMAIL }); }; @@ -166,11 +167,12 @@ export const EmailSharingConfiguration = () => { size={width < 480 ? 'sm' : 'md'} options={options} onChange={(shareType: PublicDashboardShareType) => { - reportInteraction('grafana_dashboards_public_share_type_clicked', { - type: shareType, - }); + trackDashboardSharingActionPerType( + `share_type_${shareType === PublicDashboardShareType.EMAIL ? 'email' : 'public'}`, + shareDashboardType.publicDashboard + ); setValue('shareType', shareType); - onShareTypeChange(shareType); + onUpdateShareType(shareType); }} /> ); diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/CreatePublicDashboard/CreatePublicDashboard.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/CreatePublicDashboard/CreatePublicDashboard.tsx index f80103031e4..a730b8d8f94 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/CreatePublicDashboard/CreatePublicDashboard.tsx +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/CreatePublicDashboard/CreatePublicDashboard.tsx @@ -4,13 +4,14 @@ import { FormState, UseFormRegister } from 'react-hook-form'; import { GrafanaTheme2 } from '@grafana/data/src'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src'; -import { reportInteraction } from '@grafana/runtime/src'; import { Button, Form, Spinner, useStyles2 } from '@grafana/ui/src'; import { contextSrv } from '../../../../../../core/services/context_srv'; import { AccessControlAction, useSelector } from '../../../../../../types'; import { isOrgAdmin } from '../../../../../plugins/admin/permissions'; import { useCreatePublicDashboardMutation } from '../../../../api/publicDashboardApi'; +import { trackDashboardSharingActionPerType } from '../../analytics'; +import { shareDashboardType } from '../../utils'; import { NoUpsertPermissionsAlert } from '../ModalAlerts/NoUpsertPermissionsAlert'; import { UnsupportedDataSourcesAlert } from '../ModalAlerts/UnsupportedDataSourcesAlert'; import { UnsupportedTemplateVariablesAlert } from '../ModalAlerts/UnsupportedTemplateVariablesAlert'; @@ -39,7 +40,7 @@ const CreatePublicDashboard = ({ isError }: { isError: boolean }) => { const disableInputs = !hasWritePermissions || isSaveLoading || isError; const onCreate = async () => { - reportInteraction('grafana_dashboards_public_create_clicked'); + trackDashboardSharingActionPerType('generate_public_url', shareDashboardType.publicDashboard); createPublicDashboard({ dashboard, payload: { isEnabled: true } }); }; diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.test.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.test.tsx index c885c83e248..55d7aec8c27 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.test.tsx +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.test.tsx @@ -6,7 +6,7 @@ import { setupServer } from 'msw/node'; import 'whatwg-fetch'; import { BootData, DataQuery } from '@grafana/data/src'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src'; -import { reportInteraction, setEchoSrv } from '@grafana/runtime'; +import { setEchoSrv } from '@grafana/runtime'; import { Panel } from '@grafana/schema'; import config from 'app/core/config'; import { backendSrv } from 'app/core/services/backend_srv'; @@ -14,6 +14,9 @@ import { contextSrv } from 'app/core/services/context_srv'; import { Echo } from 'app/core/services/echo/Echo'; import { createDashboardModelFixture } from 'app/features/dashboard/state/__fixtures__/dashboardFixtures'; +import { trackDashboardSharingTypeOpen, trackDashboardSharingActionPerType } from '../analytics'; +import { shareDashboardType } from '../utils'; + import * as sharePublicDashboardUtils from './SharePublicDashboardUtils'; import { getExistentPublicDashboardResponse, @@ -27,7 +30,12 @@ const server = setupServer(); jest.mock('@grafana/runtime', () => ({ ...jest.requireActual('@grafana/runtime'), getBackendSrv: () => backendSrv, - reportInteraction: jest.fn(), +})); + +jest.mock('../analytics', () => ({ + ...jest.requireActual('../analytics'), + trackDashboardSharingTypeOpen: jest.fn(), + trackDashboardSharingActionPerType: jest.fn(), })); const selectors = e2eSelectors.pages.ShareDashboardModal.PublicDashboard; @@ -334,6 +342,15 @@ describe('SharePublic - Report interactions', () => { ); }); + it('reports interaction when public dashboard tab is clicked', async () => { + await renderSharePublicDashboard(); + + await waitFor(() => { + expect(trackDashboardSharingTypeOpen).toHaveBeenCalledTimes(1); + expect(trackDashboardSharingTypeOpen).lastCalledWith(shareDashboardType.publicDashboard); + }); + }); + it('reports interaction when time range is clicked', async () => { await renderSharePublicDashboard(); await userEvent.click(screen.getByText('Settings')); @@ -344,11 +361,15 @@ describe('SharePublic - Report interactions', () => { await userEvent.click(screen.getByTestId(selectors.EnableTimeRangeSwitch)); await waitFor(() => { - expect(reportInteraction).toHaveBeenCalledWith('grafana_dashboards_public_time_selection_clicked', { - action: pubdashResponse.timeSelectionEnabled ? 'disable' : 'enable', - }); + expect(trackDashboardSharingActionPerType).toHaveBeenCalledTimes(1); + // if time range was enabled, then the item is now disable_time + expect(trackDashboardSharingActionPerType).toHaveBeenLastCalledWith( + pubdashResponse.timeSelectionEnabled ? 'disable_time' : 'enable_time', + shareDashboardType.publicDashboard + ); }); }); + it('reports interaction when show annotations is clicked', async () => { await renderSharePublicDashboard(); await userEvent.click(screen.getByText('Settings')); @@ -359,9 +380,12 @@ describe('SharePublic - Report interactions', () => { await userEvent.click(screen.getByTestId(selectors.EnableAnnotationsSwitch)); await waitFor(() => { - expect(reportInteraction).toHaveBeenCalledWith('grafana_dashboards_public_annotations_clicked', { - action: pubdashResponse.annotationsEnabled ? 'disable' : 'enable', - }); + expect(trackDashboardSharingActionPerType).toHaveBeenCalledTimes(1); + // if annotations was enabled, then the item is now disable_annotations + expect(trackDashboardSharingActionPerType).toHaveBeenCalledWith( + pubdashResponse.annotationsEnabled ? 'disable_annotations' : 'enable_annotations', + shareDashboardType.publicDashboard + ); }); }); it('reports interaction when pause is clicked', async () => { @@ -372,9 +396,12 @@ describe('SharePublic - Report interactions', () => { await userEvent.click(screen.getByTestId(selectors.PauseSwitch)); await waitFor(() => { - expect(reportInteraction).toHaveBeenCalledWith('grafana_dashboards_public_enable_clicked', { - action: pubdashResponse.isEnabled ? 'disable' : 'enable', - }); + expect(trackDashboardSharingActionPerType).toHaveBeenCalledTimes(1); + // if sharing was enabled, then the item is now disable_sharing + expect(trackDashboardSharingActionPerType).toHaveBeenLastCalledWith( + pubdashResponse.isEnabled ? 'disable_sharing' : 'enable_sharing', + shareDashboardType.publicDashboard + ); }); }); }); diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx index 569ce8f0331..9237ad5c5e9 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx @@ -1,8 +1,7 @@ import { css } from '@emotion/css'; -import React, { useEffect } from 'react'; +import React from 'react'; import { GrafanaTheme2 } from '@grafana/data/src'; -import { reportInteraction } from '@grafana/runtime/src'; import { Spinner, useStyles2 } from '@grafana/ui/src'; import { useGetPublicDashboardQuery } from 'app/features/dashboard/api/publicDashboardApi'; import { publicDashboardPersisted } from 'app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboardUtils'; @@ -30,10 +29,6 @@ const Loader = () => { export const SharePublicDashboard = (props: Props) => { const { data: publicDashboard, isLoading, isError } = useGetPublicDashboardQuery(props.dashboard.uid); - useEffect(() => { - reportInteraction('grafana_dashboards_public_share_viewed'); - }, []); - return ( <> {isLoading ? ( diff --git a/public/app/features/dashboard/components/ShareModal/ShareSnapshot.tsx b/public/app/features/dashboard/components/ShareModal/ShareSnapshot.tsx index ddb40551833..10bbf50b0e4 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareSnapshot.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareSnapshot.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import { isEmptyObject, SelectableValue } from '@grafana/data'; -import { getBackendSrv, reportInteraction } from '@grafana/runtime'; +import { getBackendSrv } from '@grafana/runtime'; import { Button, ClipboardButton, Field, Input, LinkButton, Modal, Select, Spinner } from '@grafana/ui'; import { t, Trans } from 'app/core/internationalization'; import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; @@ -9,7 +9,9 @@ import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { VariableRefresh } from '../../../variables/types'; +import { trackDashboardSharingActionPerType } from './analytics'; import { ShareModalTabProps } from './types'; +import { shareDashboardType } from './utils'; const snapshotApiUrl = '/api/snapshots'; @@ -68,7 +70,6 @@ export class ShareSnapshot extends PureComponent { } componentDidMount() { - reportInteraction('grafana_dashboards_snapshot_share_viewed'); this.getSnaphotShareOptions(); } @@ -114,9 +115,7 @@ export class ShareSnapshot extends PureComponent { step: 2, }); } finally { - reportInteraction('grafana_dashboards_snapshot_created', { - location: external ? 'raintank' : 'local', - }); + trackDashboardSharingActionPerType(external ? 'publish_snapshot' : 'local_snapshot', shareDashboardType.snapshot); this.setState({ isLoading: false }); } }; diff --git a/public/app/features/dashboard/components/ShareModal/analytics.ts b/public/app/features/dashboard/components/ShareModal/analytics.ts new file mode 100644 index 00000000000..7e27925215e --- /dev/null +++ b/public/app/features/dashboard/components/ShareModal/analytics.ts @@ -0,0 +1,19 @@ +import { reportInteraction } from '@grafana/runtime'; + +export const shareAnalyticsEventNames: { + [key: string]: string; +} = { + sharingCategoryClicked: 'dashboards_sharing_category_clicked', + sharingActionClicked: 'dashboards_sharing_actions_clicked', +}; + +export function trackDashboardSharingTypeOpen(sharingType: string) { + reportInteraction(shareAnalyticsEventNames.sharingCategoryClicked, { item: sharingType }); +} + +export function trackDashboardSharingActionPerType(action: string, sharingType: string) { + reportInteraction(shareAnalyticsEventNames.sharingActionClicked, { + item: action, + sharing_category: sharingType, + }); +} diff --git a/public/app/features/dashboard/components/ShareModal/utils.ts b/public/app/features/dashboard/components/ShareModal/utils.ts index 3b959103193..9c651470840 100644 --- a/public/app/features/dashboard/components/ShareModal/utils.ts +++ b/public/app/features/dashboard/components/ShareModal/utils.ts @@ -137,3 +137,16 @@ export function getLocalTimeZone() { return '&tz=' + encodeURIComponent(options.timeZone); } + +export const shareDashboardType: { + [key: string]: string; +} = { + link: 'link', + snapshot: 'snapshot', + export: 'export', + embed: 'embed', + libraryPanel: 'library_panel', + pdf: 'pdf', + report: 'report', + publicDashboard: 'public_dashboard', +};