@@ -3,6 +3,7 @@ import {SortableContext, verticalListSortingStrategy} from '@dnd-kit/sortable';
33import styled from '@emotion/styled' ;
44
55import { Container , Flex , Stack } from '@sentry/scraps/layout' ;
6+ import { Separator } from '@sentry/scraps/separator' ;
67
78import * as Layout from 'sentry/components/layouts/thirds' ;
89import type { DatePageFilterProps } from 'sentry/components/pageFilters/date/datePageFilter' ;
@@ -42,6 +43,7 @@ import {
4243 FilterBarWithSaveAsContainer ,
4344 StyledPageFilterBar ,
4445} from 'sentry/views/explore/metrics/styles' ;
46+ import { isVisualizeEquation } from 'sentry/views/explore/queryParams/visualize' ;
4547export const METRICS_CHART_GROUP = 'metrics-charts-group' ;
4648
4749type MetricsTabProps = {
@@ -218,8 +220,19 @@ function MetricsTabBodySection() {
218220 isMetricOptionsEmpty,
219221 } ) ;
220222 const references = useMetricReferences ( ) ;
221- const { sortableItems, sensors, onDragStart, onDragEnd, onDragCancel, isDragging} =
222- useSortableMetricQueries ( ) ;
223+ const aggregateMetricQueries = useSortableMetricQueries ( {
224+ predicate : metricQuery =>
225+ ! isVisualizeEquation ( metricQuery . queryParams . visualizes [ 0 ] ! ) ,
226+ } ) ;
227+ const equationMetricQueries = useSortableMetricQueries ( {
228+ predicate : metricQuery => isVisualizeEquation ( metricQuery . queryParams . visualizes [ 0 ] ! ) ,
229+ } ) ;
230+ const isDragging =
231+ aggregateMetricQueries . isDragging || equationMetricQueries . isDragging ;
232+ const showSectionSeparator =
233+ isDragging &&
234+ aggregateMetricQueries . sortableItems . length > 0 &&
235+ equationMetricQueries . sortableItems . length > 0 ;
223236
224237 // Cannot add metric queries beyond Z
225238 const isAddMetricDisabled =
@@ -231,41 +244,27 @@ function MetricsTabBodySection() {
231244 < ExploreContentSection >
232245 < Stack >
233246 < WidgetSyncContextProvider groupName = { METRICS_CHART_GROUP } >
234- < DndContext
235- sensors = { sensors }
236- collisionDetection = { closestCenter }
237- onDragStart = { onDragStart }
238- onDragEnd = { onDragEnd }
239- onDragCancel = { onDragCancel }
240- >
241- < SortableContext
242- items = { sortableItems }
243- strategy = { verticalListSortingStrategy }
244- >
245- { sortableItems . map ( ( { id, metricQuery} , index ) => {
246- return (
247- < MetricsQueryParamsProvider
248- key = { id }
249- queryParams = { metricQuery . queryParams }
250- setQueryParams = { metricQuery . setQueryParams }
251- traceMetric = { metricQuery . metric }
252- setTraceMetric = { metricQuery . setTraceMetric }
253- removeMetric = { metricQuery . removeMetric }
254- >
255- < SortableMetricPanel
256- sortableId = { id }
257- traceMetric = { metricQuery . metric }
258- queryIndex = { index }
259- queryLabel = { metricQuery . label ?? '' }
260- references = { references }
261- isAnyDragging = { isDragging }
262- canDrag = { sortableItems . length > 1 }
263- />
264- </ MetricsQueryParamsProvider >
265- ) ;
266- } ) }
267- </ SortableContext >
268- </ DndContext >
247+ < SortableMetricPanelSection
248+ dataTestId = "aggregate-metric-panels"
249+ sortableQueries = { aggregateMetricQueries }
250+ references = { references }
251+ isAnyDragging = { isDragging }
252+ />
253+ { showSectionSeparator ? (
254+ < Container paddingBottom = "xl" >
255+ < Separator
256+ orientation = "horizontal"
257+ border = "primary"
258+ data-test-id = "metric-section-separator"
259+ />
260+ </ Container >
261+ ) : null }
262+ < SortableMetricPanelSection
263+ dataTestId = "equation-metric-panels"
264+ sortableQueries = { equationMetricQueries }
265+ references = { references }
266+ isAnyDragging = { isDragging }
267+ />
269268 < Flex gap = "sm" direction = "row" >
270269 < ToolbarVisualizeAddChart
271270 add = { addMetricQuery }
@@ -319,6 +318,63 @@ function MetricsTabBodySection() {
319318 ) ;
320319}
321320
321+ interface SortableMetricPanelSectionProps {
322+ dataTestId : string ;
323+ isAnyDragging : boolean ;
324+ references : Set < string > ;
325+ sortableQueries : ReturnType < typeof useSortableMetricQueries > ;
326+ }
327+
328+ function SortableMetricPanelSection ( {
329+ dataTestId,
330+ sortableQueries,
331+ references,
332+ isAnyDragging,
333+ } : SortableMetricPanelSectionProps ) {
334+ const { sortableItems, sensors, onDragStart, onDragEnd, onDragCancel} = sortableQueries ;
335+
336+ if ( ! sortableItems . length ) {
337+ return null ;
338+ }
339+
340+ return (
341+ < Stack data-test-id = { dataTestId } >
342+ < DndContext
343+ sensors = { sensors }
344+ collisionDetection = { closestCenter }
345+ onDragStart = { onDragStart }
346+ onDragEnd = { onDragEnd }
347+ onDragCancel = { onDragCancel }
348+ >
349+ < SortableContext items = { sortableItems } strategy = { verticalListSortingStrategy } >
350+ { sortableItems . map ( ( { id, metricQuery, index} ) => {
351+ return (
352+ < MetricsQueryParamsProvider
353+ key = { id }
354+ queryParams = { metricQuery . queryParams }
355+ setQueryParams = { metricQuery . setQueryParams }
356+ traceMetric = { metricQuery . metric }
357+ setTraceMetric = { metricQuery . setTraceMetric }
358+ removeMetric = { metricQuery . removeMetric }
359+ >
360+ < SortableMetricPanel
361+ sortableId = { id }
362+ traceMetric = { metricQuery . metric }
363+ queryIndex = { index }
364+ queryLabel = { metricQuery . label ?? '' }
365+ references = { references }
366+ isAnyDragging = { isAnyDragging }
367+ canDrag = { sortableItems . length > 1 }
368+ />
369+ </ MetricsQueryParamsProvider >
370+ ) ;
371+ } ) }
372+ </ SortableContext >
373+ </ DndContext >
374+ </ Stack >
375+ ) ;
376+ }
377+
322378const MetricsQueryBuilderContainer = styled ( Container ) `
323379 padding: ${ p => p . theme . space . xl } ;
324380 background-color: ${ p => p . theme . tokens . background . primary } ;
0 commit comments