@@ -25,6 +25,7 @@ import {
2525import { useApiQuery } from 'sentry/utils/queryClient' ;
2626import usePageFilters from 'sentry/utils/usePageFilters' ;
2727import { SpanDurationBar } from 'sentry/views/performance/transactionSummary/transactionSpans/spanDetails/spanDetailsTable' ;
28+ import { TextAlignRight } from 'sentry/views/starfish/modules/APIModule/endpointTable' ;
2829import {
2930 getSpanFacetBreakdownQuery ,
3031 getSpanInTransactionQuery ,
@@ -62,6 +63,11 @@ const COLUMN_ORDER = [
6263 name : 'Span Duration' ,
6364 width : 200 ,
6465 } ,
66+ {
67+ key : 'p50_comparison' ,
68+ name : 'Compared to P50' ,
69+ width : 200 ,
70+ } ,
6571 {
6672 key : 'compare' ,
6773 name : '' ,
@@ -71,6 +77,7 @@ const COLUMN_ORDER = [
7177
7278type SpanTableRow = {
7379 exclusive_time : number ;
80+ p50Comparison : number ;
7481 'project.name' : string ;
7582 spanDuration : number ;
7683 spanOp : string ;
@@ -196,6 +203,78 @@ export default function SpanSummary({location, params}: Props) {
196203 } ;
197204 } ) ;
198205
206+ function renderHeadCell ( column : GridColumnHeader ) : React . ReactNode {
207+ if ( column . key === 'p50_comparison' ) {
208+ return (
209+ < TextAlignRight >
210+ < OverflowEllipsisTextContainer > { column . name } </ OverflowEllipsisTextContainer >
211+ </ TextAlignRight >
212+ ) ;
213+ }
214+
215+ return < OverflowEllipsisTextContainer > { column . name } </ OverflowEllipsisTextContainer > ;
216+ }
217+
218+ function renderBodyCell (
219+ column : GridColumnHeader ,
220+ row : SpanTableRow ,
221+ setComparison : ( eventId : string ) => void
222+ ) : React . ReactNode {
223+ if ( column . key === 'transaction_id' ) {
224+ return (
225+ < Link
226+ to = { `/performance/${ row [ 'project.name' ] } :${
227+ row . transaction_id
228+ } #span-${ row . span_id . slice ( 19 ) . replace ( '-' , '' ) } `}
229+ >
230+ { row . transaction_id . slice ( 0 , 8 ) }
231+ </ Link >
232+ ) ;
233+ }
234+
235+ if ( column . key === 'duration' ) {
236+ return (
237+ < SpanDurationBar
238+ spanOp = { row . spanOp }
239+ spanDuration = { row . spanDuration }
240+ transactionDuration = { row . transactionDuration }
241+ />
242+ ) ;
243+ }
244+
245+ if ( column . key === 'p50_comparison' ) {
246+ const { p50} = data [ 0 ] ;
247+ const diff = row . spanDuration - p50 ;
248+
249+ if ( diff === p50 ) {
250+ return 'At baseline' ;
251+ }
252+
253+ const labelString =
254+ diff > 0 ? `+${ diff . toFixed ( 2 ) } ms above` : `${ diff . toFixed ( 2 ) } ms below` ;
255+
256+ return < ComparisonLabel value = { diff } > { labelString } </ ComparisonLabel > ;
257+ }
258+
259+ if ( column . key === 'timestamp' ) {
260+ return < DateTime date = { row . timestamp } year timeZone seconds /> ;
261+ }
262+
263+ if ( column . key === 'compare' ) {
264+ return (
265+ < Button
266+ onClick = { ( ) => {
267+ setComparison ( row . transaction_id ) ;
268+ } }
269+ >
270+ { t ( 'View' ) }
271+ </ Button >
272+ ) ;
273+ }
274+
275+ return < span > { row [ column . key ] } </ span > ;
276+ }
277+
199278 return (
200279 < Layout . Page >
201280 < PageErrorProvider >
@@ -358,10 +437,6 @@ export default function SpanSummary({location, params}: Props) {
358437 ) ;
359438}
360439
361- function renderHeadCell ( column : GridColumnHeader ) : React . ReactNode {
362- return < OverflowEllipsisTextContainer > { column . name } </ OverflowEllipsisTextContainer > ;
363- }
364-
365440export const OverflowEllipsisTextContainer = styled ( 'span' ) `
366441 text-overflow: ellipsis;
367442 overflow: hidden;
@@ -404,51 +479,10 @@ const ToggleLabel = styled('span')<{active?: boolean}>`
404479 color: ${ p => ( p . active ? p . theme . purple300 : p . theme . gray300 ) } ;
405480` ;
406481
407- function renderBodyCell (
408- column : GridColumnHeader ,
409- row : SpanTableRow ,
410- setComparison : ( eventId : string ) => void
411- ) : React . ReactNode {
412- if ( column . key === 'transaction_id' ) {
413- return (
414- < Link
415- to = { `/performance/${ row [ 'project.name' ] } :${ row . transaction_id } #span-${ row . span_id
416- . slice ( 19 )
417- . replace ( '-' , '' ) } `}
418- >
419- { row . transaction_id . slice ( 0 , 8 ) }
420- </ Link >
421- ) ;
422- }
423-
424- if ( column . key === 'duration' ) {
425- return (
426- < SpanDurationBar
427- spanOp = { row . spanOp }
428- spanDuration = { row . spanDuration }
429- transactionDuration = { row . transactionDuration }
430- />
431- ) ;
432- }
433-
434- if ( column . key === 'timestamp' ) {
435- return < DateTime date = { row . timestamp } year timeZone seconds /> ;
436- }
437-
438- if ( column . key === 'compare' ) {
439- return (
440- < Button
441- onClick = { ( ) => {
442- setComparison ( row . transaction_id ) ;
443- } }
444- >
445- { t ( 'View' ) }
446- </ Button >
447- ) ;
448- }
449-
450- return < span > { row [ column . key ] } </ span > ;
451- }
482+ const ComparisonLabel = styled ( 'div' ) < { value : number } > `
483+ text-align: right;
484+ color: ${ p => ( p . value < 0 ? p . theme . green400 : p . theme . red400 ) } ;
485+ ` ;
452486
453487function SpanGroupKeyValueList ( {
454488 spanDescription,
0 commit comments