Skip to content

Commit ae0716e

Browse files
authored
chore: Disable transactions dataset in widget builder (#95440)
Disable transaction dataset in widget builder. This is feature flagged. Disabling edits on existing transaction widgets in a follow up.
1 parent 4afb2c8 commit ae0716e

File tree

5 files changed

+136
-1
lines changed

5 files changed

+136
-1
lines changed

static/app/components/forms/controls/radioGroup.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ interface BaseRadioGroupProps<C extends string> {
3131
* Switch the radio items to flow left to right, instead of vertically.
3232
*/
3333
orientInline?: boolean;
34+
tooltipIsHoverable?: boolean;
3435
tooltipPosition?: PopperProps<any>['placement'];
3536
}
3637

@@ -59,6 +60,7 @@ function RadioGroup<C extends string>({
5960
onChange,
6061
orientInline,
6162
tooltipPosition,
63+
tooltipIsHoverable,
6264
...props
6365
}: RadioGroupProps<C>) {
6466
return (
@@ -84,6 +86,7 @@ function RadioGroup<C extends string>({
8486
disabled={!disabledChoiceReason}
8587
title={disabledChoiceReason}
8688
position={tooltipPosition}
89+
isHoverable={tooltipIsHoverable}
8790
>
8891
<RadioLineItem index={index} aria-checked={value === id} disabled={disabled}>
8992
<Radio

static/app/views/dashboards/widgetBuilder/buildSteps/dataSetStep.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ export function DataSetStep({
8787
if (hasDatasetSelectorFeature) {
8888
// TODO: Finalize description copy
8989
datasetChoices.set(DataSet.ERRORS, t('Errors (TypeError, InvalidSearchQuery, etc)'));
90+
if (organization.features.includes('discover-saved-queries-deprecation')) {
91+
disabledChoices.push([
92+
DataSet.TRANSACTIONS,
93+
t('This dataset is is no longer supported. Please use the Spans dataset.'),
94+
]);
95+
}
9096
datasetChoices.set(DataSet.TRANSACTIONS, t('Transactions'));
9197
}
9298

static/app/views/dashboards/widgetBuilder/components/datasetSelector.spec.tsx

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,81 @@ describe('DatasetSelector', function () {
4646
expect.anything()
4747
);
4848
});
49+
50+
it('disables transactions dataset when discover-saved-queries-deprecation feature is enabled', async function () {
51+
const mockNavigate = jest.fn();
52+
mockUseNavigate.mockReturnValue(mockNavigate);
53+
54+
const organizationWithDeprecation = OrganizationFixture({
55+
features: ['discover-saved-queries-deprecation'],
56+
});
57+
58+
render(
59+
<WidgetBuilderProvider>
60+
<DatasetSelector />
61+
</WidgetBuilderProvider>,
62+
{
63+
router,
64+
organization: organizationWithDeprecation,
65+
deprecatedRouterMocks: true,
66+
}
67+
);
68+
69+
const transactionsRadio = screen.getByRole('radio', {name: /transactions/i});
70+
expect(transactionsRadio).toBeDisabled();
71+
72+
// Hover on the disabled transactions dataset to show tooltip
73+
await userEvent.hover(transactionsRadio);
74+
75+
expect(
76+
await screen.findByText(/This dataset is is no longer supported./i)
77+
).toBeInTheDocument();
78+
79+
// Click on the "Spans" link in the tooltip
80+
const spansLink = screen.getByRole('link', {name: 'Spans'});
81+
await userEvent.click(spansLink);
82+
83+
// Verify navigation to spans dataset
84+
expect(mockNavigate).toHaveBeenCalledWith(
85+
expect.objectContaining({
86+
...router.location,
87+
query: expect.objectContaining({dataset: 'spans'}),
88+
}),
89+
expect.anything()
90+
);
91+
});
92+
93+
it('enables transactions dataset when discover-saved-queries-deprecation feature is disabled', async function () {
94+
const mockNavigate = jest.fn();
95+
mockUseNavigate.mockReturnValue(mockNavigate);
96+
97+
const organizationWithoutDeprecation = OrganizationFixture({
98+
features: [], // No discover-saved-queries-deprecation feature
99+
});
100+
101+
render(
102+
<WidgetBuilderProvider>
103+
<DatasetSelector />
104+
</WidgetBuilderProvider>,
105+
{
106+
router,
107+
organization: organizationWithoutDeprecation,
108+
deprecatedRouterMocks: true,
109+
}
110+
);
111+
112+
const transactionsRadio = screen.getByRole('radio', {name: /transactions/i});
113+
expect(transactionsRadio).toBeEnabled();
114+
115+
// Verify transactions dataset can be selected
116+
await userEvent.click(transactionsRadio);
117+
118+
expect(mockNavigate).toHaveBeenCalledWith(
119+
expect.objectContaining({
120+
...router.location,
121+
query: expect.objectContaining({dataset: 'transaction-like'}),
122+
}),
123+
expect.anything()
124+
);
125+
});
49126
});

static/app/views/dashboards/widgetBuilder/components/datasetSelector.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import {Fragment} from 'react';
22
import styled from '@emotion/styled';
33

44
import {FeatureBadge} from 'sentry/components/core/badge/featureBadge';
5-
import RadioGroup, {type RadioOption} from 'sentry/components/forms/controls/radioGroup';
5+
import {Link} from 'sentry/components/core/link';
6+
import type {
7+
RadioGroupProps,
8+
RadioOption,
9+
} from 'sentry/components/forms/controls/radioGroup';
10+
import RadioGroup from 'sentry/components/forms/controls/radioGroup';
611
import ExternalLink from 'sentry/components/links/externalLink';
712
import {t, tct} from 'sentry/locale';
813
import {space} from 'sentry/styles/space';
@@ -15,16 +20,37 @@ import {useWidgetBuilderContext} from 'sentry/views/dashboards/widgetBuilder/con
1520
import {useCacheBuilderState} from 'sentry/views/dashboards/widgetBuilder/hooks/useCacheBuilderState';
1621
import useDashboardWidgetSource from 'sentry/views/dashboards/widgetBuilder/hooks/useDashboardWidgetSource';
1722
import useIsEditingWidget from 'sentry/views/dashboards/widgetBuilder/hooks/useIsEditingWidget';
23+
import {useSegmentSpanWidgetState} from 'sentry/views/dashboards/widgetBuilder/hooks/useSegmentSpanWidgetState';
1824

1925
function WidgetBuilderDatasetSelector() {
2026
const organization = useOrganization();
2127
const {state} = useWidgetBuilderContext();
2228
const source = useDashboardWidgetSource();
2329
const isEditing = useIsEditingWidget();
2430
const {cacheBuilderState, restoreOrSetBuilderState} = useCacheBuilderState();
31+
const {setSegmentSpanBuilderState} = useSegmentSpanWidgetState();
32+
const disabledChoices: RadioGroupProps<WidgetType>['disabledChoices'] = [];
2533

2634
const datasetChoices: Array<RadioOption<WidgetType>> = [];
2735
datasetChoices.push([WidgetType.ERRORS, t('Errors')]);
36+
if (organization.features.includes('discover-saved-queries-deprecation')) {
37+
disabledChoices.push([
38+
WidgetType.TRANSACTIONS,
39+
tct('This dataset is is no longer supported. Please use the [spans] dataset.', {
40+
spans: (
41+
<Link
42+
to=""
43+
onClick={() => {
44+
cacheBuilderState(state.dataset ?? WidgetType.ERRORS);
45+
setSegmentSpanBuilderState();
46+
}}
47+
>
48+
{t('Spans')}
49+
</Link>
50+
),
51+
}),
52+
]);
53+
}
2854
datasetChoices.push([WidgetType.TRANSACTIONS, t('Transactions')]);
2955

3056
if (organization.features.includes('visibility-explore-view')) {
@@ -66,6 +92,8 @@ function WidgetBuilderDatasetSelector() {
6692
label={t('Dataset')}
6793
value={state.dataset ?? WidgetType.ERRORS}
6894
choices={datasetChoices}
95+
disabledChoices={disabledChoices}
96+
tooltipIsHoverable
6997
onChange={(newDataset: WidgetType) => {
7098
// Set the current dataset state in local storage for recovery
7199
// when the user navigates back to this dataset
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {useCallback} from 'react';
2+
3+
import {WidgetType} from 'sentry/views/dashboards/types';
4+
import {useWidgetBuilderContext} from 'sentry/views/dashboards/widgetBuilder/contexts/widgetBuilderContext';
5+
import {BuilderStateAction} from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState';
6+
7+
export function useSegmentSpanWidgetState() {
8+
const {dispatch} = useWidgetBuilderContext();
9+
10+
const setSegmentSpanBuilderState = useCallback(() => {
11+
const nextDataset = WidgetType.SPANS;
12+
dispatch({
13+
type: BuilderStateAction.SET_STATE,
14+
payload: {dataset: nextDataset, query: ['is_transaction:true']},
15+
});
16+
}, [dispatch]);
17+
18+
return {
19+
setSegmentSpanBuilderState,
20+
};
21+
}

0 commit comments

Comments
 (0)