diff --git a/.betterer.results b/.betterer.results index fd96ef7a3b8..26e915da394 100644 --- a/.betterer.results +++ b/.betterer.results @@ -2900,10 +2900,6 @@ exports[`better eslint`] = { [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"], [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "2"] ], - "public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] - ], "public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"], diff --git a/public/app/features/dashboard/components/PanelEditor/PanelEditorTabs.tsx b/public/app/features/dashboard/components/PanelEditor/PanelEditorTabs.tsx index 410f8522405..e60c097ccd4 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelEditorTabs.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelEditorTabs.tsx @@ -1,9 +1,9 @@ import { css } from '@emotion/css'; -import React, { useEffect } from 'react'; +import React, { useEffect, useCallback } from 'react'; import { Subscription } from 'rxjs'; import { GrafanaTheme2 } from '@grafana/data'; -import { config } from '@grafana/runtime'; +import { config, reportInteraction } from '@grafana/runtime'; import { Tab, TabContent, TabsBar, toIconName, useForceUpdate, useStyles2 } from '@grafana/ui'; import AlertTabIndex from 'app/features/alerting/AlertTabIndex'; import { PanelAlertTab } from 'app/features/alerting/unified/PanelAlertTab'; @@ -26,6 +26,17 @@ export const PanelEditorTabs = React.memo(({ panel, dashboard, tabs, onChangeTab const forceUpdate = useForceUpdate(); const styles = useStyles2(getStyles); + const instrumentedOnChangeTab = useCallback( + (tab) => { + if (!tab.active) { + reportInteraction('panel_editor_tabs_changed', { tab_id: tab.id }); + } + + onChangeTab(tab); + }, + [onChangeTab] + ); + useEffect(() => { const eventSubs = new Subscription(); eventSubs.add(panel.events.subscribe(PanelQueriesChangedEvent, forceUpdate)); @@ -44,14 +55,14 @@ export const PanelEditorTabs = React.memo(({ panel, dashboard, tabs, onChangeTab {tabs.map((tab) => { if (tab.id === PanelEditorTabId.Alert) { - return renderAlertTab(tab, panel, dashboard, onChangeTab); + return renderAlertTab(tab, panel, dashboard, instrumentedOnChangeTab); } return ( onChangeTab(tab)} + onChangeTab={() => instrumentedOnChangeTab(tab)} icon={toIconName(tab.icon)} counter={getCounter(panel, tab)} /> diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx index b56f09d8a6d..fce34b37f12 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx @@ -2,6 +2,7 @@ import React, { useCallback } from 'react'; import { useToggle } from 'react-use'; import { DataFrame, DataTransformerConfig, TransformerRegistryItem, FrameMatcherID } from '@grafana/data'; +import { reportInteraction } from '@grafana/runtime'; import { HorizontalGroup } from '@grafana/ui'; import { OperationRowHelp } from 'app/core/components/QueryOperationRow/OperationRowHelp'; import { QueryOperationAction } from 'app/core/components/QueryOperationRow/QueryOperationAction'; @@ -19,7 +20,7 @@ interface TransformationOperationRowProps { id: string; index: number; data: DataFrame[]; - uiConfig: TransformerRegistryItem; + uiConfig: TransformerRegistryItem; configs: TransformationsEditorTransformation[]; onRemove: (index: number) => void; onChange: (index: number, config: DataTransformerConfig) => void; @@ -65,6 +66,21 @@ export const TransformationOperationRow = ({ onChange(index, current); }, [onChange, index, configs]); + // Instrument toggle callback + const instrumentToggleCallback = useCallback( + (callback: (e: React.MouseEvent) => void, toggleId: string, active: boolean | undefined) => + (e: React.MouseEvent) => { + reportInteraction('panel_editor_tabs_transformations_toggle', { + action: active ? 'off' : 'on', + toggleId, + transformationId: configs[index].transformation.id, + }); + + callback(e); + }, + [configs, index] + ); + const renderActions = ({ isOpen }: QueryOperationRowRenderProps) => { return ( @@ -72,15 +88,28 @@ export const TransformationOperationRow = ({ - {showFilter && } - + {showFilter && ( + + )} + onDisableToggle(index)} + onClick={instrumentToggleCallback(() => onDisableToggle(index), 'disabled', disabled)} active={disabled} /> onRemove(index)} /> @@ -113,7 +142,7 @@ export const TransformationOperationRow = ({ ); }; -function prepMarkdown(uiConfig: TransformerRegistryItem) { +function prepMarkdown(uiConfig: TransformerRegistryItem) { let helpMarkdown = uiConfig.help ?? uiConfig.description; return ` diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx index 166bce18c73..e4be969e233 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx @@ -14,6 +14,7 @@ import { TransformerRegistryItem, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { reportInteraction } from '@grafana/runtime'; import { Alert, Button, @@ -144,6 +145,10 @@ class UnThemedTransformationsEditor extends React.PureComponent) => { + reportInteraction('panel_editor_tabs_transformations_management', { + action: 'add', + transformationId: selectable.value, + }); const { transformations } = this.state; const nextId = this.getTransformationNextId(selectable.value!); @@ -163,6 +168,10 @@ class UnThemedTransformationsEditor extends React.PureComponent { const { transformations } = this.state; const next = Array.from(transformations); + reportInteraction('panel_editor_tabs_transformations_management', { + action: 'change', + transformationId: next[idx].transformation.id, + }); next[idx].transformation = config; this.onChange(next); }; @@ -170,6 +179,10 @@ class UnThemedTransformationsEditor extends React.PureComponent { const { transformations } = this.state; const next = Array.from(transformations); + reportInteraction('panel_editor_tabs_transformations_management', { + action: 'remove', + transformationId: next[idx].transformation.id, + }); next.splice(idx, 1); this.onChange(next); };