mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PublicDashboards: Frontend tracking events (#64854)
This commit is contained in:
@@ -206,6 +206,8 @@ export const Pages = {
|
||||
EmailSharingInput: 'data-testid public dashboard email sharing input',
|
||||
EmailSharingInviteButton: 'data-testid public dashboard email sharing invite button',
|
||||
EmailSharingList: 'data-testid public dashboard email sharing list',
|
||||
DeleteEmail: 'data-testid public dashboard delete email button',
|
||||
ReshareLink: 'data-testid public dashboard reshare link button',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -41,7 +41,7 @@ import { EmailSharingConfiguration } from './EmailSharingConfiguration';
|
||||
|
||||
const selectors = e2eSelectors.pages.ShareDashboardModal.PublicDashboard;
|
||||
|
||||
export interface ConfigPublicDashoardForm {
|
||||
export interface ConfigPublicDashboardForm {
|
||||
isAnnotationsEnabled: boolean;
|
||||
isTimeSelectionEnabled: boolean;
|
||||
isPaused: boolean;
|
||||
@@ -64,7 +64,7 @@ const ConfigPublicDashboard = () => {
|
||||
const [update, { isLoading: isUpdateLoading }] = useUpdatePublicDashboardMutation();
|
||||
const disableInputs = !hasWritePermissions || isUpdateLoading || isGetLoading;
|
||||
|
||||
const { handleSubmit, setValue, register } = useForm<ConfigPublicDashoardForm>({
|
||||
const { handleSubmit, setValue, register } = useForm<ConfigPublicDashboardForm>({
|
||||
defaultValues: {
|
||||
isAnnotationsEnabled: publicDashboard?.annotationsEnabled,
|
||||
isTimeSelectionEnabled: publicDashboard?.timeSelectionEnabled,
|
||||
@@ -72,7 +72,7 @@ const ConfigPublicDashboard = () => {
|
||||
},
|
||||
});
|
||||
|
||||
const onUpdate = async (values: ConfigPublicDashoardForm) => {
|
||||
const onUpdate = async (values: ConfigPublicDashboardForm) => {
|
||||
const { isAnnotationsEnabled, isTimeSelectionEnabled, isPaused } = values;
|
||||
|
||||
const req = {
|
||||
@@ -88,7 +88,7 @@ const ConfigPublicDashboard = () => {
|
||||
update(req);
|
||||
};
|
||||
|
||||
const onChange = async (name: keyof ConfigPublicDashoardForm, value: boolean) => {
|
||||
const onChange = async (name: keyof ConfigPublicDashboardForm, value: boolean) => {
|
||||
setValue(name, value);
|
||||
await handleSubmit((data) => onUpdate(data))();
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ import { getTimeRange } from 'app/features/dashboard/utils/timeRange';
|
||||
|
||||
import { useSelector } from '../../../../../../types';
|
||||
|
||||
import { ConfigPublicDashoardForm } from './ConfigPublicDashboard';
|
||||
import { ConfigPublicDashboardForm } from './ConfigPublicDashboard';
|
||||
|
||||
const selectors = e2eSelectors.pages.ShareDashboardModal.PublicDashboard;
|
||||
|
||||
@@ -21,8 +21,8 @@ export const Configuration = ({
|
||||
register,
|
||||
}: {
|
||||
disabled: boolean;
|
||||
onChange: (name: keyof ConfigPublicDashoardForm, value: boolean) => void;
|
||||
register: UseFormRegister<ConfigPublicDashoardForm>;
|
||||
onChange: (name: keyof ConfigPublicDashboardForm, value: boolean) => void;
|
||||
register: UseFormRegister<ConfigPublicDashboardForm>;
|
||||
}) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
@@ -45,7 +45,12 @@ export const Configuration = ({
|
||||
<Switch
|
||||
{...register('isTimeSelectionEnabled')}
|
||||
data-testid={selectors.EnableTimeRangeSwitch}
|
||||
onChange={(e) => onChange('isTimeSelectionEnabled', e.currentTarget.checked)}
|
||||
onChange={(e) => {
|
||||
reportInteraction('grafana_dashboards_public_time_selection_clicked', {
|
||||
action: e.currentTarget.checked ? 'enable' : 'disable',
|
||||
});
|
||||
onChange('isTimeSelectionEnabled', e.currentTarget.checked);
|
||||
}}
|
||||
/>
|
||||
<Label description="Allow viewers to change time range">Time range picker enabled</Label>
|
||||
</Layout>
|
||||
@@ -53,7 +58,7 @@ export const Configuration = ({
|
||||
<Switch
|
||||
{...register('isAnnotationsEnabled')}
|
||||
onChange={(e) => {
|
||||
reportInteraction('grafana_dashboards_annotations_clicked', {
|
||||
reportInteraction('grafana_dashboards_public_annotations_clicked', {
|
||||
action: e.currentTarget.checked ? 'enable' : 'disable',
|
||||
});
|
||||
onChange('isAnnotationsEnabled', e.currentTarget.checked);
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useForm } from 'react-hook-form';
|
||||
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data/src';
|
||||
import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
|
||||
import { reportInteraction } from '@grafana/runtime/src';
|
||||
import {
|
||||
Button,
|
||||
ButtonGroup,
|
||||
@@ -53,17 +54,19 @@ const EmailList = ({
|
||||
const isLoading = isDeleteLoading || isReshareLoading;
|
||||
|
||||
const onDeleteEmail = (recipientUid: string) => {
|
||||
reportInteraction('grafana_dashboards_public_delete_sharing_email_clicked');
|
||||
deleteEmail({ recipientUid, dashboardUid: dashboardUid, uid: publicDashboardUid });
|
||||
};
|
||||
|
||||
const onReshare = (recipientUid: string) => {
|
||||
reportInteraction('grafana_dashboards_public_reshare_email_clicked');
|
||||
reshareAccess({ recipientUid, uid: publicDashboardUid });
|
||||
};
|
||||
|
||||
return (
|
||||
<table className={styles.table} data-testid={selectors.EmailSharingList}>
|
||||
<tbody>
|
||||
{recipients!.map((recipient) => (
|
||||
{recipients!.map((recipient, idx) => (
|
||||
<tr key={recipient.uid}>
|
||||
<td>{recipient.recipient}</td>
|
||||
<td>
|
||||
@@ -77,6 +80,7 @@ const EmailList = ({
|
||||
size="sm"
|
||||
disabled={isLoading}
|
||||
onClick={() => onDeleteEmail(recipient.uid)}
|
||||
data-testid={`${selectors.DeleteEmail}-${idx}`}
|
||||
>
|
||||
Revoke
|
||||
</Button>
|
||||
@@ -89,6 +93,7 @@ const EmailList = ({
|
||||
size="sm"
|
||||
disabled={isLoading}
|
||||
onClick={() => onReshare(recipient.uid)}
|
||||
data-testid={`${selectors.ReshareLink}-${idx}`}
|
||||
>
|
||||
Resend
|
||||
</Button>
|
||||
@@ -139,6 +144,8 @@ export const EmailSharingConfiguration = () => {
|
||||
};
|
||||
|
||||
const onSubmit = async (data: EmailSharingConfigurationForm) => {
|
||||
//TODO: add if it's domain or not when developed.
|
||||
reportInteraction('grafana_dashboards_public_add_share_email_clicked');
|
||||
await addEmail({ recipient: data.email, uid: publicDashboard!.uid, dashboardUid: dashboard.uid }).unwrap();
|
||||
reset({ email: '', shareType: PublicDashboardShareType.EMAIL });
|
||||
};
|
||||
@@ -156,6 +163,9 @@ export const EmailSharingConfiguration = () => {
|
||||
{...rest}
|
||||
options={options}
|
||||
onChange={(shareType: PublicDashboardShareType) => {
|
||||
reportInteraction('grafana_dashboards_public_share_type_clicked', {
|
||||
type: shareType,
|
||||
});
|
||||
setValue('shareType', shareType);
|
||||
onShareTypeChange(shareType);
|
||||
}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { rest } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
@@ -6,7 +6,7 @@ import { setupServer } from 'msw/node';
|
||||
import 'whatwg-fetch';
|
||||
import { BootData, DataQuery } from '@grafana/data/src';
|
||||
import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
|
||||
import { setEchoSrv } from '@grafana/runtime/src';
|
||||
import { reportInteraction, setEchoSrv } from '@grafana/runtime';
|
||||
import { Panel } from '@grafana/schema';
|
||||
import config from 'app/core/config';
|
||||
import { backendSrv } from 'app/core/services/backend_srv';
|
||||
@@ -27,6 +27,7 @@ const server = setupServer();
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
getBackendSrv: () => backendSrv,
|
||||
reportInteraction: jest.fn(),
|
||||
}));
|
||||
|
||||
const selectors = e2eSelectors.pages.ShareDashboardModal.PublicDashboard;
|
||||
@@ -307,3 +308,48 @@ describe('SharePublic - Already persisted', () => {
|
||||
});
|
||||
alertTests();
|
||||
});
|
||||
|
||||
describe('SharePublic - Report interactions', () => {
|
||||
beforeEach(() => {
|
||||
server.use(getExistentPublicDashboardResponse());
|
||||
server.use(
|
||||
rest.put('/api/dashboards/uid/:dashboardUid/public-dashboards/:uid', (req, res, ctx) =>
|
||||
res(
|
||||
ctx.status(200),
|
||||
ctx.json({
|
||||
...pubdashResponse,
|
||||
dashboardUid: req.params.dashboardUid,
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('reports interaction when time range is clicked', async () => {
|
||||
await renderSharePublicDashboard();
|
||||
await userEvent.click(screen.getByTestId(selectors.EnableTimeRangeSwitch));
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'));
|
||||
|
||||
expect(reportInteraction).toHaveBeenCalledWith('grafana_dashboards_public_time_selection_clicked', {
|
||||
action: pubdashResponse.timeSelectionEnabled ? 'disable' : 'enable',
|
||||
});
|
||||
});
|
||||
it('reports interaction when show annotations is clicked', async () => {
|
||||
await renderSharePublicDashboard();
|
||||
await userEvent.click(screen.getByTestId(selectors.EnableAnnotationsSwitch));
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'));
|
||||
|
||||
expect(reportInteraction).toHaveBeenCalledWith('grafana_dashboards_public_annotations_clicked', {
|
||||
action: pubdashResponse.annotationsEnabled ? 'disable' : 'enable',
|
||||
});
|
||||
});
|
||||
it('reports interaction when pause is clicked', async () => {
|
||||
await renderSharePublicDashboard();
|
||||
await userEvent.click(screen.getByTestId(selectors.PauseSwitch));
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'));
|
||||
|
||||
expect(reportInteraction).toHaveBeenCalledWith('grafana_dashboards_public_enable_clicked', {
|
||||
action: pubdashResponse.isEnabled ? 'disable' : 'enable',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user