Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions static/app/utils/analytics/insightAnalyticEvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ export type InsightEventParameters = {
};
'insights.open_in_explore': {referrer: string};
'insights.page_loads.overview': {domain: DomainView | undefined; platforms: string[]};
'insights.release.select_release': {
filtered: boolean;
moduleName: ModuleName;
type: 'primary' | 'secondary';
};
'insights.session_health_tour.dismissed': Record<string, unknown>;
};

Expand Down Expand Up @@ -110,4 +115,5 @@ export const insightEventMap: Record<InsightEventKey, string | null> = {
'insights.eap.toggle': 'Insights: EAP Toggle',
'insights.open_in_explore': 'Insights: Open in Explore',
'insights.create_alert': 'Insights: Create Alert',
'insights.release.select_release': 'Insights: Select Release',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {OrganizationFixture} from 'sentry-fixture/organization';

import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';

import {trackAnalytics} from 'sentry/utils/analytics';
import {ReleaseComparisonSelector} from 'sentry/views/insights/common/components/releaseSelector';
import {ModuleName} from 'sentry/views/insights/types';

jest.mock('sentry/utils/analytics', () => ({
trackAnalytics: jest.fn(),
}));

jest.mock('sentry/views/insights/common/queries/useReleases', () => ({
useReleases: () => ({
data: [
{dateCreated: '2024-01-01T00:00:00Z', version: 'v1.0.0', count: 10},
{dateCreated: '2024-01-02T00:00:00Z', version: 'v2.0.0', count: 20},
],
isLoading: false,
}),
useReleaseSelection: () => ({
primaryRelease: undefined,
secondaryRelease: undefined,
isLoading: false,
}),
}));

describe('ReleaseComparisonSelector analytics', () => {
it('tracks primary release selection with module name and release', async () => {
const organization = OrganizationFixture();

render(<ReleaseComparisonSelector moduleName={ModuleName.MOBILE_VITALS} />, {
organization,
});

const primaryTrigger = screen.getByRole('button', {name: 'Filter Release'});
await userEvent.click(primaryTrigger);

const option = await screen.findByRole('option', {name: 'v2.0.0'});
await userEvent.click(option);

expect(trackAnalytics).toHaveBeenCalledWith(
'insights.release.select_release',
expect.objectContaining({
organization,
moduleName: ModuleName.MOBILE_VITALS,
filtered: true,
type: 'primary',
})
);

await userEvent.click(primaryTrigger);
const allOption = await screen.findByRole('option', {name: 'All'});
await userEvent.click(allOption);

expect(trackAnalytics).toHaveBeenCalledWith(
'insights.release.select_release',
expect.objectContaining({
organization,
moduleName: ModuleName.MOBILE_VITALS,
filtered: false,
type: 'primary',
})
);
});
});
21 changes: 21 additions & 0 deletions static/app/views/insights/common/components/releaseSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import {IconReleases} from 'sentry/icons/iconReleases';
import {t, tct, tn} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
import {decodeScalar} from 'sentry/utils/queryString';
import {useLocalStorageState} from 'sentry/utils/useLocalStorageState';
import {useLocation} from 'sentry/utils/useLocation';
import {useNavigate} from 'sentry/utils/useNavigate';
import useOrganization from 'sentry/utils/useOrganization';
import usePageFilters from 'sentry/utils/usePageFilters';
import {
ReleasesSort,
Expand All @@ -27,6 +29,7 @@ import {
useReleaseSelection,
} from 'sentry/views/insights/common/queries/useReleases';
import {formatVersionAndCenterTruncate} from 'sentry/views/insights/common/utils/formatVersionAndCenterTruncate';
import type {ModuleName} from 'sentry/views/insights/types';

export const PRIMARY_RELEASE_ALIAS = 'R1';
export const SECONDARY_RELEASE_ALIAS = 'R2';
Expand Down Expand Up @@ -108,6 +111,7 @@ function ReleaseSelector({
title: selectorValue,
prefix: triggerLabelPrefix,
children: triggerLabel,
'aria-label': t('Filter Release'),
}}
menuTitle={t('Filter Release')}
loading={isLoading}
Expand Down Expand Up @@ -187,16 +191,19 @@ function getReleasesSortBy(
}

type ReleaseComparisonSelectorProps = {
moduleName: ModuleName;
primaryOnly?: boolean;
};

export function ReleaseComparisonSelector({
primaryOnly = false,
moduleName,
}: ReleaseComparisonSelectorProps) {
const {primaryRelease, secondaryRelease} = useReleaseSelection();
const location = useLocation();
const navigate = useNavigate();
const {selection} = usePageFilters();
const organization = useOrganization();

const [localStoragedReleaseBy, setLocalStoragedReleaseBy] =
useLocalStorageState<ReleasesSortByOption>(
Expand Down Expand Up @@ -257,6 +264,13 @@ export function ReleaseComparisonSelector({
allOptionDescription={t('Show data from all releases.')}
allOptionTitle={t('All')}
onChange={newValue => {
trackAnalytics('insights.release.select_release', {
organization,
filtered: defined(newValue.value) && newValue.value !== '',
type: 'primary',
moduleName,
});

const updatedQuery: Record<string, string> = {
...location.query,
primaryRelease: newValue.value as string,
Expand Down Expand Up @@ -288,6 +302,13 @@ export function ReleaseComparisonSelector({
allOptionDescription={t('No comparison.')}
allOptionTitle={t('None')}
onChange={newValue => {
trackAnalytics('insights.release.select_release', {
organization,
filtered: defined(newValue.value) && newValue.value !== '',
type: 'secondary',
moduleName,
});

const updatedQuery: Record<string, string> = {
...location.query,
secondaryRelease: newValue.value as string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export function ScreenSummaryContentPage() {
<HeaderContainer>
<ToolRibbon>
<ModulePageFilterBar moduleName={ModuleName.APP_START} disableProjectFilter />
<ReleaseComparisonSelector />
<ReleaseComparisonSelector moduleName={ModuleName.APP_START} />
<StartTypeSelector />
</ToolRibbon>
<MobileMetricsRibbon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,11 @@ export function ScreenLoadSpansContent() {
<HeaderContainer>
<ToolRibbon>
<FilterContainer>
<ModulePageFilterBar moduleName={ModuleName.APP_START} disableProjectFilter />
<ReleaseComparisonSelector />
<ModulePageFilterBar
moduleName={ModuleName.SCREEN_LOAD}
disableProjectFilter
/>
<ReleaseComparisonSelector moduleName={ModuleName.SCREEN_LOAD} />
</FilterContainer>
</ToolRibbon>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ function ScreensLandingPage() {
<DatePageFilter />
</PageFilterBar>
<PageFilterBar condensed>
<ReleaseComparisonSelector primaryOnly />
<ReleaseComparisonSelector primaryOnly moduleName={moduleName} />
</PageFilterBar>
</ToolRibbon>
</Container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function ScreenSummaryContent() {
moduleName={ModuleName.SCREEN_RENDERING}
disableProjectFilter
/>
<ReleaseComparisonSelector />
<ReleaseComparisonSelector moduleName={ModuleName.SCREEN_RENDERING} />
</ToolRibbon>
</HeaderContainer>

Expand Down
Loading