Skip to content

Commit 05b175f

Browse files
committed
ref(ui): Change useReleaseMarkLineSeries to use useReleaseStats hook
1 parent 0b1823b commit 05b175f

File tree

5 files changed

+74
-33
lines changed

5 files changed

+74
-33
lines changed

static/app/components/charts/baseChart.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {css, Global, useTheme} from '@emotion/react';
1010
import styled from '@emotion/styled';
1111
import type {
1212
AxisPointerComponentOption,
13+
CustomSeriesOption,
1314
ECharts,
1415
EChartsOption,
1516
GridComponentOption,
@@ -137,7 +138,7 @@ export interface BaseChartProps {
137138
* Additional Chart Series
138139
* This is to pass series to BaseChart bypassing the wrappers like LineChart, AreaChart etc.
139140
*/
140-
additionalSeries?: LineSeriesOption[];
141+
additionalSeries?: Array<CustomSeriesOption | SeriesOption>;
141142
/**
142143
* If true, ignores height value and auto-scales chart to fit container height.
143144
*/

static/app/views/dashboards/widgets/timeSeriesWidget/releaseBubbles/useReleaseBubbles.tsx

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type {ReactElement} from 'react';
1+
import {type ReactElement, useCallback, useRef} from 'react';
22
import {type Theme, useTheme} from '@emotion/react';
33
import type {
44
CustomSeriesOption,
@@ -294,7 +294,7 @@ ${t('Click to expand')}
294294
}
295295

296296
interface UseReleaseBubblesParams {
297-
chartRef: React.RefObject<ReactEchartsRef | null>;
297+
bubblePadding?: {x: number; y: number};
298298
bubbleSize?: number;
299299
chartRenderer?: (rendererProps: {
300300
end: Date;
@@ -306,7 +306,6 @@ interface UseReleaseBubblesParams {
306306
releases?: ReleaseMetaBasic[];
307307
}
308308
export function useReleaseBubbles({
309-
chartRef,
310309
chartRenderer,
311310
releases,
312311
minTime,
@@ -317,7 +316,15 @@ export function useReleaseBubbles({
317316
const {openDrawer} = useDrawer();
318317
const theme = useTheme();
319318
const {options} = useUser();
319+
const chartRef = useRef<ReactEchartsRef | null>(null);
320320
const hasReleaseBubbles = organization.features.includes('release-bubbles-ui');
321+
const handleChartRef = useCallback((e: ReactEchartsRef | null) => {
322+
chartRef.current = e;
323+
324+
if (e?.getEchartsInstance) {
325+
createReleaseBubbleHighlighter(e.getEchartsInstance());
326+
}
327+
}, []);
321328
const buckets =
322329
(hasReleaseBubbles &&
323330
releases?.length &&
@@ -337,7 +344,7 @@ export function useReleaseBubbles({
337344
}
338345

339346
return {
340-
createReleaseBubbleHighlighter,
347+
createReleaseBubbleHighlighter: handleChartRef,
341348

342349
/**
343350
* An object map of ECharts event handlers. These should be spread onto a Chart component

static/app/views/dashboards/widgets/timeSeriesWidget/timeSeriesWidgetVisualization.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ export function TimeSeriesWidgetVisualization(props: TimeSeriesWidgetVisualizati
111111
releaseBubbleXAxis,
112112
releaseBubbleGrid,
113113
} = useReleaseBubbles({
114-
chartRef,
115114
chartRenderer: ({start: trimStart, end: trimEnd}) => {
116115
return (
117116
<TimeSeriesWidgetVisualization
@@ -162,7 +161,7 @@ export function TimeSeriesWidgetVisualization(props: TimeSeriesWidgetVisualizati
162161
registerWithWidgetSyncContext(echartsInstance);
163162

164163
if (hasReleaseBubblesSeries) {
165-
createReleaseBubbleHighlighter(echartsInstance);
164+
createReleaseBubbleHighlighter(e);
166165
}
167166
},
168167
[

static/app/views/issueDetails/streamline/eventGraph.tsx

+48-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ import {useApiQuery} from 'sentry/utils/queryClient';
2525
import {useLocalStorageState} from 'sentry/utils/useLocalStorageState';
2626
import {useLocation} from 'sentry/utils/useLocation';
2727
import useOrganization from 'sentry/utils/useOrganization';
28+
import {useReleaseStats} from 'sentry/utils/useReleaseStats';
2829
import {getBucketSize} from 'sentry/views/dashboards/utils/getBucketSize';
30+
import {useReleaseBubbles} from 'sentry/views/dashboards/widgets/timeSeriesWidget/releaseBubbles/useReleaseBubbles';
2931
import {useIssueDetails} from 'sentry/views/issueDetails/streamline/context';
3032
import {useCurrentEventMarklineSeries} from 'sentry/views/issueDetails/streamline/hooks/useEventMarkLineSeries';
3133
import useFlagSeries from 'sentry/views/issueDetails/streamline/hooks/useFlagSeries';
@@ -79,6 +81,7 @@ export function EventGraph({group, event, ...styleProps}: EventGraphProps) {
7981
const config = getConfigForIssueType(group, group.project);
8082
const {dispatch} = useIssueDetails();
8183
const {currentTab} = useGroupDetailsRoute();
84+
const hasReleaseBubblesSeries = organization.features.includes('release-bubbles-ui');
8285

8386
const {
8487
data: groupStats = {},
@@ -176,7 +179,43 @@ export function EventGraph({group, event, ...styleProps}: EventGraphProps) {
176179
event,
177180
group,
178181
});
179-
const releaseSeries = useReleaseMarkLineSeries({group});
182+
183+
const {releases = []} = useReleaseStats(
184+
{
185+
projects: eventView.project,
186+
environments: eventView.environment,
187+
datetime: {
188+
start: eventView.start,
189+
end: eventView.end,
190+
period: eventView.statsPeriod,
191+
},
192+
},
193+
{
194+
staleTime: 0,
195+
}
196+
);
197+
198+
const releaseSeries = useReleaseMarkLineSeries({
199+
group,
200+
releases: hasReleaseBubblesSeries ? [] : releases,
201+
});
202+
203+
const {
204+
createReleaseBubbleHighlighter,
205+
releaseBubbleEventHandlers,
206+
releaseBubbleSeries,
207+
releaseBubbleXAxis,
208+
releaseBubbleGrid,
209+
} = useReleaseBubbles({
210+
minTime: eventSeries.length && (eventSeries[0]!.name as number),
211+
maxTime: eventSeries.length && (eventSeries[eventSeries.length - 1]!.name as number),
212+
bubbleSize: 4,
213+
bubblePadding: {
214+
x: 1,
215+
y: 2,
216+
},
217+
releases,
218+
});
180219
const flagSeries = useFlagSeries({
181220
query: {
182221
start: eventView.start,
@@ -249,7 +288,7 @@ export function EventGraph({group, event, ...styleProps}: EventGraphProps) {
249288
seriesData.push(currentEventSeries as BarChartSeries);
250289
}
251290

252-
if (releaseSeries.markLine) {
291+
if (releaseSeries?.markLine) {
253292
seriesData.push(releaseSeries as BarChartSeries);
254293
}
255294

@@ -363,8 +402,11 @@ export function EventGraph({group, event, ...styleProps}: EventGraphProps) {
363402
</SummaryContainer>
364403
<ChartContainer role="figure">
365404
<BarChart
405+
{...releaseBubbleEventHandlers}
406+
ref={createReleaseBubbleHighlighter}
366407
height={100}
367408
series={series}
409+
additionalSeries={releaseBubbleSeries ? [releaseBubbleSeries] : []}
368410
legend={legend}
369411
onLegendSelectChanged={onLegendSelectChanged}
370412
showTimeInTooltip
@@ -373,6 +415,7 @@ export function EventGraph({group, event, ...styleProps}: EventGraphProps) {
373415
right: 8,
374416
top: 20,
375417
bottom: 0,
418+
...releaseBubbleGrid,
376419
}}
377420
tooltip={{
378421
formatAxisLabel: (
@@ -404,6 +447,9 @@ export function EventGraph({group, event, ...styleProps}: EventGraphProps) {
404447
},
405448
},
406449
}}
450+
xAxis={{
451+
...releaseBubbleXAxis,
452+
}}
407453
{...chartZoomProps}
408454
/>
409455
</ChartContainer>

static/app/views/issueDetails/streamline/hooks/useReleaseMarkLineSeries.tsx

+12-24
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,30 @@ import {useTheme} from '@emotion/react';
33
import MarkLine from 'sentry/components/charts/components/markLine';
44
import {t} from 'sentry/locale';
55
import type {Group} from 'sentry/types/group';
6+
import type {ReleaseMetaBasic} from 'sentry/types/release';
67
import {escape} from 'sentry/utils';
78
import {getFormattedDate} from 'sentry/utils/dates';
8-
import {useApiQuery} from 'sentry/utils/queryClient';
99
import {useNavigate} from 'sentry/utils/useNavigate';
1010
import useOrganization from 'sentry/utils/useOrganization';
1111
import {formatVersion} from 'sentry/utils/versions/formatVersion';
1212
import {useIssueDetailsEventView} from 'sentry/views/issueDetails/streamline/hooks/useIssueDetailsDiscoverQuery';
1313
import {makeReleasesPathname} from 'sentry/views/releases/utils/pathnames';
1414

15-
interface ReleaseStat {
16-
date: string;
17-
version: string;
18-
}
19-
20-
export function useReleaseMarkLineSeries({group}: {group: Group}) {
15+
export function useReleaseMarkLineSeries({
16+
group,
17+
releases,
18+
}: {
19+
group: Group;
20+
releases: ReleaseMetaBasic[];
21+
}) {
2122
const navigate = useNavigate();
2223
const theme = useTheme();
2324
const eventView = useIssueDetailsEventView({group});
2425
const organization = useOrganization();
25-
const {data: releases = []} = useApiQuery<ReleaseStat[]>(
26-
[
27-
`/organizations/${organization.slug}/releases/stats/`,
28-
{
29-
query: {
30-
project: eventView.project,
31-
environment: eventView.environment,
32-
start: eventView.start,
33-
end: eventView.end,
34-
statsPeriod: eventView.statsPeriod,
35-
},
36-
},
37-
],
38-
{
39-
staleTime: 0,
40-
}
41-
);
26+
27+
if (!releases.length) {
28+
return null;
29+
}
4230

4331
const markLine = MarkLine({
4432
animation: false,

0 commit comments

Comments
 (0)