@@ -2,7 +2,7 @@ import * as React from 'react';
22import cx from 'classnames' ;
33import { ChartConfigWithOptDateRange } from '@hyperdx/common-utils/dist/types' ;
44import { ScrollArea , Skeleton , Stack } from '@mantine/core' ;
5- import { useThrottledCallback , useThrottledValue } from '@mantine/hooks' ;
5+ import { useThrottledValue } from '@mantine/hooks' ;
66import {
77 IconArrowsLeftRight ,
88 IconMapPin ,
@@ -16,18 +16,18 @@ import { useVirtualizer } from '@tanstack/react-virtual';
1616import useRowWhere , { RowWhereResult } from '@/hooks/useRowWhere' ;
1717
1818import { useQueriedChartConfig } from './hooks/useChartConfig' ;
19+ import { SessionRow , sessionRowSchema } from './utils/sessions' ;
1920import { useFormatTime } from './useFormatTime' ;
2021import { formatmmss , getShortUrl } from './utils' ;
2122
2223import styles from '../styles/SessionSubpanelV2.module.scss' ;
2324
2425type SessionEvent = {
2526 id : string ;
26- row : Record < string , string > ; // original row object
27- sortKey : string ;
27+ row : SessionRow ; // original row object
2828 isError : boolean ;
2929 isSuccess : boolean ;
30- eventSource : 'navigation' | 'chat' | 'network' | 'custom' ;
30+ eventSource : 'navigation' | 'chat' | 'network' | 'custom' | 'log' ;
3131 title : string ;
3232 description : string ;
3333 timestamp : Date ;
@@ -112,47 +112,48 @@ export const SessionEventList = ({
112112 onTimeClick : ( ts : number ) => void ;
113113 eventsFollowPlayerPosition : boolean ;
114114} ) => {
115- const { data, isLoading, isError, error, isPlaceholderData, isSuccess } =
116- useQueriedChartConfig ( queriedConfig , {
117- placeholderData : ( prev : any ) => prev ,
118- queryKey : [ 'SessionEventList' , queriedConfig ] ,
119- } ) ;
115+ const { data, isLoading } = useQueriedChartConfig ( queriedConfig , {
116+ placeholderData : ( prev : any ) => prev ,
117+ queryKey : [ 'SessionEventList' , queriedConfig ] ,
118+ } ) ;
120119 const formatTime = useFormatTime ( ) ;
121120
122- const events = React . useMemo ( ( ) => data ?. data ?? [ ] , [ data ?. data ] ) ;
121+ const events : SessionRow [ ] = React . useMemo (
122+ ( ) =>
123+ data ?. data
124+ ?. map ( row => sessionRowSchema . safeParse ( row ) )
125+ . filter ( parsed => parsed . success )
126+ . map ( parsed => parsed . data ) ?? [ ] ,
127+ [ data ?. data ] ,
128+ ) ;
123129
124130 const getRowWhere = useRowWhere ( { meta : data ?. meta , aliasMap } ) ;
125131
126132 const rows = React . useMemo ( ( ) => {
127133 return (
128- events . map ( ( event , i ) => {
134+ events . map ( event => {
129135 const { timestamp, durationInMs } = event ;
130136
131137 // TODO: we should just use timestamp and durationInMs instead of startOffset and endOffset
132138 const startOffset = new Date ( timestamp ) . getTime ( ) ;
133139 const endOffset = new Date ( startOffset ) . getTime ( ) + durationInMs ;
134140
135- const isHighlighted = false ;
136-
137- const url = event [ 'http.url' ] ;
138- const statusCode = event [ 'http.status_code' ] ;
139- const method = event [ 'http.method' ] ;
141+ const url = event [ 'http.url' ] ?? '' ;
142+ const statusCode = Number ( event [ 'http.status_code' ] ?? '' ) ;
143+ const method = event [ 'http.method' ] ?? '' ;
140144 const shortUrl = getShortUrl ( url ) ;
141145
142146 const isNetworkRequest =
143147 method != '' && method != null && url != null && url != '' ;
144148
145149 const errorMessage = event [ 'error.message' ] ;
146150
147- const body = event [ 'body' ] ;
151+ const body = event [ 'body' ] ?? '' ;
148152 const component = event [ 'component' ] ;
149153 const spanName = event [ 'span_name' ] ;
150- const locationHref = event [ 'location.href' ] ;
154+ const locationHref = event [ 'location.href' ] ?? '' ;
151155 const otelLibraryName = event [ 'otel.library.name' ] ;
152156 const shortLocationHref = getShortUrl ( locationHref ) ;
153- const isException =
154- event [ 'exception.group_id' ] != '' &&
155- event [ 'exception.group_id' ] != null ;
156157
157158 const isCustomEvent = otelLibraryName === 'custom-action' ;
158159 const isNavigation =
@@ -167,7 +168,6 @@ export const SessionEventList = ({
167168
168169 return {
169170 id : event . id ,
170- sortKey : event . sort_key ,
171171 row : event ,
172172 isError,
173173 isSuccess,
@@ -182,29 +182,27 @@ export const SessionEventList = ({
182182 : 'log' ,
183183 title : isNavigation
184184 ? `Navigated`
185- : isException
186- ? 'Exception '
187- : spanName === 'console.error '
188- ? 'console.error '
189- : spanName === 'console.log '
190- ? 'console.log '
191- : spanName === 'console.warn'
192- ? 'console.warn'
193- : url . length > 0
194- ? ` ${ statusCode } ${ method } `
195- : spanName === 'intercom.onShow'
196- ? 'Intercom Chat Opened'
197- : isCustomEvent
185+ : spanName === 'console.error'
186+ ? 'console.error '
187+ : spanName === 'console.log '
188+ ? 'console.log '
189+ : spanName === 'console.warn '
190+ ? 'console.warn '
191+ : url . length > 0
192+ ? ` ${ statusCode } ${ method } `
193+ : spanName === 'intercom.onShow'
194+ ? 'Intercom Chat Opened'
195+ : isCustomEvent
196+ ? spanName
197+ : component === 'console'
198198 ? spanName
199- : component === 'console'
200- ? spanName
201- : 'console.error' ,
199+ : 'console.error' ,
202200 description : isNavigation
203201 ? shortLocationHref
204202 : errorMessage != null && errorMessage . length > 0
205203 ? errorMessage
206204 : component === 'console'
207- ? body
205+ ? ( body ?? '' )
208206 : url . length > 0
209207 ? shortUrl
210208 : '' ,
@@ -215,7 +213,7 @@ export const SessionEventList = ({
215213 format : 'time' ,
216214 } ) ,
217215 duration : endOffset - startOffset ,
218- } as SessionEvent ;
216+ } satisfies SessionEvent ;
219217 } ) ?? [ ]
220218 ) ;
221219 } , [ events , showRelativeTime , minTs , formatTime ] ) ;
0 commit comments