From a6497cf91ec0973a8b9ff1244eb00a296eab4787 Mon Sep 17 00:00:00 2001 From: Ihor Yeromin Date: Tue, 25 Nov 2025 17:27:45 +0100 Subject: [PATCH] Expressions: Fix duplicate SQL expression tracking events (#114239) * Expressions: Fix duplicate SQL expression tracking events * fix(tracking): event firing on type select dropdown * chore(queries): wrap handler with useCallback --- .../PanelDataPane/PanelDataQueriesTab.tsx | 19 +++++++++++++++++-- .../expressions/ExpressionQueryEditor.tsx | 17 ----------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx index 490084b24ff..cea1dfc6cb0 100644 --- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx +++ b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx @@ -1,7 +1,9 @@ +import { useCallback } from 'react'; + import { CoreApp, DataSourceApi, DataSourceInstanceSettings, getDataSourceRef } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { t, Trans } from '@grafana/i18n'; -import { config, getDataSourceSrv } from '@grafana/runtime'; +import { config, getDataSourceSrv, reportInteraction } from '@grafana/runtime'; import { SceneObjectBase, SceneComponentProps, @@ -337,11 +339,24 @@ export function PanelDataQueriesTabRendered({ model }: SceneComponentProps { + reportInteraction('dashboards_expression_interaction', { + action: 'add_expression', + expression_type: type, + context: 'panel_query_section', + }); + model.onAddExpressionOfType(type); + }, + [model] + ); + if (!datasource || !dsSettings || !data) { return null; } const showAddButton = !isSharedDashboardQuery(dsSettings.name); + const onSelectQueryFromLibrary = async (query: DataQuery) => { // ensure all queries explicitly define a datasource const enrichedQueries = queries.map((q) => @@ -421,7 +436,7 @@ export function PanelDataQueriesTabRendered({ model }: SceneComponentProps )} {config.expressionsEnabled && model.isExpressionsSupported(dsSettings) && ( - + diff --git a/public/app/features/expressions/ExpressionQueryEditor.tsx b/public/app/features/expressions/ExpressionQueryEditor.tsx index e08cdd5d94c..4e3d89cd005 100644 --- a/public/app/features/expressions/ExpressionQueryEditor.tsx +++ b/public/app/features/expressions/ExpressionQueryEditor.tsx @@ -3,7 +3,6 @@ import { useCallback, useEffect, useRef } from 'react'; import { DataSourceApi, FeatureState, GrafanaTheme2, QueryEditorProps } from '@grafana/data'; import { t, Trans } from '@grafana/i18n'; -import { reportInteraction } from '@grafana/runtime'; import { Button, FeatureBadge, IconButton, InlineField, PopoverContent, useStyles2 } from '@grafana/ui'; import { ClassicConditions } from './components/ClassicConditions'; @@ -97,22 +96,6 @@ export function ExpressionQueryEditor(props: ExpressionQueryEditorProps) { const styles = useStyles2(getStyles); - const initialExpressionRef = useRef(query.expression); - const hasTrackedAddExpression = useRef(false); - - useEffect(() => { - // Only track if 1) query has a type, and 2) we haven't tracked yet for this component instance, and - // 3) initial expression was empty (indicating a new expression, not editing existing) - if (query.type && !hasTrackedAddExpression.current && !initialExpressionRef.current) { - reportInteraction('dashboards_expression_interaction', { - action: 'add_expression', - expression_type: query.type, - context: 'panel_query_section', - }); - hasTrackedAddExpression.current = true; - } - }, [query.type, query.refId]); - useEffect(() => { setCachedExpression(query.type, query.expression); }, [query.expression, query.type, setCachedExpression]);