Favorite Datasources: Complete reported interactions (#110817)

This commit is contained in:
Andres Martinez Gotor
2025-09-10 09:29:39 +02:00
committed by GitHub
parent 4648fc902a
commit 4dbd3a00b7
3 changed files with 56 additions and 9 deletions
@@ -28,6 +28,14 @@ jest.mock('@grafana/runtime', () => ({
useFavoriteDatasources: jest.fn(),
}));
// Mock picker components
jest.mock('./picker/DataSourcePicker', () => ({
INTERACTION_EVENT_NAME: 'dashboards_dspicker_clicked',
INTERACTION_ITEM: {
TOGGLE_FAVORITE: 'toggle_favorite',
},
}));
// Set default plugin links hook
setPluginLinksHook(() => ({ links: [], isLoading: false }));
@@ -1,6 +1,6 @@
import { PluginExtensionPoints } from '@grafana/data';
import { Trans, t } from '@grafana/i18n';
import { config, usePluginLinks, useFavoriteDatasources, getDataSourceSrv } from '@grafana/runtime';
import { config, usePluginLinks, useFavoriteDatasources, getDataSourceSrv, reportInteraction } from '@grafana/runtime';
import { Button, Dropdown, LinkButton, Menu, Icon, IconButton } from '@grafana/ui';
import { contextSrv } from 'app/core/core';
@@ -9,6 +9,8 @@ import { useDataSource } from '../state/hooks';
import { trackCreateDashboardClicked, trackDsConfigClicked, trackExploreClicked } from '../tracking';
import { constructDataSourceExploreUrl } from '../utils';
import { INTERACTION_EVENT_NAME, INTERACTION_ITEM } from './picker/DataSourcePicker';
interface Props {
uid: string;
}
@@ -26,11 +28,16 @@ const FavoriteButton = ({ uid }: { uid: string }) => {
key={`favorite-${isFavorite ? 'favorite-mono' : 'star-default'}`}
name={isFavorite ? 'favorite' : 'star'}
iconType={isFavorite ? 'mono' : 'default'}
onClick={() =>
onClick={() => {
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.TOGGLE_FAVORITE,
ds_type: dataSourceInstance.type,
is_favorite: !isFavorite,
});
isFavorite
? favoriteDataSources.removeFavoriteDatasource(dataSourceInstance)
: favoriteDataSources.addFavoriteDatasource(dataSourceInstance)
}
: favoriteDataSources.addFavoriteDatasource(dataSourceInstance);
}}
disabled={favoriteDataSources.isLoading}
tooltip={
isFavorite
@@ -1,10 +1,10 @@
import { css } from '@emotion/css';
import { once } from 'lodash';
import { useMemo, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { DataSourceInstanceSettings, DataSourceRef, GrafanaTheme2 } from '@grafana/data';
import { Trans, t } from '@grafana/i18n';
import { config, reportInteraction } from '@grafana/runtime';
import { config, reportInteraction, useFavoriteDatasources } from '@grafana/runtime';
import { DataQuery } from '@grafana/schema';
import {
Modal,
@@ -19,7 +19,7 @@ import { acceptedFiles, maxFileSize } from 'app/features/dataframe-import/consta
import { GrafanaQuery } from 'app/plugins/datasource/grafana/types';
import { getFileDropToQueryHandler } from 'app/plugins/datasource/grafana/utils';
import { useDatasource } from '../../hooks';
import { useDatasource, useDatasources } from '../../hooks';
import { AddNewDataSourceButton } from './AddNewDataSourceButton';
import { BuiltInDataSourceList } from './BuiltInDataSourceList';
@@ -34,6 +34,7 @@ const INTERACTION_ITEM = {
CONFIG_NEW_DS_EMPTY_STATE: 'config_new_ds_empty_state',
SEARCH: 'search',
DISMISS: 'dismiss',
OPEN_MODAL: 'open_modal',
};
export interface DataSourceModalProps {
@@ -79,6 +80,7 @@ export function DataSourceModal({
const styles = useStyles2(getDataSourceModalStyles);
const [search, setSearch] = useState('');
const analyticsInteractionSrc = reportedInteractionFrom || 'modal';
const favoriteDataSources = useFavoriteDatasources();
const onDismissModal = () => {
onDismiss();
@@ -90,8 +92,39 @@ export function DataSourceModal({
item: INTERACTION_ITEM.SELECT_DS,
ds_type: ds.type,
src: analyticsInteractionSrc,
is_favorite: favoriteDataSources.enabled ? favoriteDataSources.isFavoriteDatasource(ds.uid) : undefined,
});
};
const grafanaDS = useDatasource('-- Grafana --');
// Get all datasources to report total_configured count
const dataSources = useDatasources({
tracing,
dashboard,
mixed,
metrics,
type,
annotations,
variables,
alerting,
pluginId,
logs,
});
// Report interaction when modal is opened
useEffect(() => {
if (dataSources.length > 0) {
reportInteraction(INTERACTION_EVENT_NAME, {
item: INTERACTION_ITEM.OPEN_MODAL,
src: analyticsInteractionSrc,
creator_team: 'grafana_plugins_catalog',
schema_version: '1.0.0',
total_configured: dataSources.length,
});
}
}, [analyticsInteractionSrc, dataSources.length]);
// Memoizing to keep once() cached so it avoids reporting multiple times
const reportSearchUsageOnce = useMemo(
() =>
@@ -101,8 +134,6 @@ export function DataSourceModal({
[analyticsInteractionSrc]
);
const grafanaDS = useDatasource('-- Grafana --');
const onFileDrop = getFileDropToQueryHandler((query, fileRejections) => {
if (!grafanaDS) {
return;
@@ -187,6 +218,7 @@ export function DataSourceModal({
logs={logs}
dashboard={dashboard}
mixed={mixed}
dataSources={dataSources}
/>
<BuiltInList className={styles.appendBuiltInDataSourcesList} />
</ScrollContainer>