import styled from '@emotion/styled'; import {DateTime} from 'sentry/components/dateTime'; import {Tooltip} from 'sentry/components/tooltip'; import {CheckInStatus} from 'sentry/views/monitors/types'; import {getTickStyle} from 'sentry/views/monitors/utils'; import {getAggregateStatus} from './utils/getAggregateStatus'; import {mergeBuckets} from './utils/mergeBuckets'; import {CheckInTooltip} from './checkInTooltip'; import type {MonitorBucketData, TimeWindowConfig} from './types'; interface TimelineProps { timeWindowConfig: TimeWindowConfig; } export interface CheckInTimelineProps extends TimelineProps { bucketedData: MonitorBucketData; environment: string; } function getBucketedCheckInsPosition( timestamp: number, timelineStart: Date, msPerPixel: number ) { const elapsedSinceStart = new Date(timestamp).getTime() - timelineStart.getTime(); return elapsedSinceStart / msPerPixel; } export function CheckInTimeline(props: CheckInTimelineProps) { const {bucketedData, timeWindowConfig, environment} = props; const {start, end, timelineWidth} = timeWindowConfig; const elapsedMs = end.getTime() - start.getTime(); const msPerPixel = elapsedMs / timelineWidth; const jobTicks = mergeBuckets(bucketedData, environment); return ( {jobTicks.map(jobTick => { const { startTs, width: tickWidth, envMapping, roundedLeft, roundedRight, } = jobTick; const timestampMs = startTs * 1000; const left = getBucketedCheckInsPosition(timestampMs, start, msPerPixel); return ( ); })} ); } export interface MockCheckInTimelineProps extends TimelineProps { mockTimestamps: Date[]; } export function MockCheckInTimeline({ mockTimestamps, timeWindowConfig, }: MockCheckInTimelineProps) { const {start, end} = timeWindowConfig; const elapsedMs = end.getTime() - start.getTime(); const msPerPixel = elapsedMs / timeWindowConfig.timelineWidth; return ( {mockTimestamps.map(ts => { const timestampMs = ts.getTime(); const left = getBucketedCheckInsPosition(timestampMs, start, msPerPixel); return ( } skipWrapper > ); })} ); } const TimelineContainer = styled('div')` position: relative; height: 100%; `; const JobTick = styled('div')<{ roundedLeft: boolean; roundedRight: boolean; status: CheckInStatus; }>` position: absolute; top: calc(50% + 1px); width: 4px; height: 14px; transform: translateY(-50%); opacity: 0.7; ${p => getTickStyle(p.status, p.theme)}; ${p => p.roundedLeft && ` border-top-left-radius: 2px; border-bottom-left-radius: 2px; `}; ${p => p.roundedRight && ` border-top-right-radius: 2px; border-bottom-right-radius: 2px; `} ${p => !p.roundedLeft && 'border-left-width: 0'}; ${p => !p.roundedRight && 'border-right-width: 0'}; `;