Skip to content

Commit a15c571

Browse files
feat(crons): Display unknown legend when unknown check-ins present (#80985)
1 parent 0d57182 commit a15c571

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

static/app/views/monitors/components/detailsTimeline.tsx

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {useRef} from 'react';
1+
import {useEffect, useRef} from 'react';
22
import styled from '@emotion/styled';
33

44
import {
@@ -9,24 +9,30 @@ import Panel from 'sentry/components/panels/panel';
99
import Text from 'sentry/components/text';
1010
import {t} from 'sentry/locale';
1111
import {space} from 'sentry/styles/space';
12-
import type {Organization} from 'sentry/types/organization';
1312
import {setApiQueryData, useQueryClient} from 'sentry/utils/queryClient';
1413
import useApi from 'sentry/utils/useApi';
1514
import {useDimensions} from 'sentry/utils/useDimensions';
1615
import {useLocation} from 'sentry/utils/useLocation';
16+
import useOrganization from 'sentry/utils/useOrganization';
1717
import type {Monitor} from 'sentry/views/monitors/types';
1818
import {makeMonitorDetailsQueryKey} from 'sentry/views/monitors/utils';
1919

2020
import {OverviewRow} from './overviewTimeline/overviewRow';
2121
import {GridLineLabels, GridLineOverlay} from './timeline/gridLines';
22+
import {useMonitorStats} from './timeline/hooks/useMonitorStats';
2223
import {useTimeWindowConfig} from './timeline/hooks/useTimeWindowConfig';
24+
import type {MonitorBucket} from './timeline/types';
2325

2426
interface Props {
2527
monitor: Monitor;
26-
organization: Organization;
28+
/**
29+
* Called when monitor stats have been loaded for this timeline.
30+
*/
31+
onStatsLoaded: (stats: MonitorBucket[]) => void;
2732
}
2833

29-
export function DetailsTimeline({monitor, organization}: Props) {
34+
export function DetailsTimeline({monitor, onStatsLoaded}: Props) {
35+
const organization = useOrganization();
3036
const location = useLocation();
3137
const api = useApi();
3238
const queryClient = useQueryClient();
@@ -43,6 +49,16 @@ export function DetailsTimeline({monitor, organization}: Props) {
4349
{...location.query}
4450
);
4551

52+
const {data: monitorStats} = useMonitorStats({
53+
monitors: [monitor.id],
54+
timeWindowConfig,
55+
});
56+
57+
useEffect(
58+
() => monitorStats?.[monitor.id] && onStatsLoaded?.(monitorStats[monitor.id]),
59+
[onStatsLoaded, monitorStats, monitor.id]
60+
);
61+
4662
const handleDeleteEnvironment = async (env: string) => {
4763
const success = await deleteMonitorEnvironment(api, organization.slug, monitor, env);
4864
if (!success) {

static/app/views/monitors/details.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Fragment} from 'react';
1+
import {Fragment, useCallback, useState} from 'react';
22
import styled from '@emotion/styled';
33
import sortBy from 'lodash/sortBy';
44

@@ -32,6 +32,7 @@ import MonitorIssues from './components/monitorIssues';
3232
import MonitorStats from './components/monitorStats';
3333
import MonitorOnboarding from './components/onboarding';
3434
import {StatusToggleButton} from './components/statusToggleButton';
35+
import type {MonitorBucket} from './components/timeline/types';
3536
import type {CheckinProcessingError, Monitor, ProcessingErrorType} from './types';
3637

3738
const DEFAULT_POLL_INTERVAL_MS = 5000;
@@ -110,6 +111,17 @@ function MonitorDetails({params, location}: Props) {
110111
refetchErrors();
111112
}
112113

114+
// Only display the unknown legend when there are visible unknown check-ins
115+
// in the timeline
116+
const [showUnknownLegend, setShowUnknownLegend] = useState(false);
117+
118+
const checkHasUnknown = useCallback((stats: MonitorBucket[]) => {
119+
const hasUnknown = stats.some(bucket =>
120+
Object.values(bucket[1]).some(envBucket => Boolean(envBucket.unknown))
121+
);
122+
setShowUnknownLegend(hasUnknown);
123+
}, []);
124+
113125
if (isError) {
114126
return (
115127
<LoadingError message={t('The monitor you were looking for was not found.')} />
@@ -169,7 +181,7 @@ function MonitorDetails({params, location}: Props) {
169181
<MonitorOnboarding monitor={monitor} />
170182
) : (
171183
<Fragment>
172-
<DetailsTimeline organization={organization} monitor={monitor} />
184+
<DetailsTimeline monitor={monitor} onStatsLoaded={checkHasUnknown} />
173185
<MonitorStats
174186
orgSlug={organization.slug}
175187
monitor={monitor}
@@ -194,6 +206,7 @@ function MonitorDetails({params, location}: Props) {
194206
<DetailsSidebar
195207
monitorEnv={envsSortedByLastCheck[envsSortedByLastCheck.length - 1]}
196208
monitor={monitor}
209+
showUnknownLegend={showUnknownLegend}
197210
/>
198211
</Layout.Side>
199212
</Layout.Body>

0 commit comments

Comments
 (0)