diff --git a/public/app/features/datasources/components/DataSourcesListHeader.tsx b/public/app/features/datasources/components/DataSourcesListHeader.tsx
index 413d9284045..cf0a97883d1 100644
--- a/public/app/features/datasources/components/DataSourcesListHeader.tsx
+++ b/public/app/features/datasources/components/DataSourcesListHeader.tsx
@@ -1,10 +1,12 @@
-import { useCallback } from 'react';
+import { debounce } from 'lodash';
+import { useCallback, useMemo } from 'react';
import { SelectableValue } from '@grafana/data';
import PageActionBar from 'app/core/components/PageActionBar/PageActionBar';
import { StoreState, useSelector, useDispatch } from 'app/types';
import { getDataSourcesSearchQuery, getDataSourcesSort, setDataSourcesSearchQuery, setIsSortAscending } from '../state';
+import { trackDsSearched } from '../tracking';
const ascendingSortValue = 'alpha-asc';
const descendingSortValue = 'alpha-desc';
@@ -19,7 +21,23 @@ const sortOptions = [
export function DataSourcesListHeader() {
const dispatch = useDispatch();
- const setSearchQuery = useCallback((q: string) => dispatch(setDataSourcesSearchQuery(q)), [dispatch]);
+ const debouncedTrackSearch = useMemo(
+ () =>
+ debounce((q) => {
+ trackDsSearched({ query: q });
+ }, 300),
+ []
+ );
+
+ const setSearchQuery = useCallback(
+ (q: string) => {
+ dispatch(setDataSourcesSearchQuery(q));
+ if (q) {
+ debouncedTrackSearch(q);
+ }
+ },
+ [dispatch, debouncedTrackSearch]
+ );
const searchQuery = useSelector(({ dataSources }: StoreState) => getDataSourcesSearchQuery(dataSources));
const setSort = useCallback(
diff --git a/public/app/features/datasources/components/picker/DataSourcePicker.tsx b/public/app/features/datasources/components/picker/DataSourcePicker.tsx
index 14dd2676050..332d5ec020a 100644
--- a/public/app/features/datasources/components/picker/DataSourcePicker.tsx
+++ b/public/app/features/datasources/components/picker/DataSourcePicker.tsx
@@ -3,7 +3,8 @@ import { autoUpdate, flip, offset, shift, size, useFloating } from '@floating-ui
import { useDialog } from '@react-aria/dialog';
import { FocusScope } from '@react-aria/focus';
import { useOverlay } from '@react-aria/overlays';
-import { useCallback, useEffect, useRef, useState } from 'react';
+import { debounce } from 'lodash';
+import { useCallback, useEffect, useRef, useState, useMemo } from 'react';
import * as React from 'react';
import { Observable } from 'rxjs';
@@ -26,6 +27,7 @@ import { dataSourceLabel, matchDataSourceWithSearch } from './utils';
const INTERACTION_EVENT_NAME = 'dashboards_dspicker_clicked';
const INTERACTION_ITEM = {
+ SEARCH: 'search',
OPEN_DROPDOWN: 'open_dspicker',
SELECT_DS: 'select_ds',
ADD_FILE: 'add_file',
@@ -78,6 +80,18 @@ export function DataSourcePicker(props: DataSourcePickerProps) {
const [filterTerm, setFilterTerm] = useState('');
const { onKeyDown, keyboardEvents } = useKeyNavigationListener();
const ref = useRef(null);
+ const debouncedTrackSearch = useMemo(
+ () =>
+ debounce((q) => {
+ reportInteraction(INTERACTION_EVENT_NAME, {
+ item: INTERACTION_ITEM.SEARCH,
+ query: q,
+ creator_team: 'grafana_plugins_catalog',
+ schema_version: '1.0.0',
+ });
+ }, 300),
+ []
+ );
// Used to position the popper correctly and to bring back the focus when navigating from footer to input
const [markerElement, setMarkerElement] = useState();
@@ -151,7 +165,6 @@ export function DataSourcePicker(props: DataSourcePickerProps) {
);
function openDropdown() {
- reportInteraction(INTERACTION_EVENT_NAME, { item: INTERACTION_ITEM.OPEN_DROPDOWN });
setOpen(true);
markerElement?.focus();
}
@@ -214,7 +227,17 @@ export function DataSourcePicker(props: DataSourcePickerProps) {
{/* This clickable div is just extending the clickable area on the input element to include the prefix and suffix. */}
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
-