@@ -40,6 +40,7 @@ import {
40
40
SidebarInset ,
41
41
SidebarProvider ,
42
42
} from '@/components/ui/sidebar' ;
43
+ import { Skeleton } from '@/components/ui/skeleton' ;
43
44
import { Spinner } from '@/components/ui/spinner' ;
44
45
import {
45
46
Table ,
@@ -92,7 +93,8 @@ const chartConfig = {
92
93
93
94
const Traffic_TracesStatusBreakdownBucketFragment = graphql ( `
94
95
fragment Traffic_TracesStatusBreakdownBucketFragment on TraceStatusBreakdownBucket {
95
- timeBucket
96
+ timeBucketStart
97
+ timeBucketEnd
96
98
okCountTotal
97
99
errorCountTotal
98
100
okCountFiltered
@@ -110,7 +112,8 @@ const TrafficBucketDiagram = memo(function Traffic(props: TrafficProps) {
110
112
ok : b . okCountFiltered ,
111
113
error : b . errorCountFiltered ,
112
114
remaining : b . okCountTotal + b . errorCountTotal - b . okCountFiltered - b . errorCountFiltered ,
113
- timeBucket : b . timeBucket . substring ( 0 , 10 ) ,
115
+ timeBucketStart : b . timeBucketStart ,
116
+ timeBucketEnd : b . timeBucketEnd ,
114
117
} ) ) ;
115
118
const [ refAreaLeft , setRefAreaLeft ] = useState < string | null > ( null ) ;
116
119
const [ refAreaRight , setRefAreaRight ] = useState < string | null > ( null ) ;
@@ -168,6 +171,17 @@ const TrafficBucketDiagram = memo(function Traffic(props: TrafficProps) {
168
171
setIsSelecting ( false ) ;
169
172
} , [ refAreaLeft , refAreaRight , navigate ] ) ;
170
173
174
+ function formatDate ( str : string ) {
175
+ return new Date ( str ) . toLocaleDateString ( 'en-US' , {
176
+ year : 'numeric' ,
177
+ month : 'short' , // e.g., "Sep"
178
+ day : 'numeric' ,
179
+ hour : '2-digit' ,
180
+ minute : '2-digit' ,
181
+ hour12 : false , // 24-hour format; set true for AM/PM
182
+ } ) ;
183
+ }
184
+
171
185
return (
172
186
< ChartContainer
173
187
config = { chartConfig }
@@ -183,29 +197,29 @@ const TrafficBucketDiagram = memo(function Traffic(props: TrafficProps) {
183
197
data = { data }
184
198
>
185
199
< XAxis
186
- dataKey = "timeBucket "
200
+ dataKey = "timeBucketStart "
187
201
tickLine = { false }
188
202
axisLine = { false }
189
203
tickMargin = { 8 }
190
204
minTickGap = { 32 }
191
- tickFormatter = { value => {
192
- const date = new Date ( value ) ;
193
- return date . toLocaleDateString ( 'en-US' , {
194
- month : 'short' ,
195
- day : 'numeric' ,
196
- } ) ;
205
+ tickFormatter = { date => {
206
+ return formatDate ( date ) ;
197
207
} }
198
208
/>
199
209
< ChartTooltip
200
210
content = {
201
211
< ChartTooltipContent
202
212
className = "w-[150px]"
203
- labelFormatter = { value => {
204
- return new Date ( value ) . toLocaleDateString ( 'en-US' , {
205
- month : 'short' ,
206
- day : 'numeric' ,
207
- year : 'numeric' ,
208
- } ) ;
213
+ labelFormatter = { ( _ , data ) => {
214
+ const payload = data [ 0 ] ?. payload ;
215
+
216
+ if ( ! payload ) {
217
+ return null ;
218
+ }
219
+
220
+ return (
221
+ formatDate ( payload . timeBucketStart ) + ' - ' + formatDate ( payload . timeBucketEnd )
222
+ ) ;
209
223
} }
210
224
/>
211
225
}
@@ -948,38 +962,55 @@ function SelectedTraceSheet(props: SelectedTraceSheetProps) {
948
962
949
963
return (
950
964
< SheetContent className = "border-l border-gray-800 bg-black p-0 text-white md:max-w-[50%]" >
951
- { trace && (
952
- < SheetHeader className = "relative border-b border-gray-800 p-4" >
953
- < div className = "flex items-center justify-between" >
954
- < SheetTitle className = "text-lg font-medium text-white" >
955
- { trace ?. operationName ?? < span className = "text-gray-400" > { '<unknown>' } </ span > }
956
- < span className = "text-muted-foreground ml-2 font-mono font-normal" >
957
- { trace . id . substring ( 0 , 4 ) }
965
+ < SheetHeader className = "relative border-b border-gray-800 p-4" >
966
+ < div className = "flex items-center justify-between" >
967
+ < SheetTitle className = "text-lg font-medium text-white" >
968
+ { trace ? (
969
+ < >
970
+ { trace . operationName ?? < span className = "text-gray-400" > { '<unknown>' } </ span > }
971
+ < span className = "text-muted-foreground ml-2 font-mono font-normal" >
972
+ { trace . id . substring ( 0 , 4 ) }
973
+ </ span >
974
+ </ >
975
+ ) : (
976
+ < Skeleton className = "inline-block h-5 w-[260px]" />
977
+ ) }
978
+ </ SheetTitle >
979
+ </ div >
980
+ < SheetDescription className = "mt-1 text-xs text-gray-400" >
981
+ Trace ID:{ ' ' }
982
+ { trace ?. id ? (
983
+ < >
984
+ < span className = "font-mono" > { trace . id } </ span >
985
+ < CopyIconButton value = { trace . id } label = "Copy Trace ID" />
986
+ </ >
987
+ ) : (
988
+ < Skeleton className = "inline-block h-4 w-[200px]" />
989
+ ) }
990
+ </ SheetDescription >
991
+ < div className = "mt-2 flex items-center gap-3 text-xs" >
992
+ { trace ? (
993
+ < >
994
+ < div className = "flex items-center gap-1" >
995
+ < Clock className = "size-3 text-gray-400" />
996
+ < span className = "text-gray-300" > { formatNanoseconds ( BigInt ( trace . duration ) ) } </ span >
997
+ </ div >
998
+ < Badge
999
+ variant = "outline"
1000
+ className = { cn (
1001
+ 'rounded-sm border-0 px-1 font-medium uppercase' ,
1002
+ trace . success ? 'bg-green-900/30 text-green-400' : 'bg-red-900/30 text-red-400' ,
1003
+ ) }
1004
+ >
1005
+ { trace . success ? 'Ok' : 'Error' }
1006
+ </ Badge >
1007
+ < span className = "font-mono uppercase text-gray-300" >
1008
+ { trace ? formatDate ( trace . timestamp , 'MMM dd HH:mm:ss' ) : null }
958
1009
</ span >
959
- </ SheetTitle >
960
- </ div >
961
- < SheetDescription className = "mt-1 text-xs text-gray-400" >
962
- Trace ID: < span className = "font-mono" > { trace . id } </ span >
963
- < CopyIconButton value = { trace . id } label = "Copy Trace ID" />
964
- </ SheetDescription >
965
- < div className = "mt-2 flex items-center gap-3 text-xs" >
966
- < div className = "flex items-center gap-1" >
967
- < Clock className = "size-3 text-gray-400" />
968
- < span className = "text-gray-300" > { formatNanoseconds ( BigInt ( trace . duration ) ) } </ span >
969
- </ div >
970
- < Badge
971
- variant = "outline"
972
- className = { cn (
973
- 'rounded-sm border-0 px-1 font-medium uppercase' ,
974
- trace . success ? 'bg-green-900/30 text-green-400' : 'bg-red-900/30 text-red-400' ,
975
- ) }
976
- >
977
- { trace . success ? 'Ok' : 'Error' }
978
- </ Badge >
979
- < span className = "font-mono uppercase text-gray-300" >
980
- { formatDate ( trace . timestamp , 'MMM dd HH:mm:ss' ) }
981
- </ span >
982
- </ div >
1010
+ </ >
1011
+ ) : (
1012
+ < Skeleton className = "inline-block h-4 w-[150px]" />
1013
+ ) }
983
1014
< Button asChild variant = "outline" size = "sm" >
984
1015
< Link
985
1016
to = "/$organizationSlug/$projectSlug/$targetSlug/trace/$traceId"
@@ -995,8 +1026,8 @@ function SelectedTraceSheet(props: SelectedTraceSheetProps) {
995
1026
Full Trace
996
1027
</ Link >
997
1028
</ Button >
998
- </ SheetHeader >
999
- ) }
1029
+ </ div >
1030
+ </ SheetHeader >
1000
1031
{ trace && (
1001
1032
< ImportedTraceSheet
1002
1033
activeSpanId = { null }
0 commit comments