import type { JobTickData, MonitorBucketData, } from 'sentry/views/monitors/components/overviewTimeline/types'; import {filterMonitorStatsBucketByEnv} from './filterMonitorStatsBucketByEnv'; import {getAggregateStatus} from './getAggregateStatus'; import {getAggregateStatusFromMultipleBuckets} from './getAggregateStatusFromMultipleBuckets'; import {isEnvMappingEmpty} from './isEnvMappingEmpty'; import {mergeEnvMappings} from './mergeEnvMappings'; function generateJobTickFromBucket( bucket: MonitorBucketData[number], options?: Partial ) { const [timestamp, envMapping] = bucket; return { endTs: timestamp, startTs: timestamp, width: 1, envMapping, roundedLeft: false, roundedRight: false, ...options, }; } export function mergeBuckets(data: MonitorBucketData, environment: string) { const minTickWidth = 4; const jobTicks: JobTickData[] = []; data.reduce( (currentJobTick, bucket, i) => { const filteredBucket = filterMonitorStatsBucketByEnv(bucket, environment); const [timestamp, envMapping] = filteredBucket; const envMappingEmpty = isEnvMappingEmpty(envMapping); if (!currentJobTick) { return envMappingEmpty ? currentJobTick : generateJobTickFromBucket(filteredBucket, {roundedLeft: true}); } const bucketStatus = getAggregateStatus(envMapping); const currJobTickStatus = getAggregateStatus(currentJobTick.envMapping); // If the current bucket is empty and our job tick has reached a min width if (envMappingEmpty && currentJobTick.width >= minTickWidth) { // Then add our current tick to the running list of job ticks to render currentJobTick.roundedRight = true; jobTicks.push(currentJobTick); return null; } const nextTickAggregateStatus = getAggregateStatusFromMultipleBuckets( data.slice(i, i + minTickWidth).map(([_, envData]) => envData) ); // If the next buckets have a different status from our current job tick if ( bucketStatus !== currJobTickStatus && nextTickAggregateStatus !== currJobTickStatus && currentJobTick.width >= minTickWidth ) { // Then add our current tick to the running list of job ticks to render jobTicks.push(currentJobTick); return generateJobTickFromBucket(filteredBucket); } // Merge our current tick with the current bucket data currentJobTick = { ...currentJobTick, endTs: timestamp, envMapping: mergeEnvMappings(currentJobTick.envMapping, envMapping), width: currentJobTick.width + 1, }; // Ensure we render the last tick if (i === data.length - 1) { currentJobTick.roundedRight = true; jobTicks.push(currentJobTick); } return currentJobTick; }, null as JobTickData | null ); return jobTicks; }