Skip to content

Commit 25d4ac7

Browse files
authored
feat(aci): Add environment labels to cron checkin timeline (#102497)
1 parent 8578cb3 commit 25d4ac7

File tree

7 files changed

+203
-40
lines changed

7 files changed

+203
-40
lines changed

static/app/views/detectors/components/detectorListTable/detectorListRow.tsx

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import {Fragment} from 'react';
12
import styled from '@emotion/styled';
23

34
import {Checkbox} from 'sentry/components/core/checkbox';
@@ -11,20 +12,17 @@ import {DetectorLink} from 'sentry/views/detectors/components/detectorLink';
1112
import {DetectorListConnectedAutomations} from 'sentry/views/detectors/components/detectorListConnectedAutomations';
1213
import {DetectorAssigneeCell} from 'sentry/views/detectors/components/detectorListTable/detectorAssigneeCell';
1314
import {DetectorTypeCell} from 'sentry/views/detectors/components/detectorListTable/detectorTypeCell';
15+
import {useMonitorViewContext} from 'sentry/views/detectors/monitorViewContext';
1416

1517
interface DetectorListRowProps {
1618
detector: Detector;
1719
onSelect: (id: string) => void;
1820
selected: boolean;
19-
renderVisualization?: (detector: Detector) => React.ReactNode;
2021
}
2122

22-
export function DetectorListRow({
23-
detector,
24-
selected,
25-
onSelect,
26-
renderVisualization,
27-
}: DetectorListRowProps) {
23+
export function DetectorListRow({detector, selected, onSelect}: DetectorListRowProps) {
24+
const {additionalColumns = [], renderVisualization} = useMonitorViewContext();
25+
2826
return (
2927
<DetectorSimpleTableRow
3028
variant={detector.enabled ? 'default' : 'faded'}
@@ -55,12 +53,17 @@ export function DetectorListRow({
5553
<SimpleTable.RowCell data-column-name="connected-automations">
5654
<DetectorListConnectedAutomations automationIds={detector.workflowIds} />
5755
</SimpleTable.RowCell>
58-
{defined(renderVisualization) && renderVisualization(detector)}
56+
{additionalColumns.map(col => (
57+
<Fragment key={col.id}>{col.renderCell(detector)}</Fragment>
58+
))}
59+
{defined(renderVisualization) && renderVisualization({detector})}
5960
</DetectorSimpleTableRow>
6061
);
6162
}
6263

6364
export function DetectorListRowSkeleton() {
65+
const {additionalColumns = [], renderVisualization} = useMonitorViewContext();
66+
6467
return (
6568
<DetectorSimpleTableRow>
6669
<SimpleTable.RowCell>
@@ -81,6 +84,16 @@ export function DetectorListRowSkeleton() {
8184
<SimpleTable.RowCell data-column-name="connected-automations">
8285
<Placeholder height="20px" />
8386
</SimpleTable.RowCell>
87+
{additionalColumns.map(col => (
88+
<Fragment key={col.id}>
89+
{col.renderPendingCell?.() ?? (
90+
<SimpleTable.RowCell data-column-name={col.id}>
91+
<Placeholder height="20px" />
92+
</SimpleTable.RowCell>
93+
)}
94+
</Fragment>
95+
))}
96+
{defined(renderVisualization) ? renderVisualization({detector: null}) : null}
8497
</DetectorSimpleTableRow>
8598
);
8699
}

static/app/views/detectors/components/detectorListTable/index.tsx

Lines changed: 73 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import {useCallback, useMemo, useRef, useState, type ComponentProps} from 'react';
1+
import {
2+
Fragment,
3+
useCallback,
4+
useMemo,
5+
useRef,
6+
useState,
7+
type ComponentProps,
8+
} from 'react';
29
import {css, type Theme} from '@emotion/react';
310
import styled from '@emotion/styled';
411

@@ -25,6 +32,10 @@ import {
2532
DetectorListRowSkeleton,
2633
} from 'sentry/views/detectors/components/detectorListTable/detectorListRow';
2734
import {DETECTOR_LIST_PAGE_LIMIT} from 'sentry/views/detectors/constants';
35+
import {
36+
useMonitorViewContext,
37+
type MonitorListAdditionalColumn,
38+
} from 'sentry/views/detectors/monitorViewContext';
2839
import {useCanEditDetectors} from 'sentry/views/detectors/utils/useCanEditDetector';
2940
import {CronServiceIncidents} from 'sentry/views/insights/crons/components/serviceIncidents';
3041

@@ -36,7 +47,6 @@ type DetectorListTableProps = {
3647
isSuccess: boolean;
3748
queryCount: string;
3849
sort: Sort | undefined;
39-
renderVisualization?: (detector: Detector) => React.ReactNode;
4050
};
4151

4252
function LoadingSkeletons() {
@@ -45,14 +55,14 @@ function LoadingSkeletons() {
4555
));
4656
}
4757

48-
function HeaderCell({
58+
export function HeaderCell({
4959
children,
5060
sortKey,
5161
sort,
5262
...props
5363
}: {
54-
children: React.ReactNode;
5564
sort: Sort | undefined;
65+
children?: React.ReactNode;
5666
divider?: boolean;
5767
sortKey?: string;
5868
} & Omit<ComponentProps<typeof SimpleTable.HeaderCell>, 'sort'>) {
@@ -90,7 +100,6 @@ function DetectorListTable({
90100
sort,
91101
queryCount,
92102
allResultsVisible,
93-
renderVisualization,
94103
}: DetectorListTableProps) {
95104
const [selected, setSelected] = useState<Set<string>>(new Set());
96105

@@ -136,11 +145,15 @@ function DetectorListTable({
136145
const timelineWidth = useDebouncedValue(containerWidth, 1000);
137146
const timeWindowConfig = useTimeWindowConfig({timelineWidth});
138147

148+
const {additionalColumns = [], renderVisualization} = useMonitorViewContext();
139149
const hasVisualization = defined(renderVisualization);
140150

141151
return (
142152
<TableContainer>
143-
<DetectorListSimpleTable hasVisualization={hasVisualization}>
153+
<DetectorListSimpleTable
154+
hasVisualization={hasVisualization}
155+
additionalColumns={additionalColumns}
156+
>
144157
{selected.size === 0 ? (
145158
<SimpleTable.Header>
146159
<HeaderCell sortKey="name" sort={sort}>
@@ -174,6 +187,9 @@ function DetectorListTable({
174187
>
175188
{t('Alerts')}
176189
</HeaderCell>
190+
{additionalColumns.map(col => (
191+
<Fragment key={col.id}>{col.renderHeaderCell()}</Fragment>
192+
))}
177193
{hasVisualization && (
178194
<Container
179195
data-column-name="visualization"
@@ -211,7 +227,6 @@ function DetectorListTable({
211227
detector={detector}
212228
selected={selected.has(detector.id)}
213229
onSelect={handleSelect}
214-
renderVisualization={renderVisualization}
215230
/>
216231
))}
217232
{hasVisualization && (
@@ -235,7 +250,10 @@ const TableContainer = styled('div')`
235250
container-type: inline-size;
236251
`;
237252

238-
const gridDefinitions = (p: {theme: Theme}) => css`
253+
const gridDefinitions = (
254+
p: {theme: Theme},
255+
additionalColumns: MonitorListAdditionalColumn[]
256+
) => css`
239257
@container (min-width: ${p.theme.breakpoints.xs}) {
240258
grid-template-columns: 3fr 0.8fr;
241259
@@ -267,10 +285,27 @@ const gridDefinitions = (p: {theme: Theme}) => css`
267285
display: flex;
268286
}
269287
}
288+
289+
@container (min-width: ${p.theme.breakpoints.xl}) {
290+
grid-template-columns: 4.5fr 0.8fr 1.5fr 0.8fr 1.1fr ${additionalColumns
291+
.map(col => col.columnWidth ?? 'auto')
292+
.join(' ')};
293+
294+
${additionalColumns.map(
295+
col => css`
296+
[data-column-name='${col.id}'] {
297+
display: flex;
298+
}
299+
`
300+
)}
301+
}
270302
`;
271303

272304
// When there is a visualization, replace the "Type" column with the visualization
273-
const gridDefinitionsWithVisualization = (p: {theme: Theme}) => css`
305+
const gridDefinitionsWithVisualization = (
306+
p: {theme: Theme},
307+
additionalColumns: MonitorListAdditionalColumn[]
308+
) => css`
274309
@container (min-width: ${p.theme.breakpoints.sm}) {
275310
grid-template-columns: 3fr 1.5fr;
276311
@@ -296,15 +331,28 @@ const gridDefinitionsWithVisualization = (p: {theme: Theme}) => css`
296331
}
297332
298333
@container (min-width: ${p.theme.breakpoints.xl}) {
299-
grid-template-columns: 4.5fr 2fr auto 1.1fr 6fr;
334+
grid-template-columns: 4.5fr 2fr auto 1.1fr ${additionalColumns
335+
.map(col => col.columnWidth ?? 'auto')
336+
.join(' ')} 6fr;
300337
301338
[data-column-name='visualization'] {
302339
display: block;
303340
}
341+
342+
${additionalColumns.map(
343+
col => css`
344+
[data-column-name='${col.id}'] {
345+
display: flex;
346+
}
347+
`
348+
)}
304349
}
305350
`;
306351

307-
const DetectorListSimpleTable = styled(SimpleTable)<{hasVisualization: boolean}>`
352+
const DetectorListSimpleTable = styled(SimpleTable)<{
353+
additionalColumns: MonitorListAdditionalColumn[];
354+
hasVisualization: boolean;
355+
}>`
308356
grid-template-columns: 1fr;
309357
margin-bottom: ${space(2)};
310358
@@ -316,7 +364,19 @@ const DetectorListSimpleTable = styled(SimpleTable)<{hasVisualization: boolean}>
316364
display: none;
317365
}
318366
319-
${p => (p.hasVisualization ? gridDefinitionsWithVisualization(p) : gridDefinitions(p))}
367+
${p =>
368+
p.additionalColumns.map(
369+
col => css`
370+
[data-column-name='${col.id}'] {
371+
display: none;
372+
}
373+
`
374+
)}
375+
376+
${p =>
377+
p.hasVisualization
378+
? gridDefinitionsWithVisualization(p, p.additionalColumns)
379+
: gridDefinitions(p, p.additionalColumns)}
320380
`;
321381

322382
const PositionedGridLineOverlay = styled(GridLineOverlay)`
@@ -327,7 +387,7 @@ const PositionedGridLineOverlay = styled(GridLineOverlay)`
327387
328388
display: none;
329389
330-
@media (min-width: ${p => p.theme.breakpoints.xl}) {
390+
@container (min-width: ${p => p.theme.breakpoints.xl}) {
331391
display: block;
332392
}
333393
`;

static/app/views/detectors/list.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ export default function DetectorsList() {
7373
const location = useLocation();
7474
const navigate = useNavigate();
7575
const {selection, isReady} = usePageFilters();
76-
const {detectorFilter, assigneeFilter, renderVisualization, emptyState} =
77-
useMonitorViewContext();
76+
const {detectorFilter, assigneeFilter, emptyState} = useMonitorViewContext();
7877

7978
const {
8079
sort: sorts,
@@ -180,7 +179,6 @@ export default function DetectorsList() {
180179
sort={sort}
181180
queryCount={hitsInt > maxHitsInt ? `${maxHits}+` : hits}
182181
allResultsVisible={allResultsVisible()}
183-
renderVisualization={renderVisualization}
184182
/>
185183
)}
186184
</VisuallyCompleteWithData>

static/app/views/detectors/list/cron.spec.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ describe('CronDetectorsList', () => {
108108
// Name
109109
expect(within(row).getByText('Cron Detector')).toBeInTheDocument();
110110

111+
// Environment name
112+
expect(within(row).getByText('production')).toBeInTheDocument();
113+
111114
// Timeline visualization should render ticks once stats load
112115
expect(await screen.findAllByTestId('monitor-checkin-tick')).not.toHaveLength(0);
113116
expect(monitorStatsRequest).toHaveBeenCalled();

0 commit comments

Comments
 (0)