mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Query History: Add feature tracking for query history (#49685)
* Add feature tracking for query history * Fix unit tests * Update event names
This commit is contained in:
parent
c6ac9410b2
commit
e0adb41e80
@ -18,6 +18,11 @@ const mockDS = mockDataSource({
|
|||||||
type: DataSourceType.Alertmanager,
|
type: DataSourceType.Alertmanager,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jest.mock('@grafana/runtime', () => ({
|
||||||
|
...jest.requireActual('@grafana/runtime'),
|
||||||
|
reportInteraction: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
jest.mock('@grafana/runtime/src/services/dataSourceSrv', () => {
|
jest.mock('@grafana/runtime/src/services/dataSourceSrv', () => {
|
||||||
return {
|
return {
|
||||||
getDataSourceSrv: () => ({
|
getDataSourceSrv: () => ({
|
||||||
|
@ -3,7 +3,7 @@ import React, { useState, useEffect } from 'react';
|
|||||||
import { connect, ConnectedProps } from 'react-redux';
|
import { connect, ConnectedProps } from 'react-redux';
|
||||||
|
|
||||||
import { GrafanaTheme, DataSourceApi, DataQuery } from '@grafana/data';
|
import { GrafanaTheme, DataSourceApi, DataQuery } from '@grafana/data';
|
||||||
import { getDataSourceSrv } from '@grafana/runtime';
|
import { config, getDataSourceSrv, reportInteraction } from '@grafana/runtime';
|
||||||
import { stylesFactory, useTheme, TextArea, Button, IconButton } from '@grafana/ui';
|
import { stylesFactory, useTheme, TextArea, Button, IconButton } from '@grafana/ui';
|
||||||
import { notifyApp } from 'app/core/actions';
|
import { notifyApp } from 'app/core/actions';
|
||||||
import appEvents from 'app/core/app_events';
|
import appEvents from 'app/core/app_events';
|
||||||
@ -176,12 +176,17 @@ export function RichHistoryCard(props: Props) {
|
|||||||
|
|
||||||
const onRunQuery = async () => {
|
const onRunQuery = async () => {
|
||||||
const queriesToRun = query.queries;
|
const queriesToRun = query.queries;
|
||||||
if (query.datasourceName !== datasourceInstance?.name) {
|
const differentDataSource = query.datasourceName !== datasourceInstance?.name;
|
||||||
|
if (differentDataSource) {
|
||||||
await changeDatasource(exploreId, query.datasourceName, { importQueries: true });
|
await changeDatasource(exploreId, query.datasourceName, { importQueries: true });
|
||||||
setQueries(exploreId, queriesToRun);
|
setQueries(exploreId, queriesToRun);
|
||||||
} else {
|
} else {
|
||||||
setQueries(exploreId, queriesToRun);
|
setQueries(exploreId, queriesToRun);
|
||||||
}
|
}
|
||||||
|
reportInteraction('grafana_explore_query_history_run', {
|
||||||
|
queryHistoryEnabled: config.queryHistoryEnabled,
|
||||||
|
differentDataSource,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCopyQuery = () => {
|
const onCopyQuery = () => {
|
||||||
@ -196,6 +201,14 @@ export function RichHistoryCard(props: Props) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onDeleteQuery = () => {
|
const onDeleteQuery = () => {
|
||||||
|
const performDelete = (queryId: string) => {
|
||||||
|
deleteHistoryItem(queryId);
|
||||||
|
dispatch(notifyApp(createSuccessNotification('Query deleted')));
|
||||||
|
reportInteraction('grafana_explore_query_history_deleted', {
|
||||||
|
queryHistoryEnabled: config.queryHistoryEnabled,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// For starred queries, we want confirmation. For non-starred, we don't.
|
// For starred queries, we want confirmation. For non-starred, we don't.
|
||||||
if (query.starred) {
|
if (query.starred) {
|
||||||
appEvents.publish(
|
appEvents.publish(
|
||||||
@ -204,20 +217,20 @@ export function RichHistoryCard(props: Props) {
|
|||||||
text: 'Are you sure you want to permanently delete your starred query?',
|
text: 'Are you sure you want to permanently delete your starred query?',
|
||||||
yesText: 'Delete',
|
yesText: 'Delete',
|
||||||
icon: 'trash-alt',
|
icon: 'trash-alt',
|
||||||
onConfirm: () => {
|
onConfirm: () => performDelete(query.id),
|
||||||
deleteHistoryItem(query.id);
|
|
||||||
dispatch(notifyApp(createSuccessNotification('Query deleted')));
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
deleteHistoryItem(query.id);
|
performDelete(query.id);
|
||||||
dispatch(notifyApp(createSuccessNotification('Query deleted')));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onStarrQuery = () => {
|
const onStarrQuery = () => {
|
||||||
starHistoryItem(query.id, !query.starred);
|
starHistoryItem(query.id, !query.starred);
|
||||||
|
reportInteraction('grafana_explore_query_history_starred', {
|
||||||
|
queryHistoryEnabled: config.queryHistoryEnabled,
|
||||||
|
newValue: !query.starred,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleActiveUpdateComment = () => setActiveUpdateComment(!activeUpdateComment);
|
const toggleActiveUpdateComment = () => setActiveUpdateComment(!activeUpdateComment);
|
||||||
@ -225,6 +238,9 @@ export function RichHistoryCard(props: Props) {
|
|||||||
const onUpdateComment = () => {
|
const onUpdateComment = () => {
|
||||||
commentHistoryItem(query.id, comment);
|
commentHistoryItem(query.id, comment);
|
||||||
setActiveUpdateComment(false);
|
setActiveUpdateComment(false);
|
||||||
|
reportInteraction('grafana_explore_query_history_commented', {
|
||||||
|
queryHistoryEnabled: config.queryHistoryEnabled,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancelUpdateComment = () => {
|
const onCancelUpdateComment = () => {
|
||||||
|
@ -17,6 +17,7 @@ jest.mock('@grafana/runtime', () => ({
|
|||||||
getList: () => [],
|
getList: () => [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
reportInteraction: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const setup = (propOverrides?: Partial<Props>) => {
|
const setup = (propOverrides?: Partial<Props>) => {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { connect, ConnectedProps } from 'react-redux';
|
import { connect, ConnectedProps } from 'react-redux';
|
||||||
|
|
||||||
|
import { config, reportInteraction } from '@grafana/runtime';
|
||||||
import { useTheme2 } from '@grafana/ui';
|
import { useTheme2 } from '@grafana/ui';
|
||||||
// Types
|
// Types
|
||||||
import { ExploreItemState, StoreState } from 'app/types';
|
import { ExploreItemState, StoreState } from 'app/types';
|
||||||
@ -86,6 +87,9 @@ export function RichHistoryContainer(props: Props) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initRichHistory();
|
initRichHistory();
|
||||||
|
reportInteraction('grafana_explore_query_history_opened', {
|
||||||
|
queryHistoryEnabled: config.queryHistoryEnabled,
|
||||||
|
});
|
||||||
}, [initRichHistory]);
|
}, [initRichHistory]);
|
||||||
|
|
||||||
if (!richHistorySettings) {
|
if (!richHistorySettings) {
|
||||||
|
@ -40,9 +40,13 @@ import {
|
|||||||
const fetchMock = jest.fn();
|
const fetchMock = jest.fn();
|
||||||
const postMock = jest.fn();
|
const postMock = jest.fn();
|
||||||
const getMock = jest.fn();
|
const getMock = jest.fn();
|
||||||
|
const reportInteractionMock = jest.fn();
|
||||||
jest.mock('@grafana/runtime', () => ({
|
jest.mock('@grafana/runtime', () => ({
|
||||||
...jest.requireActual('@grafana/runtime'),
|
...jest.requireActual('@grafana/runtime'),
|
||||||
getBackendSrv: () => ({ fetch: fetchMock, post: postMock, get: getMock }),
|
getBackendSrv: () => ({ fetch: fetchMock, post: postMock, get: getMock }),
|
||||||
|
reportInteraction: (...args: object[]) => {
|
||||||
|
reportInteractionMock(...args);
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('app/core/core', () => ({
|
jest.mock('app/core/core', () => ({
|
||||||
@ -84,6 +88,7 @@ describe('Explore: Query History', () => {
|
|||||||
fetchMock.mockClear();
|
fetchMock.mockClear();
|
||||||
postMock.mockClear();
|
postMock.mockClear();
|
||||||
getMock.mockClear();
|
getMock.mockClear();
|
||||||
|
reportInteractionMock.mockClear();
|
||||||
tearDown();
|
tearDown();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -109,6 +114,11 @@ describe('Explore: Query History', () => {
|
|||||||
// previously added query is in query history
|
// previously added query is in query history
|
||||||
await openQueryHistory();
|
await openQueryHistory();
|
||||||
await assertQueryHistoryExists(RAW_QUERY);
|
await assertQueryHistoryExists(RAW_QUERY);
|
||||||
|
|
||||||
|
expect(reportInteractionMock).toBeCalledTimes(2);
|
||||||
|
expect(reportInteractionMock).toBeCalledWith('grafana_explore_query_history_opened', {
|
||||||
|
queryHistoryEnabled: false,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds recently added query if the query history panel is already open', async () => {
|
it('adds recently added query if the query history panel is already open', async () => {
|
||||||
@ -159,10 +169,17 @@ describe('Explore: Query History', () => {
|
|||||||
starQueryHistory(1, ExploreId.left);
|
starQueryHistory(1, ExploreId.left);
|
||||||
await assertQueryHistoryIsStarred([false, true], ExploreId.left);
|
await assertQueryHistoryIsStarred([false, true], ExploreId.left);
|
||||||
await assertQueryHistoryIsStarred([false, true], ExploreId.right);
|
await assertQueryHistoryIsStarred([false, true], ExploreId.right);
|
||||||
|
expect(reportInteractionMock).toBeCalledWith('grafana_explore_query_history_starred', {
|
||||||
|
queryHistoryEnabled: false,
|
||||||
|
newValue: true,
|
||||||
|
});
|
||||||
|
|
||||||
deleteQueryHistory(0, ExploreId.left);
|
deleteQueryHistory(0, ExploreId.left);
|
||||||
await assertQueryHistory(['{"expr":"query #1"}'], ExploreId.left);
|
await assertQueryHistory(['{"expr":"query #1"}'], ExploreId.left);
|
||||||
await assertQueryHistory(['{"expr":"query #1"}'], ExploreId.right);
|
await assertQueryHistory(['{"expr":"query #1"}'], ExploreId.right);
|
||||||
|
expect(reportInteractionMock).toBeCalledWith('grafana_explore_query_history_deleted', {
|
||||||
|
queryHistoryEnabled: false,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updates query history settings', async () => {
|
it('updates query history settings', async () => {
|
||||||
@ -198,6 +215,9 @@ describe('Explore: Query History', () => {
|
|||||||
|
|
||||||
await openQueryHistory();
|
await openQueryHistory();
|
||||||
expect(postMock).not.toBeCalledWith('/api/query-history/migrate', { queries: [] });
|
expect(postMock).not.toBeCalledWith('/api/query-history/migrate', { queries: [] });
|
||||||
|
expect(reportInteractionMock).toBeCalledWith('grafana_explore_query_history_opened', {
|
||||||
|
queryHistoryEnabled: false,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('migrates query history from local storage', async () => {
|
it('migrates query history from local storage', async () => {
|
||||||
@ -225,6 +245,9 @@ describe('Explore: Query History', () => {
|
|||||||
url: expect.stringMatching('/api/query-history/migrate'),
|
url: expect.stringMatching('/api/query-history/migrate'),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
expect(reportInteractionMock).toBeCalledWith('grafana_explore_query_history_opened', {
|
||||||
|
queryHistoryEnabled: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user