1
+ import { useMemo } from 'react' ;
1
2
import type { Location } from 'history' ;
3
+ import qs from 'query-string' ;
2
4
3
5
import {
4
6
openAddToDashboardModal ,
@@ -15,6 +17,7 @@ import {
15
17
MEPState ,
16
18
useMEPSettingContext ,
17
19
} from 'sentry/utils/performance/contexts/metricsEnhancedSetting' ;
20
+ import { safeURL } from 'sentry/utils/url/safeURL' ;
18
21
import useOrganization from 'sentry/utils/useOrganization' ;
19
22
import type { DashboardFilters , Widget } from 'sentry/views/dashboards/types' ;
20
23
import { DashboardWidgetSource , WidgetType } from 'sentry/views/dashboards/types' ;
@@ -31,6 +34,7 @@ import {
31
34
} from 'sentry/views/dashboards/utils/getWidgetExploreUrl' ;
32
35
import { getReferrer } from 'sentry/views/dashboards/widgetCard/genericWidgetQueries' ;
33
36
import { Mode } from 'sentry/views/explore/contexts/pageParamsContext/mode' ;
37
+ import { getExploreUrl } from 'sentry/views/explore/utils' ;
34
38
35
39
import { useDashboardsMEPContext } from './dashboardsMEPContext' ;
36
40
@@ -49,26 +53,57 @@ export const useIndexedEventsWarning = (): string | null => {
49
53
50
54
export const useTransactionsDeprecationWarning = ( {
51
55
widget,
56
+ selection,
52
57
} : {
58
+ selection : PageFilters ;
53
59
widget : Widget ;
54
60
} ) : React . JSX . Element | null => {
55
61
const organization = useOrganization ( ) ;
56
62
57
- if (
58
- organization . features . includes ( 'transaction-widget-deprecation-explore-view' ) &&
59
- widget . widgetType === WidgetType . TRANSACTIONS &&
60
- widget . exploreUrls &&
61
- widget . exploreUrls . length > 0
62
- ) {
63
- return tct (
64
- 'Transactions widgets are in the process of being migrated to spans widgets. To see what your query could look like, open it in [explore:Explore].' ,
65
- {
66
- explore : < Link to = { widget . exploreUrls [ 0 ] ! } /> ,
67
- }
68
- ) ;
63
+ // memoize the URL to avoid recalculating it on every render
64
+ const exploreUrl = useMemo ( ( ) => {
65
+ if (
66
+ ! organization . features . includes ( 'transaction-widget-deprecation-explore-view' ) ||
67
+ widget . widgetType !== WidgetType . TRANSACTIONS ||
68
+ ! widget . exploreUrls ||
69
+ widget . exploreUrls . length === 0
70
+ ) {
71
+ return null ;
72
+ }
73
+ return createExploreUrl ( widget . exploreUrls [ 0 ] ! , selection , organization ) ;
74
+ } , [ organization , widget . widgetType , widget . exploreUrls , selection ] ) ;
75
+
76
+ if ( ! exploreUrl ) {
77
+ return null ;
69
78
}
70
79
71
- return null ;
80
+ return tct (
81
+ 'Transactions widgets are in the process of being migrated to spans widgets. To see what your query could look like, open it in [explore:Explore].' ,
82
+ {
83
+ explore : < Link to = { exploreUrl } /> ,
84
+ }
85
+ ) ;
86
+ } ;
87
+
88
+ const createExploreUrl = (
89
+ baseUrl : string ,
90
+ selection : PageFilters ,
91
+ organization : Organization
92
+ ) : string => {
93
+ const parsedUrl = safeURL ( baseUrl ) ;
94
+ const queryParams = qs . parse ( parsedUrl ?. search ?? '' ) ;
95
+
96
+ if ( queryParams . aggregateField ) {
97
+ // we need to parse the aggregateField because it comes in stringified but needs to be passed in JSON format
98
+ if ( typeof queryParams . aggregateField === 'string' ) {
99
+ queryParams . aggregateField = JSON . parse ( queryParams . aggregateField ) ;
100
+ } else if ( Array . isArray ( queryParams . aggregateField ) ) {
101
+ queryParams . aggregateField = queryParams . aggregateField . map ( item =>
102
+ JSON . parse ( item )
103
+ ) ;
104
+ }
105
+ }
106
+ return getExploreUrl ( { organization, selection, ...queryParams } ) ;
72
107
} ;
73
108
74
109
export function getMenuOptions (
0 commit comments